From 7cb669603fa7c3efd617c763a5f122ecdb42f66f Mon Sep 17 00:00:00 2001 From: ssk97 Date: Mon, 1 Jul 2024 21:46:14 -0700 Subject: [PATCH] [WHO] Time Reaper, Add target adjuster for "that player controls/owns" damage trigger targets (#12528) * Implement Time Reaper, start rework * Create DamagedPlayerControlsTargetAdjuster, convert Aberrant to use it * Always add targets for EachOpponentPermanentTargetsAdjuster * Improve target name, finish Time Reaper * Convert some cards * Improve documentation, more cards * More cards, fix cards that needed to use owner instead of controller * Fix unfinished AlelaCunningConqueror changes * more cards * All remaining cards * Fix target type * Remove outdated attempt at TargetController.SOURCE_EFFECT_TARGET_POINTER * Finish removal of SOURCE_EFFECT_TARGET_POINTER * Change targetAdjuster blueprint target to be set inside setTargetAdjuster, add error checking * Always add Target Adjuster after Target * Add comment * Fix TolarianContemptTest to skip opponent with no valid targets * Forgot to git add the new abstract GenericTargetAdjuster * Test now possible after merge, fix missed ChangeOfPlans adjuster order * Text and optional-ness fixes * Always set target pointer --- Mage.Sets/src/mage/cards/a/Aberrant.java | 62 ++--------- .../mage/cards/a/AlelaCunningConqueror.java | 63 +++-------- Mage.Sets/src/mage/cards/a/Archipelagore.java | 2 +- Mage.Sets/src/mage/cards/a/ArmWithAether.java | 70 +++--------- .../mage/cards/a/AryelKnightOfWindgrace.java | 2 +- .../mage/cards/a/AshlingTheExtinguisher.java | 69 ++---------- .../src/mage/cards/a/AureliasVindicator.java | 2 +- Mage.Sets/src/mage/cards/a/Avalanche.java | 2 +- Mage.Sets/src/mage/cards/b/BackInTown.java | 2 +- .../src/mage/cards/b/BlatantThievery.java | 2 +- Mage.Sets/src/mage/cards/b/BlindZealot.java | 64 ++--------- .../src/mage/cards/b/BlueSunsTwilight.java | 2 +- .../src/mage/cards/b/BronzebeakForagers.java | 2 +- Mage.Sets/src/mage/cards/c/CausticWasps.java | 73 +++---------- Mage.Sets/src/mage/cards/c/ChangeOfPlans.java | 2 +- Mage.Sets/src/mage/cards/c/ChokingVines.java | 2 +- Mage.Sets/src/mage/cards/c/CometStorm.java | 2 +- Mage.Sets/src/mage/cards/c/CommandoRaid.java | 103 +++--------------- .../src/mage/cards/c/CrackleWithPower.java | 2 +- .../src/mage/cards/c/CurseOfTheSwine.java | 2 +- .../src/mage/cards/c/CustodiSoulcaller.java | 2 +- Mage.Sets/src/mage/cards/d/DawningPurist.java | 68 +++--------- Mage.Sets/src/mage/cards/d/DeathDenied.java | 2 +- Mage.Sets/src/mage/cards/d/DeathKiss.java | 2 +- Mage.Sets/src/mage/cards/d/DecoyGambit.java | 2 +- .../src/mage/cards/d/DeluxeDragster.java | 75 ++++--------- .../src/mage/cards/d/DesecrateReality.java | 2 +- Mage.Sets/src/mage/cards/d/Detonate.java | 2 +- Mage.Sets/src/mage/cards/d/Disembowel.java | 2 +- .../src/mage/cards/d/DismantlingWave.java | 2 +- .../src/mage/cards/d/DisorderInTheCourt.java | 2 +- .../src/mage/cards/d/DistortingWake.java | 2 +- .../src/mage/cards/d/DokuchiSilencer.java | 12 +- Mage.Sets/src/mage/cards/d/Doppelgang.java | 2 +- Mage.Sets/src/mage/cards/d/DreadmawsIre.java | 78 +++---------- Mage.Sets/src/mage/cards/d/DregsOfSorrow.java | 2 +- .../mage/cards/e/ElminstersSimulacrum.java | 2 +- Mage.Sets/src/mage/cards/e/EnigmaThief.java | 2 +- .../src/mage/cards/e/EntDraughtBasin.java | 2 +- .../src/mage/cards/e/EntrancingLyre.java | 2 +- .../src/mage/cards/e/EntreatTheDead.java | 2 +- .../src/mage/cards/e/EtrataTheSilencer.java | 85 ++++----------- .../mage/cards/e/ExtraordinaryJourney.java | 2 +- .../src/mage/cards/f/FinaleOfEternity.java | 2 +- Mage.Sets/src/mage/cards/f/Firestorm.java | 2 +- Mage.Sets/src/mage/cards/g/GangUp.java | 2 +- .../src/mage/cards/g/GethLordOfTheVault.java | 2 +- .../src/mage/cards/g/GhostLitDrifter.java | 2 +- .../src/mage/cards/g/GlimpseTheSunGod.java | 2 +- Mage.Sets/src/mage/cards/g/GraspOfFate.java | 2 +- Mage.Sets/src/mage/cards/g/Gridlock.java | 2 +- Mage.Sets/src/mage/cards/h/HammerOfRuin.java | 75 +++---------- .../src/mage/cards/h/HammersOfMoradin.java | 2 +- .../src/mage/cards/h/HideousTaskmaster.java | 2 +- .../src/mage/cards/h/HourOfEternity.java | 2 +- Mage.Sets/src/mage/cards/i/IcyBlast.java | 2 +- .../mage/cards/i/InTheDarknessBindThem.java | 2 +- .../mage/cards/i/IndomitableCreativity.java | 2 +- .../src/mage/cards/i/InkEyesServantOfOni.java | 71 +++--------- .../src/mage/cards/j/JuvenileMistDragon.java | 2 +- Mage.Sets/src/mage/cards/k/KaerveksPurge.java | 2 +- Mage.Sets/src/mage/cards/k/KillingGlare.java | 2 +- .../src/mage/cards/l/LatullasOrders.java | 76 +++---------- .../mage/cards/l/LazavTheMultifarious.java | 4 +- .../src/mage/cards/l/LightwielderPaladin.java | 80 ++++---------- .../src/mage/cards/l/LikenessLooter.java | 4 +- Mage.Sets/src/mage/cards/l/LostInTheMaze.java | 2 +- .../src/mage/cards/l/LullmagesDomination.java | 2 +- .../src/mage/cards/l/LuminatePrimordial.java | 2 +- .../src/mage/cards/m/MaliciousAdvice.java | 2 +- .../mage/cards/m/MarchOfBurgeoningLife.java | 2 +- .../cards/m/MarchOfOtherworldlyLight.java | 2 +- .../src/mage/cards/m/MarchOfSwirlingMist.java | 2 +- .../src/mage/cards/m/MarshalsAnthem.java | 2 +- Mage.Sets/src/mage/cards/m/MassMutiny.java | 2 +- Mage.Sets/src/mage/cards/m/MeteorBlast.java | 2 +- .../src/mage/cards/m/MidnightArsonist.java | 2 +- .../src/mage/cards/m/MinamoSightbender.java | 2 +- .../src/mage/cards/m/MistbladeShinobi.java | 70 +++--------- .../src/mage/cards/m/MogissMarauder.java | 2 +- Mage.Sets/src/mage/cards/m/Molder.java | 2 +- .../src/mage/cards/m/MoltenPrimordial.java | 2 +- Mage.Sets/src/mage/cards/m/MordantDragon.java | 98 +++-------------- Mage.Sets/src/mage/cards/n/NahirisWrath.java | 2 +- .../src/mage/cards/n/NeyamShaiMurad.java | 17 ++- .../src/mage/cards/n/NostalgicDreams.java | 2 +- .../src/mage/cards/o/OpenIntoWonder.java | 2 +- Mage.Sets/src/mage/cards/o/OpenSeason.java | 2 +- Mage.Sets/src/mage/cards/o/Outmaneuver.java | 2 +- .../src/mage/cards/p/PestInfestation.java | 2 +- Mage.Sets/src/mage/cards/p/PolisCrusher.java | 82 ++++---------- .../src/mage/cards/q/QuarantineField.java | 2 +- Mage.Sets/src/mage/cards/q/QuestingBeast.java | 63 ++--------- Mage.Sets/src/mage/cards/r/RatsFeast.java | 2 +- .../src/mage/cards/r/ReleaseTheGremlins.java | 2 +- .../src/mage/cards/r/RestlessDreams.java | 2 +- .../src/mage/cards/r/ReturnToTheRanks.java | 2 +- .../src/mage/cards/r/RiptideEntrancer.java | 65 +++-------- Mage.Sets/src/mage/cards/r/RotHulk.java | 2 +- Mage.Sets/src/mage/cards/r/RustmouthOgre.java | 67 +++--------- .../mage/cards/r/RuthlessTechnomancer.java | 2 +- Mage.Sets/src/mage/cards/s/SchemaThief.java | 62 ++--------- .../src/mage/cards/s/ScionOfCalamity.java | 71 +++--------- .../src/mage/cards/s/ScionOfDarkness.java | 71 +++--------- Mage.Sets/src/mage/cards/s/ScrapWelder.java | 2 +- .../src/mage/cards/s/SequenceEngine.java | 2 +- Mage.Sets/src/mage/cards/s/SereneSunset.java | 2 +- .../src/mage/cards/s/ShatteredCrypt.java | 2 +- .../mage/cards/s/ShigekiJukaiVisionary.java | 2 +- Mage.Sets/src/mage/cards/s/Silkguard.java | 2 +- Mage.Sets/src/mage/cards/s/SkirkCommando.java | 58 +++------- Mage.Sets/src/mage/cards/s/Skullsnatcher.java | 63 +++-------- .../src/mage/cards/s/SmokeSpiritsAid.java | 2 +- .../src/mage/cards/s/SnappingThragg.java | 67 +++--------- .../src/mage/cards/s/SontaranGeneral.java | 2 +- .../mage/cards/s/SorinVengefulBloodlord.java | 2 +- Mage.Sets/src/mage/cards/s/SparkMage.java | 73 +++---------- Mage.Sets/src/mage/cards/s/SpellBlast.java | 2 +- Mage.Sets/src/mage/cards/s/SpellBurst.java | 2 +- Mage.Sets/src/mage/cards/s/StirTheGrave.java | 2 +- .../src/mage/cards/s/StolenByTheFae.java | 2 +- Mage.Sets/src/mage/cards/s/SunderShaman.java | 72 +++--------- .../src/mage/cards/s/SupremeLeaderSnoke.java | 2 +- .../src/mage/cards/s/SylvanPrimordial.java | 2 +- .../src/mage/cards/s/SynodArtificer.java | 4 +- .../mage/cards/t/TameshiRealityArchitect.java | 2 +- .../mage/cards/t/TamiyoCompleatedSage.java | 2 +- .../src/mage/cards/t/TemporalFirestorm.java | 2 +- .../src/mage/cards/t/TemptedByTheOriq.java | 2 +- .../src/mage/cards/t/TheBalrogOfMoria.java | 2 +- .../src/mage/cards/t/TheBattleOfNaboo.java | 2 +- .../src/mage/cards/t/TheHorusHeresy.java | 2 +- .../src/mage/cards/t/TheTrueScriptures.java | 2 +- .../src/mage/cards/t/ThievingSkydiver.java | 2 +- Mage.Sets/src/mage/cards/t/Thrive.java | 2 +- Mage.Sets/src/mage/cards/t/ThroatSlitter.java | 73 +++---------- Mage.Sets/src/mage/cards/t/TimeReaper.java | 65 +++++++++++ .../mage/cards/t/TinybonesThePickpocket.java | 80 ++++---------- .../src/mage/cards/t/TolarianContempt.java | 2 +- .../src/mage/cards/t/TrygonPredator.java | 75 +++---------- .../src/mage/cards/t/TurbulentDreams.java | 2 +- .../src/mage/cards/v/VengefulDreams.java | 2 +- .../src/mage/cards/v/VitalityHunter.java | 2 +- .../src/mage/cards/v/VolcanicEruption.java | 2 +- Mage.Sets/src/mage/cards/v/VoyagerDrake.java | 2 +- .../mage/cards/v/VronosMaskedInquisitor.java | 2 +- Mage.Sets/src/mage/cards/w/WakeTheDead.java | 2 +- .../src/mage/cards/w/WaveOfIndifference.java | 2 +- Mage.Sets/src/mage/cards/w/WaxmaneBaku.java | 2 +- Mage.Sets/src/mage/cards/w/WelcomeTo.java | 2 +- Mage.Sets/src/mage/cards/w/WildestDreams.java | 2 +- .../src/mage/cards/w/WindgracesJudgment.java | 2 +- Mage.Sets/src/mage/cards/w/WordOfBinding.java | 2 +- .../src/mage/cards/w/WrexialTheRisenDeep.java | 78 ++++--------- .../mage/cards/z/ZarethSanTheTrickster.java | 59 ++-------- .../mage/cards/z/ZethiArcaneBlademaster.java | 2 +- .../src/mage/cards/z/ZombieCannibal.java | 64 ++--------- Mage.Sets/src/mage/sets/DoctorWho.java | 1 + .../single/mat/TolarianContemptTest.java | 7 +- .../src/main/java/mage/abilities/Ability.java | 4 + .../main/java/mage/abilities/AbilityImpl.java | 5 + ...APlayerOrPlaneswalkerTriggeredAbility.java | 12 ++ .../DragonMenaceAndStealArtifactToken.java | 65 ++--------- .../DamagedPlayerControlsTargetAdjuster.java | 61 +++++++++++ .../EachOpponentPermanentTargetsAdjuster.java | 29 +++-- .../GenericTargetAdjuster.java | 17 +++ .../ManaValueTargetAdjuster.java | 7 +- .../targetadjustment/PowerTargetAdjuster.java | 8 +- .../targetadjustment/TargetAdjuster.java | 6 + .../TargetsCountAdjuster.java | 7 +- .../ToughnessTargetAdjuster.java | 7 +- Mage/src/main/java/mage/util/CardUtil.java | 13 +++ 172 files changed, 891 insertions(+), 2219 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/t/TimeReaper.java create mode 100644 Mage/src/main/java/mage/target/targetadjustment/DamagedPlayerControlsTargetAdjuster.java create mode 100644 Mage/src/main/java/mage/target/targetadjustment/GenericTargetAdjuster.java diff --git a/Mage.Sets/src/mage/cards/a/Aberrant.java b/Mage.Sets/src/mage/cards/a/Aberrant.java index 005999e54fa..ea06d8710c0 100644 --- a/Mage.Sets/src/mage/cards/a/Aberrant.java +++ b/Mage.Sets/src/mage/cards/a/Aberrant.java @@ -1,7 +1,8 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.RavenousAbility; import mage.abilities.keyword.TrampleAbility; @@ -9,15 +10,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; import mage.filter.common.FilterArtifactOrEnchantmentPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; @@ -26,6 +21,9 @@ import java.util.UUID; */ public final class Aberrant extends CardImpl { + private static final FilterArtifactOrEnchantmentPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment that player controls"); + public Aberrant(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{X}{1}{G}"); @@ -41,7 +39,11 @@ public final class Aberrant extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Heavy Power Hammer -- Whenever Aberrant deals combat damage to a player, destroy target artifact or enchantment that player controls. - this.addAbility(new AberrantTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.withFlavorWord("Heavy Power Hammer"); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private Aberrant(final Aberrant card) { @@ -53,45 +55,3 @@ public final class Aberrant extends CardImpl { return new Aberrant(this); } } - -class AberrantTriggeredAbility extends TriggeredAbilityImpl { - - AberrantTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect() - .setText("destroy target artifact or enchantment that player controls"), false - ); - this.withFlavorWord("Heavy Power Hammer"); - this.setTriggerPhrase("Whenever {this} deals combat damage to a player, "); - } - - private AberrantTriggeredAbility(final AberrantTriggeredAbility ability) { - super(ability); - } - - @Override - public AberrantTriggeredAbility copy() { - return new AberrantTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player player = game.getPlayer(event.getPlayerId()); - if (player == null - || !event.getSourceId().equals(this.getSourceId()) - || !((DamagedEvent) event).isCombatDamage()) { - return false; - } - FilterPermanent filter = new FilterArtifactOrEnchantmentPermanent( - "artifact or enchantment " + player.getLogName() + " controls" - ); - filter.add(new ControllerIdPredicate(player.getId())); - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/a/AlelaCunningConqueror.java b/Mage.Sets/src/mage/cards/a/AlelaCunningConqueror.java index e98dd15413b..2ead5282316 100644 --- a/Mage.Sets/src/mage/cards/a/AlelaCunningConqueror.java +++ b/Mage.Sets/src/mage/cards/a/AlelaCunningConqueror.java @@ -1,32 +1,32 @@ package mage.cards.a; import mage.MageInt; -import mage.abilities.TriggeredAbility; +import mage.abilities.Ability; import mage.abilities.common.DealCombatDamageControlledTriggeredAbility; import mage.abilities.common.FirstSpellOpponentsTurnTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.combat.GoadTargetEffect; 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.*; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.token.FaerieRogueToken; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author Susucr + * @author notgreat */ public final class AlelaCunningConqueror extends CardImpl { + private static final FilterCreaturePermanent faerieFilter = new FilterCreaturePermanent(SubType.FAERIE, "Faeries"); + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public AlelaCunningConqueror(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); @@ -45,8 +45,12 @@ public final class AlelaCunningConqueror extends CardImpl { )); // Whenever one or more Faeries you control deal combat damage to a player, goad target creature that player controls. - TriggeredAbility trigger = new AlelaCunningConquerorTriggeredAbility(); - this.addAbility(trigger); + Effect effect = new GoadTargetEffect().setText("goad target creature that player controls"); + Ability ability = new DealCombatDamageControlledTriggeredAbility(Zone.BATTLEFIELD, effect, faerieFilter, SetTargetPointer.PLAYER, false); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + + this.addAbility(ability); } private AlelaCunningConqueror(final AlelaCunningConqueror card) { @@ -58,38 +62,3 @@ public final class AlelaCunningConqueror extends CardImpl { return new AlelaCunningConqueror(this); } } - -class AlelaCunningConquerorTriggeredAbility extends DealCombatDamageControlledTriggeredAbility { - - private static final FilterCreaturePermanent faerieFilter = new FilterCreaturePermanent(SubType.FAERIE, "Faeries"); - - AlelaCunningConquerorTriggeredAbility() { - super(new GoadTargetEffect().setText("goad target creature that player controls"), faerieFilter); - } - - private AlelaCunningConquerorTriggeredAbility(final AlelaCunningConquerorTriggeredAbility ability) { - super(ability); - } - - @Override - public AlelaCunningConquerorTriggeredAbility copy() { - return new AlelaCunningConquerorTriggeredAbility(this); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!super.checkTrigger(event, game)) { - return false; - } - Player opponent = game.getPlayer(event.getTargetId()); - if (opponent == null) { - return false; - } - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - -} diff --git a/Mage.Sets/src/mage/cards/a/Archipelagore.java b/Mage.Sets/src/mage/cards/a/Archipelagore.java index 01359797495..fadcfb1e4a0 100644 --- a/Mage.Sets/src/mage/cards/a/Archipelagore.java +++ b/Mage.Sets/src/mage/cards/a/Archipelagore.java @@ -36,8 +36,8 @@ public final class Archipelagore extends CardImpl { "tap up to X target creatures, where X is the number of times this creature has mutated." )); ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("Those creatures")); - ability.setTargetAdjuster(new TargetsCountAdjuster(SourceMutatedCount.instance)); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new TargetsCountAdjuster(SourceMutatedCount.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/ArmWithAether.java b/Mage.Sets/src/mage/cards/a/ArmWithAether.java index 232da6b1a62..5c8eacb5aac 100644 --- a/Mage.Sets/src/mage/cards/a/ArmWithAether.java +++ b/Mage.Sets/src/mage/cards/a/ArmWithAether.java @@ -1,8 +1,8 @@ package mage.cards.a; -import java.util.UUID; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; @@ -10,27 +10,29 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author North + * @author notgreat */ public final class ArmWithAether extends CardImpl { - public ArmWithAether(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public ArmWithAether(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand." - Effect effect = new GainAbilityControlledEffect(new ArmWithAetherTriggeredAbility(), Duration.EndOfTurn, new FilterCreaturePermanent()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + + Effect effect = new GainAbilityControlledEffect(ability, Duration.EndOfTurn, new FilterCreaturePermanent()); effect.setText("Until end of turn, creatures you control gain \"Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand.\""); this.getSpellAbility().addEffect(effect); } @@ -44,43 +46,3 @@ public final class ArmWithAether extends CardImpl { return new ArmWithAether(this); } } - -class ArmWithAetherTriggeredAbility extends TriggeredAbilityImpl { - - public ArmWithAetherTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), true); - } - - private ArmWithAetherTriggeredAbility(final ArmWithAetherTriggeredAbility ability) { - super(ability); - } - - @Override - public ArmWithAetherTriggeredAbility copy() { - return new ArmWithAetherTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null && event.getSourceId().equals(this.sourceId)) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand."; - } -} diff --git a/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java b/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java index ad4635320dd..52383708bdc 100644 --- a/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java +++ b/Mage.Sets/src/mage/cards/a/AryelKnightOfWindgrace.java @@ -54,8 +54,8 @@ public final class AryelKnightOfWindgrace extends CardImpl { .setText("Destroy target creature with power X or less"), new ManaCostsImpl<>("{B}")); ability.addCost(new TapSourceCost()); ability.addCost(new TapVariableTargetCost(filter)); - ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java b/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java index d27ad68df16..87c9ed6ce85 100644 --- a/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java +++ b/Mage.Sets/src/mage/cards/a/AshlingTheExtinguisher.java @@ -1,27 +1,22 @@ package mage.cards.a; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.SacrificeTargetEffect; 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.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author Loki + * @author notgreat */ public final class AshlingTheExtinguisher extends CardImpl { @@ -34,7 +29,11 @@ public final class AshlingTheExtinguisher extends CardImpl { // Whenever Ashling, the Extinguisher deals combat damage to a player, choose target creature that player controls. they sacrifice that creature. this.power = new MageInt(4); this.toughness = new MageInt(4); - this.addAbility(new AshlingTheExtinguisherTriggeredAbility()); + Effect effect = new SacrificeTargetEffect().setText("choose target creature that player controls. The player sacrifices that creature"); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private AshlingTheExtinguisher(final AshlingTheExtinguisher card) { @@ -47,47 +46,3 @@ public final class AshlingTheExtinguisher extends CardImpl { } } - -class AshlingTheExtinguisherTriggeredAbility extends TriggeredAbilityImpl { - - public AshlingTheExtinguisherTriggeredAbility() { - super(Zone.BATTLEFIELD, new SacrificeTargetEffect()); - this.addTarget(new TargetCreaturePermanent()); - } - - private AshlingTheExtinguisherTriggeredAbility(final AshlingTheExtinguisherTriggeredAbility ability) { - super(ability); - } - - @Override - public AshlingTheExtinguisherTriggeredAbility copy() { - return new AshlingTheExtinguisherTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, choose target creature that player controls. The player sacrifices that creature."; - } -} diff --git a/Mage.Sets/src/mage/cards/a/AureliasVindicator.java b/Mage.Sets/src/mage/cards/a/AureliasVindicator.java index 6926a974c8d..c11ea3a592d 100644 --- a/Mage.Sets/src/mage/cards/a/AureliasVindicator.java +++ b/Mage.Sets/src/mage/cards/a/AureliasVindicator.java @@ -50,10 +50,10 @@ public final class AureliasVindicator extends CardImpl { // When Aurelia's Vindicator is turned face up, exile up to X other target creatures from the battlefield and/or creature cards from graveyards. Ability ability = new TurnedFaceUpSourceTriggeredAbility(new ExileTargetForSourceEffect() .setText("exile up to X other target creatures from the battlefield and/or creature cards from graveyards")); - ability.setTargetAdjuster(new TargetsCountAdjuster(MorphManacostVariableValue.instance)); ability.addTarget(new TargetCardInGraveyardBattlefieldOrStack( 0, 1, StaticFilters.FILTER_CARD_CREATURE, StaticFilters.FILTER_PERMANENT_CREATURES )); + ability.setTargetAdjuster(new TargetsCountAdjuster(MorphManacostVariableValue.instance)); this.addAbility(ability); // When Aurelia's Vindicator leaves the battlefield, return the exiled cards to their owners' hands. diff --git a/Mage.Sets/src/mage/cards/a/Avalanche.java b/Mage.Sets/src/mage/cards/a/Avalanche.java index eda7c9943d0..1305495ca58 100644 --- a/Mage.Sets/src/mage/cards/a/Avalanche.java +++ b/Mage.Sets/src/mage/cards/a/Avalanche.java @@ -29,8 +29,8 @@ public final class Avalanche extends CardImpl { // Destroy X target snow lands. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target snow lands")); - this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(ManacostVariableValue.REGULAR)); this.getSpellAbility().addTarget(new TargetPermanent(1, 1, filter, false)); + this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(ManacostVariableValue.REGULAR)); } diff --git a/Mage.Sets/src/mage/cards/b/BackInTown.java b/Mage.Sets/src/mage/cards/b/BackInTown.java index f27446b86f2..c92a9d5059b 100644 --- a/Mage.Sets/src/mage/cards/b/BackInTown.java +++ b/Mage.Sets/src/mage/cards/b/BackInTown.java @@ -29,8 +29,8 @@ public final class BackInTown extends CardImpl { // Return X target outlaw creature cards from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect() .setText("return X target outlaw creature cards from your graveyard to the battlefield")); - this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(ManacostVariableValue.REGULAR)); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter)); + this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(ManacostVariableValue.REGULAR)); } private BackInTown(final BackInTown card) { diff --git a/Mage.Sets/src/mage/cards/b/BlatantThievery.java b/Mage.Sets/src/mage/cards/b/BlatantThievery.java index 44ee9842ad5..f81f7fd6887 100644 --- a/Mage.Sets/src/mage/cards/b/BlatantThievery.java +++ b/Mage.Sets/src/mage/cards/b/BlatantThievery.java @@ -23,8 +23,8 @@ public final class BlatantThievery extends CardImpl { this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom, true) .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, gain control of target permanent that player controls")); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent()); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private BlatantThievery(final BlatantThievery card) { diff --git a/Mage.Sets/src/mage/cards/b/BlindZealot.java b/Mage.Sets/src/mage/cards/b/BlindZealot.java index 0ea2d5210c5..2d1cb8f963b 100644 --- a/Mage.Sets/src/mage/cards/b/BlindZealot.java +++ b/Mage.Sets/src/mage/cards/b/BlindZealot.java @@ -2,8 +2,9 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.keyword.IntimidateAbility; @@ -11,22 +12,18 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author North + * @author notgreat */ public final class BlindZealot extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); public BlindZealot(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); @@ -39,7 +36,10 @@ public final class BlindZealot extends CardImpl { this.addAbility(IntimidateAbility.getInstance()); // Whenever Blind Zealot deals combat damage to a player, you may sacrifice it. If you do, destroy target creature that player controls. - Ability ability = new BlindZealotTriggeredAbility(); + OneShotEffect effect = new DoIfCostPaid(new DestroyTargetEffect(), new SacrificeSourceCost()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); this.addAbility(ability); } @@ -52,45 +52,3 @@ public final class BlindZealot extends CardImpl { return new BlindZealot(this); } } - -class BlindZealotTriggeredAbility extends TriggeredAbilityImpl { - - BlindZealotTriggeredAbility() { - super(Zone.BATTLEFIELD, new DoIfCostPaid(new DestroyTargetEffect(), new SacrificeSourceCost()), false); - } - - private BlindZealotTriggeredAbility(final BlindZealotTriggeredAbility ability) { - super(ability); - } - - @Override - public BlindZealotTriggeredAbility copy() { - return new BlindZealotTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent == null - || !event.getSourceId().equals(this.sourceId) - || !((DamagedEvent) event).isCombatDamage()) { - return false; - } - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may sacrifice it. " - + "If you do, destroy target creature that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BlueSunsTwilight.java b/Mage.Sets/src/mage/cards/b/BlueSunsTwilight.java index 7f3d05567a3..c98b8d7cd43 100644 --- a/Mage.Sets/src/mage/cards/b/BlueSunsTwilight.java +++ b/Mage.Sets/src/mage/cards/b/BlueSunsTwilight.java @@ -31,8 +31,8 @@ public final class BlueSunsTwilight extends CardImpl { new CreateTokenCopyTargetEffect(), BlueSunsTwilightCondition.instance, "If X is 5 or more, create a token that's a copy of that creature" )); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); } private BlueSunsTwilight(final BlueSunsTwilight card) { diff --git a/Mage.Sets/src/mage/cards/b/BronzebeakForagers.java b/Mage.Sets/src/mage/cards/b/BronzebeakForagers.java index c2dc1ed0315..1ed6a601d16 100644 --- a/Mage.Sets/src/mage/cards/b/BronzebeakForagers.java +++ b/Mage.Sets/src/mage/cards/b/BronzebeakForagers.java @@ -46,8 +46,8 @@ public final class BronzebeakForagers extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, exile up to one target nonland permanent that player controls until {this} leaves the battlefield") ); - etbAbility.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); etbAbility.addTarget(new TargetNonlandPermanent(0, 1)); + etbAbility.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(etbAbility); // {X}{W}: Put target card with mana value X exiled with Bronzebeak Foragers into its owner's graveyard. diff --git a/Mage.Sets/src/mage/cards/c/CausticWasps.java b/Mage.Sets/src/mage/cards/c/CausticWasps.java index a19b15500f9..b7b6fb7f341 100644 --- a/Mage.Sets/src/mage/cards/c/CausticWasps.java +++ b/Mage.Sets/src/mage/cards/c/CausticWasps.java @@ -1,33 +1,31 @@ package mage.cards.c; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; +import mage.filter.common.FilterArtifactPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author Mitchel Stein + * @author notgreat */ public final class CausticWasps extends CardImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public CausticWasps(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); this.subtype.add(SubType.INSECT); this.power = new MageInt(1); @@ -35,8 +33,12 @@ public final class CausticWasps extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // Whenever Caustic Wasps deals combat damage to a player, you may destroy target artifact that player controls. - this.addAbility(new CausticWaspsTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private CausticWasps(final CausticWasps card) { @@ -48,46 +50,3 @@ public final class CausticWasps extends CardImpl { return new CausticWasps(this); } } - -class CausticWaspsTriggeredAbility extends TriggeredAbilityImpl { - - public CausticWaspsTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private CausticWaspsTriggeredAbility(final CausticWaspsTriggeredAbility ability) { - super(ability); - } - - @Override - public CausticWaspsTriggeredAbility copy() { - return new CausticWaspsTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an artifact controlled by " + player.getLogName()); - filter.add(CardType.ARTIFACT.getPredicate()); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may destroy target artifact that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java b/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java index 91f363b551e..d422797b1b5 100644 --- a/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java +++ b/Mage.Sets/src/mage/cards/c/ChangeOfPlans.java @@ -33,8 +33,8 @@ public final class ChangeOfPlans extends CardImpl { // Each of X target creatures you control connive. You may have any number of them phase out. this.getSpellAbility().addEffect(new ChangeOfPlansEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private ChangeOfPlans(final ChangeOfPlans card) { diff --git a/Mage.Sets/src/mage/cards/c/ChokingVines.java b/Mage.Sets/src/mage/cards/c/ChokingVines.java index e89c8aaec5d..d07731b13f5 100644 --- a/Mage.Sets/src/mage/cards/c/ChokingVines.java +++ b/Mage.Sets/src/mage/cards/c/ChokingVines.java @@ -30,8 +30,8 @@ public final class ChokingVines extends CardImpl { .setText("X target attacking creatures become blocked.")); this.getSpellAbility().addEffect(new DamageTargetEffect(1) .setText("{this} deals 1 damage to each of those creatures")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ATTACKING_CREATURES)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private ChokingVines(final ChokingVines card) { diff --git a/Mage.Sets/src/mage/cards/c/CometStorm.java b/Mage.Sets/src/mage/cards/c/CometStorm.java index 33ef207045f..07d72fe74bf 100644 --- a/Mage.Sets/src/mage/cards/c/CometStorm.java +++ b/Mage.Sets/src/mage/cards/c/CometStorm.java @@ -31,8 +31,8 @@ public final class CometStorm extends CardImpl { // Choose any target, then choose another any target for each time Comet Storm was kicked. Comet Storm deals X damage to each of them. this.getSpellAbility().addEffect(new CometStormEffect()); this.getSpellAbility().addTarget(new TargetAnyTarget(1)); - this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(new IntPlusDynamicValue(1, MultikickerCount.instance))); this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(new IntPlusDynamicValue(1, MultikickerCount.instance))); } private CometStorm(final CometStorm card) { diff --git a/Mage.Sets/src/mage/cards/c/CommandoRaid.java b/Mage.Sets/src/mage/cards/c/CommandoRaid.java index 5cea82500fd..87a8b48da60 100644 --- a/Mage.Sets/src/mage/cards/c/CommandoRaid.java +++ b/Mage.Sets/src/mage/cards/c/CommandoRaid.java @@ -1,31 +1,23 @@ package mage.cards.c; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author TheElk801 + * @author notgreat */ public final class CommandoRaid extends CardImpl { @@ -33,12 +25,18 @@ public final class CommandoRaid extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // Until end of turn, target creature you control gains "When this creature deals combat damage to a player, you may have it deal damage equal to its power to target creature that player controls." + Effect effect = new DamageTargetEffect(new SourcePermanentPowerCount()); + effect.setText("have it deal damage equal to its power to target creature that player controls."); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, true, true); + ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.getSpellAbility().addEffect(new GainAbilityTargetEffect( - new CommandoRaidTriggeredAbility(), Duration.EndOfTurn, + ability, Duration.EndOfTurn, "Until end of turn, target creature you control gains " - + "\"When this creature deals combat damage to a player, " - + "you may have it deal damage equal to its power " - + "to target creature that player controls.\"" + + "\"When this creature deals combat damage to a player, " + + "you may have it deal damage equal to its power " + + "to target creature that player controls.\"" )); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); } @@ -52,72 +50,3 @@ public final class CommandoRaid extends CardImpl { return new CommandoRaid(this); } } - -class CommandoRaidTriggeredAbility extends TriggeredAbilityImpl { - - public CommandoRaidTriggeredAbility() { - super(Zone.BATTLEFIELD, new CommandoRaidEffect(), true); - } - - private CommandoRaidTriggeredAbility(final CommandoRaidTriggeredAbility ability) { - super(ability); - } - - @Override - public CommandoRaidTriggeredAbility copy() { - return new CommandoRaidTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Player opponent = game.getPlayer(event.getPlayerId()); - if (!damageEvent.isCombatDamage() - || !event.getSourceId().equals(this.getSourceId()) - || opponent == null) { - return false; - } - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - for (Effect effect : this.getAllEffects()) { - effect.setTargetPointer(new FixedTarget(event.getPlayerId())); - effect.setValue("damage", event.getAmount()); - } - return true; - } - - @Override - public String getRule() { - return "When this creature deals combat damage to a player, " - + "you may have it deal that much damage to target creature that player controls"; - } -} - -class CommandoRaidEffect extends OneShotEffect { - - CommandoRaidEffect() { - super(Outcome.Damage); - staticText = "it deals that much damage to target creature that player controls"; - } - - private CommandoRaidEffect(final CommandoRaidEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return new DamageTargetEffect((Integer) getValue("damage")).apply(game, source); - } - - @Override - public CommandoRaidEffect copy() { - return new CommandoRaidEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CrackleWithPower.java b/Mage.Sets/src/mage/cards/c/CrackleWithPower.java index 4f4d52a3fcb..6afbb3bf74a 100644 --- a/Mage.Sets/src/mage/cards/c/CrackleWithPower.java +++ b/Mage.Sets/src/mage/cards/c/CrackleWithPower.java @@ -26,8 +26,8 @@ public final class CrackleWithPower extends CardImpl { this.getSpellAbility().addEffect( new DamageTargetEffect(value).setText("{this} deals five times X damage to each of up to X targets") ); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetAnyTarget(0, 1)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private CrackleWithPower(final CrackleWithPower card) { diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java index ca611c29932..c94312062fa 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheSwine.java @@ -30,8 +30,8 @@ public final class CurseOfTheSwine extends CardImpl { this.getSpellAbility().addEffect(new CurseOfTheSwineEffect()); // Correct number of targets will be set in adjustTargets - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } diff --git a/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java b/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java index 15c1568792c..fe7efa6a38d 100644 --- a/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java +++ b/Mage.Sets/src/mage/cards/c/CustodiSoulcaller.java @@ -40,8 +40,8 @@ public final class CustodiSoulcaller extends CardImpl { // Whenever Custodi Soulcaller attacks, return target creature card with converted mana cost X or less from your graveyard to the battlefield, where X is the number of players you attacked with a creature this combat. Ability ability = new AttacksTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect().setText("return target creature card with mana value X or less from your graveyard to the battlefield, where X is the number of players you attacked this combat"), false); ability.addWatcher(new CustodiSoulcallerWatcher()); - ability.setTargetAdjuster(new ManaValueTargetAdjuster(CustodiSoulcallerValue.instance, ComparisonType.OR_LESS)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new ManaValueTargetAdjuster(CustodiSoulcallerValue.instance, ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DawningPurist.java b/Mage.Sets/src/mage/cards/d/DawningPurist.java index 5c3e9bde32f..b41e8c8ecf2 100644 --- a/Mage.Sets/src/mage/cards/d/DawningPurist.java +++ b/Mage.Sets/src/mage/cards/d/DawningPurist.java @@ -1,9 +1,9 @@ package mage.cards.d; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.MorphAbility; @@ -11,30 +11,33 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterEnchantmentPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author djbrez + * @author notgreat */ public final class DawningPurist extends CardImpl { + private static final FilterEnchantmentPermanent filter + = new FilterEnchantmentPermanent("enchantment that player controls"); + public DawningPurist(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.CLERIC); - + this.power = new MageInt(2); this.toughness = new MageInt(2); // Whenever Dawning Purist deals combat damage to a player, you may destroy target enchantment that player controls. - this.addAbility(new DawningPuristTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); // Morph {1}{W} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{1}{W}"))); @@ -49,44 +52,3 @@ public final class DawningPurist extends CardImpl { return new DawningPurist(this); } } - -class DawningPuristTriggeredAbility extends TriggeredAbilityImpl { - - DawningPuristTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private DawningPuristTriggeredAbility(final DawningPuristTriggeredAbility ability) { - super(ability); - } - - @Override - public DawningPuristTriggeredAbility copy() { - return new DawningPuristTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("enchantment that player controls"); - filter.add(new ControllerIdPredicate(event.getPlayerId())); - filter.setMessage("enchantment controlled by " + game.getPlayer(event.getTargetId()).getLogName()); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may destroy target enchantment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DeathDenied.java b/Mage.Sets/src/mage/cards/d/DeathDenied.java index 2ec4ae04fa8..0c08e04a841 100644 --- a/Mage.Sets/src/mage/cards/d/DeathDenied.java +++ b/Mage.Sets/src/mage/cards/d/DeathDenied.java @@ -26,8 +26,8 @@ public final class DeathDenied extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target creature cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private DeathDenied(final DeathDenied card) { diff --git a/Mage.Sets/src/mage/cards/d/DeathKiss.java b/Mage.Sets/src/mage/cards/d/DeathKiss.java index ae3109dc0f9..b60029d95d9 100644 --- a/Mage.Sets/src/mage/cards/d/DeathKiss.java +++ b/Mage.Sets/src/mage/cards/d/DeathKiss.java @@ -48,8 +48,8 @@ public final class DeathKiss extends CardImpl { Ability ability = new BecomesMonstrousSourceTriggeredAbility( new GoadTargetEffect().setText("goad up to X target creatures your opponents control") ); - ability.setTargetAdjuster(new TargetsCountAdjuster(GetMonstrosityXValue.instance)); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); + ability.setTargetAdjuster(new TargetsCountAdjuster(GetMonstrosityXValue.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DecoyGambit.java b/Mage.Sets/src/mage/cards/d/DecoyGambit.java index 6ef505bc150..e2a0abf6eb6 100644 --- a/Mage.Sets/src/mage/cards/d/DecoyGambit.java +++ b/Mage.Sets/src/mage/cards/d/DecoyGambit.java @@ -33,8 +33,8 @@ public final class DecoyGambit extends CardImpl { // For each opponent, choose up to one target creature that player controls, // then return that creature to its owner's hand unless its controller has you draw a card. this.getSpellAbility().addEffect(new DecoyGambitEffect()); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0,1)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private DecoyGambit(final DecoyGambit card) { diff --git a/Mage.Sets/src/mage/cards/d/DeluxeDragster.java b/Mage.Sets/src/mage/cards/d/DeluxeDragster.java index fc787d555a3..eba0ecfca95 100644 --- a/Mage.Sets/src/mage/cards/d/DeluxeDragster.java +++ b/Mage.Sets/src/mage/cards/d/DeluxeDragster.java @@ -1,34 +1,36 @@ package mage.cards.d; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MayCastTargetCardEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.abilities.effects.common.replacement.ThatSpellGraveyardExileReplacementEffect; import mage.abilities.keyword.CrewAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.CastManaAdjustment; +import mage.constants.Duration; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterInstantOrSorceryCard; import mage.filter.predicate.Predicates; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.Target; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author TheElk801, Grath, xenohedron + * @author TheElk801, Grath, xenohedron, notgreat */ public final class DeluxeDragster extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("except by Vehicles"); + private static final FilterCard filterCard = new FilterInstantOrSorceryCard("instant or sorcery card from that player's graveyard"); static { filter.add(Predicates.not(SubType.VEHICLE.getPredicate())); @@ -46,7 +48,14 @@ public final class DeluxeDragster extends CardImpl { // Whenever Deluxe Dragster deals combat damage to a player, you may cast target instant or sorcery card from // that player’s graveyard without paying its mana cost. If that spell would be put into a graveyard, exile it instead. - this.addAbility(new DeluxeDragsterTriggeredAbility()); + OneShotEffect effect = new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST, true); + effect.setText("you may cast target instant or sorcery card from " + + "that player's graveyard without paying its mana cost. " + + ThatSpellGraveyardExileReplacementEffect.RULE_A); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetCardInGraveyard(filterCard)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); // Crew 2 this.addAbility(new CrewAbility(2)); @@ -61,49 +70,3 @@ public final class DeluxeDragster extends CardImpl { return new DeluxeDragster(this); } } - -class DeluxeDragsterTriggeredAbility extends TriggeredAbilityImpl { - - DeluxeDragsterTriggeredAbility() { - super(Zone.BATTLEFIELD, new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST, true) - .setText("you may cast target instant or sorcery card from " - + "that player's graveyard without paying its mana cost. " - + ThatSpellGraveyardExileReplacementEffect.RULE_A), false); - setTriggerPhrase("Whenever {this} deals combat damage to a player, "); - } - - private DeluxeDragsterTriggeredAbility(final DeluxeDragsterTriggeredAbility ability) { - super(ability); - } - - @Override - public DeluxeDragsterTriggeredAbility copy() { - return new DeluxeDragsterTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterCard("instant or sorcery card from that player's graveyard"); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - filter.add(Predicates.or( - CardType.INSTANT.getPredicate(), - CardType.SORCERY.getPredicate() - )); - Target target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DesecrateReality.java b/Mage.Sets/src/mage/cards/d/DesecrateReality.java index a1f22f83754..ae0d5b45ff1 100644 --- a/Mage.Sets/src/mage/cards/d/DesecrateReality.java +++ b/Mage.Sets/src/mage/cards/d/DesecrateReality.java @@ -44,8 +44,8 @@ public final class DesecrateReality extends CardImpl { this.getSpellAbility().addEffect(new ExileTargetEffect() .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, exile up to one target permanent that player controls with an even mana value.")); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, evenFilter)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); // Adamant -- If at least three colorless mana was spent to cast this spell, return a permanent card with an odd mana value from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( diff --git a/Mage.Sets/src/mage/cards/d/Detonate.java b/Mage.Sets/src/mage/cards/d/Detonate.java index c06657376a3..867c3e37f4c 100644 --- a/Mage.Sets/src/mage/cards/d/Detonate.java +++ b/Mage.Sets/src/mage/cards/d/Detonate.java @@ -28,8 +28,8 @@ public final class Detonate extends CardImpl { Effect effect = new DamageTargetControllerEffect(ManacostVariableValue.REGULAR); effect.setText("{this} deals X damage to that artifact's controller"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetArtifactPermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private Detonate(final Detonate card) { diff --git a/Mage.Sets/src/mage/cards/d/Disembowel.java b/Mage.Sets/src/mage/cards/d/Disembowel.java index 44b391c17e0..8d9993fa059 100644 --- a/Mage.Sets/src/mage/cards/d/Disembowel.java +++ b/Mage.Sets/src/mage/cards/d/Disembowel.java @@ -20,8 +20,8 @@ public final class Disembowel extends CardImpl { // Destroy target creature with converted mana cost X. this.getSpellAbility().addEffect(new DestroyTargetEffect("destroy target creature with mana value X")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private Disembowel(final Disembowel card) { diff --git a/Mage.Sets/src/mage/cards/d/DismantlingWave.java b/Mage.Sets/src/mage/cards/d/DismantlingWave.java index 22dac026cb7..7c928ee2846 100644 --- a/Mage.Sets/src/mage/cards/d/DismantlingWave.java +++ b/Mage.Sets/src/mage/cards/d/DismantlingWave.java @@ -27,8 +27,8 @@ public final class DismantlingWave extends CardImpl { this.getSpellAbility().addEffect(new DestroyTargetEffect() .setTargetPointer(new EachTargetPointer()) .setText("For each opponent, destroy up to one target artifact or enchantment that player controls.")); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); // Cycling {6}{W}{W} this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{6}{W}{W}"))); diff --git a/Mage.Sets/src/mage/cards/d/DisorderInTheCourt.java b/Mage.Sets/src/mage/cards/d/DisorderInTheCourt.java index 32a64703709..1ed4b3ceb2e 100644 --- a/Mage.Sets/src/mage/cards/d/DisorderInTheCourt.java +++ b/Mage.Sets/src/mage/cards/d/DisorderInTheCourt.java @@ -35,8 +35,8 @@ public final class DisorderInTheCourt extends CardImpl { // Exile X target creatures, then investigate X times. Return the exiled cards to the battlefield tapped under their owners' control at the beginning of the next end step. this.getSpellAbility().addEffect(new DisorderInTheCourtEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private DisorderInTheCourt(final DisorderInTheCourt card) { diff --git a/Mage.Sets/src/mage/cards/d/DistortingWake.java b/Mage.Sets/src/mage/cards/d/DistortingWake.java index 1c1ca7dcf8b..cf910f04e69 100644 --- a/Mage.Sets/src/mage/cards/d/DistortingWake.java +++ b/Mage.Sets/src/mage/cards/d/DistortingWake.java @@ -23,8 +23,8 @@ public final class DistortingWake extends CardImpl { Effect effect = new ReturnToHandTargetEffect(); effect.setText("Return X target nonland permanents to their owners' hands"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetNonlandPermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private DistortingWake(final DistortingWake card) { diff --git a/Mage.Sets/src/mage/cards/d/DokuchiSilencer.java b/Mage.Sets/src/mage/cards/d/DokuchiSilencer.java index 665dc888daa..37f24e3977e 100644 --- a/Mage.Sets/src/mage/cards/d/DokuchiSilencer.java +++ b/Mage.Sets/src/mage/cards/d/DokuchiSilencer.java @@ -42,7 +42,7 @@ public final class DokuchiSilencer extends CardImpl { this.addAbility(new NinjutsuAbility("{1}{B}")); // Whenever Dokuchi Silencer deals combat damage to a player, you may discard a creature card. When you do, destroy target creature or planeswalker that player controls. - this.addAbility(new BlindZealotTriggeredAbility()); + this.addAbility(new DokuchiSilencerTriggeredAbility()); } private DokuchiSilencer(final DokuchiSilencer card) { @@ -55,19 +55,19 @@ public final class DokuchiSilencer extends CardImpl { } } -class BlindZealotTriggeredAbility extends TriggeredAbilityImpl { +class DokuchiSilencerTriggeredAbility extends TriggeredAbilityImpl { - BlindZealotTriggeredAbility() { + DokuchiSilencerTriggeredAbility() { super(Zone.BATTLEFIELD, null, false); } - private BlindZealotTriggeredAbility(final BlindZealotTriggeredAbility ability) { + private DokuchiSilencerTriggeredAbility(final DokuchiSilencerTriggeredAbility ability) { super(ability); } @Override - public BlindZealotTriggeredAbility copy() { - return new BlindZealotTriggeredAbility(this); + public DokuchiSilencerTriggeredAbility copy() { + return new DokuchiSilencerTriggeredAbility(this); } @Override diff --git a/Mage.Sets/src/mage/cards/d/Doppelgang.java b/Mage.Sets/src/mage/cards/d/Doppelgang.java index f059102ddcd..ce8b93cf106 100644 --- a/Mage.Sets/src/mage/cards/d/Doppelgang.java +++ b/Mage.Sets/src/mage/cards/d/Doppelgang.java @@ -24,8 +24,8 @@ public final class Doppelgang extends CardImpl { // For each of X target permanents, create X tokens that are copies of that permanent. this.getSpellAbility().addEffect(new DoppelgangEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private Doppelgang(final Doppelgang card) { diff --git a/Mage.Sets/src/mage/cards/d/DreadmawsIre.java b/Mage.Sets/src/mage/cards/d/DreadmawsIre.java index 3732a61c7e3..0ca1d4808f0 100644 --- a/Mage.Sets/src/mage/cards/d/DreadmawsIre.java +++ b/Mage.Sets/src/mage/cards/d/DreadmawsIre.java @@ -1,6 +1,10 @@ package mage.cards.d; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.dynamicvalue.common.SourcePermanentPowerCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; @@ -8,24 +12,21 @@ import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetAttackingCreature; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author Susucr + * @author notgreat */ public final class DreadmawsIre extends CardImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public DreadmawsIre(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); @@ -36,9 +37,14 @@ public final class DreadmawsIre extends CardImpl { this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()) .setText("and gains trample")); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect( - new DreadmawsIreTriggeredAbility() - ).setText("and \"Whenever this creature deals combat damage to a player, destroy target artifact that player controls.\"")); + Effect effect = new DamageTargetEffect(new SourcePermanentPowerCount()); + effect.setText("have it deal damage equal to its power to target creature that player controls."); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(ability) + .setText("and \"Whenever this creature deals combat damage to a player, destroy target artifact that player controls.\"")); } private DreadmawsIre(final DreadmawsIre card) { @@ -50,51 +56,3 @@ public final class DreadmawsIre extends CardImpl { return new DreadmawsIre(this); } } - -/** - * Inspired by {@link mage.cards.t.TrygonPredator} - */ -class DreadmawsIreTriggeredAbility extends TriggeredAbilityImpl { - - public DreadmawsIreTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), false); - } - - private DreadmawsIreTriggeredAbility(final DreadmawsIreTriggeredAbility ability) { - super(ability); - } - - @Override - public DreadmawsIreTriggeredAbility copy() { - return new DreadmawsIreTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - - Player player = game.getPlayer(event.getTargetId()); - if (player == null) { - return false; - } - - FilterPermanent filter = new FilterArtifactPermanent("an artifact controlled by " + player.getLogName()); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, destroy target artifact that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java index 08c913a156b..bbcc971b87d 100644 --- a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java +++ b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java @@ -23,8 +23,8 @@ public final class DregsOfSorrow extends CardImpl { // Destroy X target nonblack creatures. Draw X cards. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target nonblack creatures")); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ManacostVariableValue.REGULAR)); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURES_NON_BLACK)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private DregsOfSorrow(final DregsOfSorrow card) { diff --git a/Mage.Sets/src/mage/cards/e/ElminstersSimulacrum.java b/Mage.Sets/src/mage/cards/e/ElminstersSimulacrum.java index 1c18cea6b4f..a78e92e87b0 100644 --- a/Mage.Sets/src/mage/cards/e/ElminstersSimulacrum.java +++ b/Mage.Sets/src/mage/cards/e/ElminstersSimulacrum.java @@ -25,8 +25,8 @@ public final class ElminstersSimulacrum extends CardImpl { // For each opponent, you create a token that's a copy of up to one target creature that player controls. this.getSpellAbility().addEffect(new ElminstersSimulacrumAdjusterEffect()); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0,1)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private ElminstersSimulacrum(final ElminstersSimulacrum card) { diff --git a/Mage.Sets/src/mage/cards/e/EnigmaThief.java b/Mage.Sets/src/mage/cards/e/EnigmaThief.java index f83d56988b2..ae1576c35ad 100644 --- a/Mage.Sets/src/mage/cards/e/EnigmaThief.java +++ b/Mage.Sets/src/mage/cards/e/EnigmaThief.java @@ -39,8 +39,8 @@ public final class EnigmaThief extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect() .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, return up to one target nonland permanent that player controls to its owner's hand")); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetNonlandPermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EntDraughtBasin.java b/Mage.Sets/src/mage/cards/e/EntDraughtBasin.java index 0f73952585d..bf8b7ede397 100644 --- a/Mage.Sets/src/mage/cards/e/EntDraughtBasin.java +++ b/Mage.Sets/src/mage/cards/e/EntDraughtBasin.java @@ -30,8 +30,8 @@ public final class EntDraughtBasin extends CardImpl { new ManaCostsImpl<>("{X}") ); ability.addCost(new TapSourceCost()); - ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.EQUAL_TO)); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.EQUAL_TO)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EntrancingLyre.java b/Mage.Sets/src/mage/cards/e/EntrancingLyre.java index 7f2c5237d84..ffe1747457e 100644 --- a/Mage.Sets/src/mage/cards/e/EntrancingLyre.java +++ b/Mage.Sets/src/mage/cards/e/EntrancingLyre.java @@ -33,8 +33,8 @@ public final class EntrancingLyre extends CardImpl { ); ability.addCost(new TapSourceCost()); ability.addEffect(new DontUntapAsLongAsSourceTappedEffect()); - ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EntreatTheDead.java b/Mage.Sets/src/mage/cards/e/EntreatTheDead.java index f9d65163a9e..8003222b954 100644 --- a/Mage.Sets/src/mage/cards/e/EntreatTheDead.java +++ b/Mage.Sets/src/mage/cards/e/EntreatTheDead.java @@ -21,8 +21,8 @@ public final class EntreatTheDead extends CardImpl { // Return X target creature cards from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect().setText("return X target creature cards from your graveyard to the battlefield")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); // Miracle {X}{B}{B} this.addAbility(new MiracleAbility("{X}{B}{B}")); diff --git a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java index 80a445ca94d..6d198edacd4 100644 --- a/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java +++ b/Mage.Sets/src/mage/cards/e/EtrataTheSilencer.java @@ -1,36 +1,33 @@ package mage.cards.e; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Mode; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ShuffleIntoLibrarySourceEffect; import mage.abilities.keyword.CantBeBlockedSourceAbility; import mage.cards.Card; 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.constants.Zone; +import mage.constants.*; import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author TheElk801 + * @author TheElk801. notgreat */ public final class EtrataTheSilencer extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); public EtrataTheSilencer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); @@ -45,7 +42,11 @@ public final class EtrataTheSilencer extends CardImpl { this.addAbility(new CantBeBlockedSourceAbility()); // Whenever Etrata deals combat damage to a player, exile target creature that player controls and put a hit counter on that card. That player loses the game if they own three or more exiled card with hit counters on them. Etrata's owner shuffles Etrata into their library. - this.addAbility(new EtrataTheSilencerTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new EtrataTheSilencerEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + + this.addAbility(ability); } private EtrataTheSilencer(final EtrataTheSilencer card) { @@ -58,53 +59,6 @@ public final class EtrataTheSilencer extends CardImpl { } } -class EtrataTheSilencerTriggeredAbility extends TriggeredAbilityImpl { - - public EtrataTheSilencerTriggeredAbility() { - super(Zone.BATTLEFIELD, new EtrataTheSilencerEffect()); - } - - private EtrataTheSilencerTriggeredAbility(final EtrataTheSilencerTriggeredAbility ability) { - super(ability); - } - - @Override - public EtrataTheSilencerTriggeredAbility copy() { - return new EtrataTheSilencerTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "exile target creature that player controls " - + "and put a hit counter on that card. " - + "That player loses the game if they own three or more " - + "exiled cards with hit counters on them. " - + "{this}'s owner shuffles {this} into their library."; - } -} - class EtrataTheSilencerEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard(); @@ -157,4 +111,13 @@ class EtrataTheSilencerEffect extends OneShotEffect { controller.shuffleLibrary(source, game); return true; } + + @Override + public String getText(Mode mode) { + return "exile target creature that player controls " + + "and put a hit counter on that card. " + + "That player loses the game if they own three or more " + + "exiled cards with hit counters on them. " + + "{this}'s owner shuffles {this} into their library"; + } } diff --git a/Mage.Sets/src/mage/cards/e/ExtraordinaryJourney.java b/Mage.Sets/src/mage/cards/e/ExtraordinaryJourney.java index 18daf3e5924..6818199f6c8 100644 --- a/Mage.Sets/src/mage/cards/e/ExtraordinaryJourney.java +++ b/Mage.Sets/src/mage/cards/e/ExtraordinaryJourney.java @@ -43,8 +43,8 @@ public final class ExtraordinaryJourney extends CardImpl { // When Extraordinary Journey enters the battlefield, exile up to X target creatures. For each of those cards, its owner may play it for as long as it remains exiled. Ability ability = new EntersBattlefieldTriggeredAbility(new ExtraordinaryJourneyEffect()); - ability.setTargetAdjuster(new XTargetsCountAdjuster()); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(ability); // Whenever one or more nontoken creatures enter the battlefield, if one or more of them entered from exile or was cast from exile, you draw a card. This ability triggers only once each turn. diff --git a/Mage.Sets/src/mage/cards/f/FinaleOfEternity.java b/Mage.Sets/src/mage/cards/f/FinaleOfEternity.java index 6dfbc6d6e9d..971da2a7115 100644 --- a/Mage.Sets/src/mage/cards/f/FinaleOfEternity.java +++ b/Mage.Sets/src/mage/cards/f/FinaleOfEternity.java @@ -28,8 +28,8 @@ public final class FinaleOfEternity extends CardImpl { // Destroy up to three target creatures with toughness X or less. If X is 10 or more, return all creature cards from your graveyard to the battlefield. this.getSpellAbility().addEffect(new DestroyTargetEffect().setText("destroy up to three target creatures with toughness X or less")); this.getSpellAbility().addEffect(new FinaleOfEternityEffect()); - this.getSpellAbility().setTargetAdjuster(new ToughnessTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetPermanent(0, 3, StaticFilters.FILTER_PERMANENT_CREATURES)); + this.getSpellAbility().setTargetAdjuster(new ToughnessTargetAdjuster(ComparisonType.OR_LESS)); } private FinaleOfEternity(final FinaleOfEternity card) { diff --git a/Mage.Sets/src/mage/cards/f/Firestorm.java b/Mage.Sets/src/mage/cards/f/Firestorm.java index 26ad19a95cb..a2f7f19f98f 100644 --- a/Mage.Sets/src/mage/cards/f/Firestorm.java +++ b/Mage.Sets/src/mage/cards/f/Firestorm.java @@ -30,8 +30,8 @@ public final class Firestorm extends CardImpl { // Firestorm deals X damage to each of X target creatures and/or players. this.getSpellAbility().addEffect(new FirestormEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private Firestorm(final Firestorm card) { diff --git a/Mage.Sets/src/mage/cards/g/GangUp.java b/Mage.Sets/src/mage/cards/g/GangUp.java index 03769d5b036..12bc2d46121 100644 --- a/Mage.Sets/src/mage/cards/g/GangUp.java +++ b/Mage.Sets/src/mage/cards/g/GangUp.java @@ -26,8 +26,8 @@ public final class GangUp extends CardImpl { // Destroy target creature with power X or less. this.getSpellAbility().addEffect(new DestroyTargetEffect("destroy target creature with power X or less")); - this.getSpellAbility().setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE)); + this.getSpellAbility().setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); } private GangUp(final GangUp card) { diff --git a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java index 9bcb2c90fbe..df613d1dec7 100644 --- a/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java +++ b/Mage.Sets/src/mage/cards/g/GethLordOfTheVault.java @@ -47,8 +47,8 @@ public final class GethLordOfTheVault extends CardImpl { // {X}{B}: Put target artifact or creature card with converted mana cost X from an opponent's graveyard onto the battlefield under your control tapped. // Then that player puts the top X cards of their library into their graveyard. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GethLordOfTheVaultEffect(), new ManaCostsImpl<>("{X}{B}")); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInGraveyard(filter)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java b/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java index cc8d843093b..57508711b98 100644 --- a/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java +++ b/Mage.Sets/src/mage/cards/g/GhostLitDrifter.java @@ -47,8 +47,8 @@ public final class GhostLitDrifter extends CardImpl { FlyingAbility.getInstance(), Duration.EndOfTurn, "X target creatures gain flying until end of turn" )); - ability.setTargetAdjuster(new XTargetsCountAdjuster()); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java b/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java index a26a974a194..d8e573263a4 100644 --- a/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java +++ b/Mage.Sets/src/mage/cards/g/GlimpseTheSunGod.java @@ -22,8 +22,8 @@ public final class GlimpseTheSunGod extends CardImpl { // Tap X target creatures. Scry 1. this.getSpellAbility().addEffect(new TapTargetEffect("tap X target creatures")); this.getSpellAbility().addEffect(new ScryEffect(1)); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private GlimpseTheSunGod(final GlimpseTheSunGod card) { diff --git a/Mage.Sets/src/mage/cards/g/GraspOfFate.java b/Mage.Sets/src/mage/cards/g/GraspOfFate.java index 6241bc6a740..e7f6012bb04 100644 --- a/Mage.Sets/src/mage/cards/g/GraspOfFate.java +++ b/Mage.Sets/src/mage/cards/g/GraspOfFate.java @@ -25,8 +25,8 @@ public final class GraspOfFate extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, exile up to one target nonland permanent that player controls until {this} leaves the battlefield") ); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetNonlandPermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Gridlock.java b/Mage.Sets/src/mage/cards/g/Gridlock.java index 32ce19c71e7..b97785ac3cc 100644 --- a/Mage.Sets/src/mage/cards/g/Gridlock.java +++ b/Mage.Sets/src/mage/cards/g/Gridlock.java @@ -20,8 +20,8 @@ public final class Gridlock extends CardImpl { // Tap X target nonland permanents. this.getSpellAbility().addEffect(new TapTargetEffect("tap X target nonland permanents")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetNonlandPermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private Gridlock(final Gridlock card) { diff --git a/Mage.Sets/src/mage/cards/h/HammerOfRuin.java b/Mage.Sets/src/mage/cards/h/HammerOfRuin.java index 5737900f338..b1c238709e5 100644 --- a/Mage.Sets/src/mage/cards/h/HammerOfRuin.java +++ b/Mage.Sets/src/mage/cards/h/HammerOfRuin.java @@ -2,8 +2,8 @@ package mage.cards.h; -import java.util.UUID; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DestroyTargetEffect; @@ -15,29 +15,33 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; +import mage.filter.common.FilterEquipmentPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author Loki + * @author notgreat */ public final class HammerOfRuin extends CardImpl { - public HammerOfRuin (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + private static final FilterEquipmentPermanent filter + = new FilterEquipmentPermanent("Equipment that player controls"); + + public HammerOfRuin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 0))); + // Whenever equipped creature deals combat damage to a player, you may destroy target Equipment that player controls. - this.addAbility(new HammerOfRuinTriggeredAbility()); + Ability ability = new DealsDamageToAPlayerAttachedTriggeredAbility(new DestroyTargetEffect(), "equipped creature", false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); + // Equip {2} this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), false)); } @@ -52,46 +56,3 @@ public final class HammerOfRuin extends CardImpl { } } - -class HammerOfRuinTriggeredAbility extends TriggeredAbilityImpl { - - HammerOfRuinTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private HammerOfRuinTriggeredAbility(final HammerOfRuinTriggeredAbility ability) { - super(ability); - } - - @Override - public HammerOfRuinTriggeredAbility copy() { - return new HammerOfRuinTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; - Permanent p = game.getPermanent(event.getSourceId()); - if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) { - FilterPermanent filter = new FilterPermanent("Equipment that player controls"); - filter.add(SubType.EQUIPMENT.getPredicate()); - filter.add(new ControllerIdPredicate(event.getPlayerId())); - filter.setMessage("creature controlled by " + game.getPlayer(event.getTargetId()).getLogName()); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever equipped creature deals combat damage to a player, you may destroy target Equipment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/h/HammersOfMoradin.java b/Mage.Sets/src/mage/cards/h/HammersOfMoradin.java index c43b89939ea..64efef5e031 100644 --- a/Mage.Sets/src/mage/cards/h/HammersOfMoradin.java +++ b/Mage.Sets/src/mage/cards/h/HammersOfMoradin.java @@ -37,8 +37,8 @@ public final class HammersOfMoradin extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, tap up to one target creature that player controls") ); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HideousTaskmaster.java b/Mage.Sets/src/mage/cards/h/HideousTaskmaster.java index 36dca80d1c8..a6db807d723 100644 --- a/Mage.Sets/src/mage/cards/h/HideousTaskmaster.java +++ b/Mage.Sets/src/mage/cards/h/HideousTaskmaster.java @@ -41,8 +41,8 @@ public final class HideousTaskmaster extends CardImpl { Ability ability = new CastSourceTriggeredAbility( new GainControlTargetEffect(Duration.EndOfTurn).setTargetPointer(new EachTargetPointer()).setText( "for each opponent, gain control of up to one target creature that player controls until end of turn")); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addEffect( new UntapTargetEffect().setTargetPointer(new EachTargetPointer()).setText("Untap those creatures")); ability.addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) diff --git a/Mage.Sets/src/mage/cards/h/HourOfEternity.java b/Mage.Sets/src/mage/cards/h/HourOfEternity.java index f3e0df78a29..270eac61a7d 100644 --- a/Mage.Sets/src/mage/cards/h/HourOfEternity.java +++ b/Mage.Sets/src/mage/cards/h/HourOfEternity.java @@ -32,8 +32,8 @@ public final class HourOfEternity extends CardImpl { // Exile X target creature cards from your graveyard. For each card exiled this way, create a token that's a copy of that card, except it's a 4/4 black Zombie. this.getSpellAbility().addEffect(new HourOfEternityEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private HourOfEternity(final HourOfEternity card) { diff --git a/Mage.Sets/src/mage/cards/i/IcyBlast.java b/Mage.Sets/src/mage/cards/i/IcyBlast.java index db01c035198..f1e1a3a3858 100644 --- a/Mage.Sets/src/mage/cards/i/IcyBlast.java +++ b/Mage.Sets/src/mage/cards/i/IcyBlast.java @@ -32,8 +32,8 @@ public final class IcyBlast extends CardImpl { new LockedInCondition(FerociousCondition.instance)); effect.setText("
Ferocious — If you control a creature with power 4 or greater, those creatures don't untap during their controllers' next untap steps"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addHint(FerociousHint.instance); } diff --git a/Mage.Sets/src/mage/cards/i/InTheDarknessBindThem.java b/Mage.Sets/src/mage/cards/i/InTheDarknessBindThem.java index ac10e9577ff..a71cff5e69e 100644 --- a/Mage.Sets/src/mage/cards/i/InTheDarknessBindThem.java +++ b/Mage.Sets/src/mage/cards/i/InTheDarknessBindThem.java @@ -57,8 +57,8 @@ public final class InTheDarknessBindThem extends CardImpl { ability.addEffect(new TheRingTemptsYouEffect()); ability.getEffects().setTargetPointer(new EachTargetPointer()); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } ); diff --git a/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java b/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java index 846c0db65be..8d2360d22e5 100644 --- a/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java +++ b/Mage.Sets/src/mage/cards/i/IndomitableCreativity.java @@ -30,8 +30,8 @@ public final class IndomitableCreativity extends CardImpl { // Destroy X target artifacts and/or creatures. For each permanent destroyed this way, its controller reveals cards from the top of their library until an artifact or creature card is revealed and exiles that card. Those players put the exiled card onto the battlefield, then shuffle their libraries. this.getSpellAbility().addEffect(new IndomitableCreativityEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private IndomitableCreativity(final IndomitableCreativity card) { diff --git a/Mage.Sets/src/mage/cards/i/InkEyesServantOfOni.java b/Mage.Sets/src/mage/cards/i/InkEyesServantOfOni.java index 9bae77ae5de..bfe57449df6 100644 --- a/Mage.Sets/src/mage/cards/i/InkEyesServantOfOni.java +++ b/Mage.Sets/src/mage/cards/i/InkEyesServantOfOni.java @@ -1,8 +1,8 @@ package mage.cards.i; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.RegenerateSourceEffect; @@ -14,20 +14,20 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; -import mage.filter.FilterCard; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.filter.common.FilterCreatureCard; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author notgreat */ public final class InkEyesServantOfOni extends CardImpl { + private static final FilterCreatureCard filter + = new FilterCreatureCard("creature card from that player's graveyard"); + public InkEyesServantOfOni(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); this.subtype.add(SubType.RAT); @@ -41,7 +41,10 @@ public final class InkEyesServantOfOni extends CardImpl { this.addAbility(new NinjutsuAbility("{3}{B}{B}")); // Whenever Ink-Eyes, Servant of Oni deals combat damage to a player, you may put target creature card from that player's graveyard onto the battlefield under your control. - this.addAbility(new InkEyesServantOfOniTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true, true); + ability.addTarget(new TargetCardInGraveyard(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); // {1}{B}: Regenerate Ink-Eyes. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl<>("{1}{B}"))); @@ -56,49 +59,3 @@ public final class InkEyesServantOfOni extends CardImpl { return new InkEyesServantOfOni(this); } } - -class InkEyesServantOfOniTriggeredAbility extends TriggeredAbilityImpl { - - public InkEyesServantOfOniTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), true); - } - - private InkEyesServantOfOniTriggeredAbility(final InkEyesServantOfOniTriggeredAbility ability) { - super(ability); - } - - @Override - public InkEyesServantOfOniTriggeredAbility copy() { - return new InkEyesServantOfOniTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterCard("creature in " + damagedPlayer.getName() + "'s graveyard"); - filter.add(CardType.CREATURE.getPredicate()); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - TargetCardInGraveyard target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "you may put target creature card from that player's " - + "graveyard onto the battlefield under your control."; - } -} diff --git a/Mage.Sets/src/mage/cards/j/JuvenileMistDragon.java b/Mage.Sets/src/mage/cards/j/JuvenileMistDragon.java index 258e5033d2a..8be53c0323a 100644 --- a/Mage.Sets/src/mage/cards/j/JuvenileMistDragon.java +++ b/Mage.Sets/src/mage/cards/j/JuvenileMistDragon.java @@ -42,8 +42,8 @@ public final class JuvenileMistDragon extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("Each of those creatures doesn't untap during its controller's next untap step") ); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability.withFlavorWord("Confounding Clouds")); } diff --git a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java index 1a35da4e375..58bb5569f1f 100644 --- a/Mage.Sets/src/mage/cards/k/KaerveksPurge.java +++ b/Mage.Sets/src/mage/cards/k/KaerveksPurge.java @@ -25,8 +25,8 @@ public final class KaerveksPurge extends CardImpl { // Destroy target creature with converted mana cost X. If that creature dies this way, Kaervek's Purge deals damage equal to the creature's power to the creature's controller. this.getSpellAbility().addEffect(new KaerveksPurgeEffect()); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private KaerveksPurge(final KaerveksPurge card) { diff --git a/Mage.Sets/src/mage/cards/k/KillingGlare.java b/Mage.Sets/src/mage/cards/k/KillingGlare.java index 873d6f78e58..22c0d64ca4f 100644 --- a/Mage.Sets/src/mage/cards/k/KillingGlare.java +++ b/Mage.Sets/src/mage/cards/k/KillingGlare.java @@ -21,8 +21,8 @@ public final class KillingGlare extends CardImpl { // Destroy target creature with power X or less. this.getSpellAbility().addEffect(new DestroyTargetEffect("destroy target creature with power X or less")); - this.getSpellAbility().setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); } private KillingGlare(final KillingGlare card) { diff --git a/Mage.Sets/src/mage/cards/l/LatullasOrders.java b/Mage.Sets/src/mage/cards/l/LatullasOrders.java index 3f9e3ea6a0f..065a8d31516 100644 --- a/Mage.Sets/src/mage/cards/l/LatullasOrders.java +++ b/Mage.Sets/src/mage/cards/l/LatullasOrders.java @@ -1,8 +1,8 @@ package mage.cards.l; -import java.util.UUID; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.EnchantAbility; @@ -10,28 +10,25 @@ import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.constants.SubType; +import mage.filter.common.FilterArtifactPermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author L_J + * @author notgreat */ public final class LatullasOrders extends CardImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public LatullasOrders(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); this.subtype.add(SubType.AURA); // Flash @@ -44,7 +41,10 @@ public final class LatullasOrders extends CardImpl { this.addAbility(new EnchantAbility(auraTarget)); // Whenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls. - this.addAbility(new LatullasOrdersTriggeredAbility()); + Ability ability = new DealsDamageToAPlayerAttachedTriggeredAbility(new DestroyTargetEffect(), "enchanted creature", true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private LatullasOrders(final LatullasOrders card) { @@ -56,47 +56,3 @@ public final class LatullasOrders extends CardImpl { return new LatullasOrders(this); } } - -class LatullasOrdersTriggeredAbility extends TriggeredAbilityImpl { - - public LatullasOrdersTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private LatullasOrdersTriggeredAbility(final LatullasOrdersTriggeredAbility ability) { - super(ability); - } - - @Override - public LatullasOrdersTriggeredAbility copy() { - return new LatullasOrdersTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent enchantment = game.getPermanentOrLKIBattlefield(this.getSourceId()); - if (event.getSourceId().equals(enchantment.getAttachedTo()) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an artifact controlled by " + player.getLogName()); - filter.add(CardType.ARTIFACT.getPredicate()); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LazavTheMultifarious.java b/Mage.Sets/src/mage/cards/l/LazavTheMultifarious.java index 75be07827f7..53040b39fe2 100644 --- a/Mage.Sets/src/mage/cards/l/LazavTheMultifarious.java +++ b/Mage.Sets/src/mage/cards/l/LazavTheMultifarious.java @@ -47,8 +47,8 @@ public final class LazavTheMultifarious extends CardImpl { new LazavTheMultifariousEffect(), new ManaCostsImpl<>("{X}") ); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability); } @@ -115,8 +115,8 @@ class LazavTheMultifariousCopyApplier extends CopyApplier { new LazavTheMultifariousEffect(), new ManaCostsImpl<>("{X}") ); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); blueprint.getAbilities().add(ability); blueprint.setName("Lazav, the Multifarious"); blueprint.addSuperType(SuperType.LEGENDARY); diff --git a/Mage.Sets/src/mage/cards/l/LightwielderPaladin.java b/Mage.Sets/src/mage/cards/l/LightwielderPaladin.java index b87cc0a2912..00d395d0cbd 100644 --- a/Mage.Sets/src/mage/cards/l/LightwielderPaladin.java +++ b/Mage.Sets/src/mage/cards/l/LightwielderPaladin.java @@ -1,44 +1,53 @@ package mage.cards.l; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author North + * @author notgreat */ public final class LightwielderPaladin extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("black or red permanent that player controls"); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.BLACK), + new ColorPredicate(ObjectColor.RED))); + } + public LightwielderPaladin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.KNIGHT); this.power = new MageInt(4); this.toughness = new MageInt(4); + //First strike this.addAbility(FirstStrikeAbility.getInstance()); - this.addAbility(new LightwielderPaladinTriggeredAbility()); + + // Whenever Lightwielder Paladin deals combat damage to a player, you may exile target black or red permanent that player controls. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ExileTargetEffect(), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private LightwielderPaladin(final LightwielderPaladin card) { @@ -50,48 +59,3 @@ public final class LightwielderPaladin extends CardImpl { return new LightwielderPaladin(this); } } - -class LightwielderPaladinTriggeredAbility extends TriggeredAbilityImpl { - - public LightwielderPaladinTriggeredAbility() { - super(Zone.BATTLEFIELD, new ExileTargetEffect(), true); - } - - private LightwielderPaladinTriggeredAbility(final LightwielderPaladinTriggeredAbility ability) { - super(ability); - } - - @Override - public LightwielderPaladinTriggeredAbility copy() { - return new LightwielderPaladinTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("black or red permanent controlled by " + player.getLogName()); - filter.add(Predicates.or( - new ColorPredicate(ObjectColor.BLACK), - new ColorPredicate(ObjectColor.RED))); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may exile target black or red permanent that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LikenessLooter.java b/Mage.Sets/src/mage/cards/l/LikenessLooter.java index 2cdd846ac7e..b1cc6215cea 100644 --- a/Mage.Sets/src/mage/cards/l/LikenessLooter.java +++ b/Mage.Sets/src/mage/cards/l/LikenessLooter.java @@ -50,8 +50,8 @@ public final class LikenessLooter extends CardImpl { new LikenessLooterEffect(), new ManaCostsImpl<>("{X}") ); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability); } @@ -116,8 +116,8 @@ class LikenessLooterCopyApplier extends CopyApplier { new LikenessLooterEffect(), new ManaCostsImpl<>("{X}") ); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); blueprint.getAbilities().add(ability); return true; } diff --git a/Mage.Sets/src/mage/cards/l/LostInTheMaze.java b/Mage.Sets/src/mage/cards/l/LostInTheMaze.java index 1c6dd9a01d9..17a12a91fc4 100644 --- a/Mage.Sets/src/mage/cards/l/LostInTheMaze.java +++ b/Mage.Sets/src/mage/cards/l/LostInTheMaze.java @@ -44,8 +44,8 @@ public final class LostInTheMaze extends CardImpl { // When Lost in the Maze enters the battlefield, tap X target creatures. Put a stun counter on each of those creatures you don't control. Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect("tap X target creatures")); ability.addEffect(new LostInTheMazeEffect()); - ability.setTargetAdjuster(new XTargetsCountAdjuster()); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(ability); // Tapped creatures you control have hexproof. diff --git a/Mage.Sets/src/mage/cards/l/LullmagesDomination.java b/Mage.Sets/src/mage/cards/l/LullmagesDomination.java index a176e9d667a..ed42cec9e42 100644 --- a/Mage.Sets/src/mage/cards/l/LullmagesDomination.java +++ b/Mage.Sets/src/mage/cards/l/LullmagesDomination.java @@ -47,8 +47,8 @@ public final class LullmagesDomination extends CardImpl { // Gain control of target creature with converted mana cost X. this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.Custom) .setText("gain control of target creature with mana value X")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private LullmagesDomination(final LullmagesDomination card) { diff --git a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java index 57fb357ca8f..9ca665ac758 100644 --- a/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java +++ b/Mage.Sets/src/mage/cards/l/LuminatePrimordial.java @@ -40,8 +40,8 @@ public final class LuminatePrimordial extends CardImpl { // When Luminate Primordial enters the battlefield, for each opponent, exile up to one target creature // that player controls and that player gains life equal to its power. Ability ability = new EntersBattlefieldTriggeredAbility(new LuminatePrimordialEffect(), false); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java index 61d2e7bc30f..c0d3ca4c69b 100644 --- a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java +++ b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java @@ -38,8 +38,8 @@ public final class MaliciousAdvice extends CardImpl { effect.setText("Tap X target artifacts, creatures, and/or lands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(ManacostVariableValue.REGULAR)); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(filter)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private MaliciousAdvice(final MaliciousAdvice card) { diff --git a/Mage.Sets/src/mage/cards/m/MarchOfBurgeoningLife.java b/Mage.Sets/src/mage/cards/m/MarchOfBurgeoningLife.java index 300363227da..88e773676df 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfBurgeoningLife.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfBurgeoningLife.java @@ -44,8 +44,8 @@ public final class MarchOfBurgeoningLife extends CardImpl { // Choose target creature with mana value less than X. Search your library for a creature card with the same name as that creature, put it onto the battlefield tapped, then shuffle. this.getSpellAbility().addEffect(new MarchOfBurgeoningLifeEffect()); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.FEWER_THAN)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.FEWER_THAN)); } private MarchOfBurgeoningLife(final MarchOfBurgeoningLife card) { diff --git a/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java b/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java index f70266810d1..8f2e85efe9e 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfOtherworldlyLight.java @@ -44,8 +44,8 @@ public final class MarchOfOtherworldlyLight extends CardImpl { this.getSpellAbility().addEffect(new ExileTargetEffect( "exile target artifact, creature, or enchantment with mana value X or less" )); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetPermanent(filter2)); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); } private MarchOfOtherworldlyLight(final MarchOfOtherworldlyLight card) { diff --git a/Mage.Sets/src/mage/cards/m/MarchOfSwirlingMist.java b/Mage.Sets/src/mage/cards/m/MarchOfSwirlingMist.java index 7c8f91949ac..2bd17cc4a44 100644 --- a/Mage.Sets/src/mage/cards/m/MarchOfSwirlingMist.java +++ b/Mage.Sets/src/mage/cards/m/MarchOfSwirlingMist.java @@ -32,8 +32,8 @@ public final class MarchOfSwirlingMist extends CardImpl { // Up to X target creatures phase out. this.getSpellAbility().addEffect(new PhaseOutTargetEffect().setText("up to X target creatures phase out")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private MarchOfSwirlingMist(final MarchOfSwirlingMist card) { diff --git a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java index 671e26a2045..5aae7525acd 100644 --- a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java +++ b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java @@ -42,8 +42,8 @@ public final class MarshalsAnthem extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility( new ReturnFromGraveyardToBattlefieldTargetEffect().setText(rule), false ); - ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); ability.addTarget(new TargetCardInYourGraveyard(0, 1, StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MassMutiny.java b/Mage.Sets/src/mage/cards/m/MassMutiny.java index 72264d66b5d..5518750f6bd 100644 --- a/Mage.Sets/src/mage/cards/m/MassMutiny.java +++ b/Mage.Sets/src/mage/cards/m/MassMutiny.java @@ -31,8 +31,8 @@ public final class MassMutiny extends CardImpl { // For each opponent, gain control of up to one target creature that player controls until end of turn. Untap those creatures. They gain haste until end of turn. this.getSpellAbility().addEffect(new MassMutinyEffect()); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0,1)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private MassMutiny(final MassMutiny card) { diff --git a/Mage.Sets/src/mage/cards/m/MeteorBlast.java b/Mage.Sets/src/mage/cards/m/MeteorBlast.java index ed4dcbe40c6..786da447bef 100644 --- a/Mage.Sets/src/mage/cards/m/MeteorBlast.java +++ b/Mage.Sets/src/mage/cards/m/MeteorBlast.java @@ -21,8 +21,8 @@ public final class MeteorBlast extends CardImpl { this.getSpellAbility().addEffect( new DamageTargetEffect(4).setText("{this} deals 4 damage to each of X targets") ); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetAnyTarget()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private MeteorBlast(final MeteorBlast card) { diff --git a/Mage.Sets/src/mage/cards/m/MidnightArsonist.java b/Mage.Sets/src/mage/cards/m/MidnightArsonist.java index 4f83c5592a0..3f0be8f81e5 100644 --- a/Mage.Sets/src/mage/cards/m/MidnightArsonist.java +++ b/Mage.Sets/src/mage/cards/m/MidnightArsonist.java @@ -44,8 +44,8 @@ public final class MidnightArsonist extends CardImpl { // When Midnight Arsonist enters the battlefield, destroy up to X target artifacts without mana abilities, where X is the number of Vampires you control. Ability ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect() .setText("destroy up to X target artifacts without mana abilities, where X is the number of Vampires you control")); - ability.setTargetAdjuster(new TargetsCountAdjuster(new PermanentsOnBattlefieldCount(filter))); ability.addTarget(new TargetPermanent(0, 1, filter2)); + ability.setTargetAdjuster(new TargetsCountAdjuster(new PermanentsOnBattlefieldCount(filter))); ability.addHint(new ValueHint("Vampires you control", new PermanentsOnBattlefieldCount(filter))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MinamoSightbender.java b/Mage.Sets/src/mage/cards/m/MinamoSightbender.java index 5dd07b849f8..15661be296f 100644 --- a/Mage.Sets/src/mage/cards/m/MinamoSightbender.java +++ b/Mage.Sets/src/mage/cards/m/MinamoSightbender.java @@ -36,8 +36,8 @@ public final class MinamoSightbender extends CardImpl { // {X}, {T}: Target creature with power X or less can't be blocked this turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBeBlockedTargetEffect(), new ManaCostsImpl<>("{X}")); - ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetCreaturePermanent(filter)); + ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); ability.addCost(new TapSourceCost()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MistbladeShinobi.java b/Mage.Sets/src/mage/cards/m/MistbladeShinobi.java index 18f13a42693..304042e182e 100644 --- a/Mage.Sets/src/mage/cards/m/MistbladeShinobi.java +++ b/Mage.Sets/src/mage/cards/m/MistbladeShinobi.java @@ -1,34 +1,31 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.keyword.NinjutsuAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author notgreat */ public final class MistbladeShinobi extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public MistbladeShinobi(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.NINJA); @@ -39,7 +36,10 @@ public final class MistbladeShinobi extends CardImpl { this.addAbility(new NinjutsuAbility("{U}")); // Whenever Mistblade Shinobi deals combat damage to a player, you may return target creature that player controls to its owner's hand. - this.addAbility(new MistbladeShinobiTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandTargetEffect(), true, true); + ability.addTarget(new TargetCreaturePermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private MistbladeShinobi(final MistbladeShinobi card) { @@ -51,45 +51,3 @@ public final class MistbladeShinobi extends CardImpl { return new MistbladeShinobi(this); } } - -class MistbladeShinobiTriggeredAbility extends TriggeredAbilityImpl { - - MistbladeShinobiTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), true); - } - - private MistbladeShinobiTriggeredAbility(final MistbladeShinobiTriggeredAbility ability) { - super(ability); - } - - @Override - public MistbladeShinobiTriggeredAbility copy() { - return new MistbladeShinobiTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (((DamagedPlayerEvent) event).isCombatDamage() - && event.getSourceId().equals(sourceId)) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may return target creature that player controls to its owner's hand."; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MogissMarauder.java b/Mage.Sets/src/mage/cards/m/MogissMarauder.java index 8167a6ca2cb..3192b208998 100644 --- a/Mage.Sets/src/mage/cards/m/MogissMarauder.java +++ b/Mage.Sets/src/mage/cards/m/MogissMarauder.java @@ -41,8 +41,8 @@ public final class MogissMarauder extends CardImpl { HasteAbility.getInstance(), Duration.EndOfTurn, "and haste until end of turn, where X is your devotion to black" )); - ability.setTargetAdjuster(new TargetsCountAdjuster(DevotionCount.B)); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new TargetsCountAdjuster(DevotionCount.B)); ability.addHint(DevotionCount.B.getHint()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/Molder.java b/Mage.Sets/src/mage/cards/m/Molder.java index 282769b7a3a..2710f98ad14 100644 --- a/Mage.Sets/src/mage/cards/m/Molder.java +++ b/Mage.Sets/src/mage/cards/m/Molder.java @@ -24,8 +24,8 @@ public final class Molder extends CardImpl { // Destroy target artifact or enchantment with converted mana cost X. It can't be regenerated. You gain X life. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy target artifact or enchantment with mana value X. It can't be regenerated", true)); this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.REGULAR)); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private Molder(final Molder card) { diff --git a/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java b/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java index 7bb7f68d76b..7074703d156 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java +++ b/Mage.Sets/src/mage/cards/m/MoltenPrimordial.java @@ -41,8 +41,8 @@ public final class MoltenPrimordial extends CardImpl { // When Molten Primordial enters the battlefield, for each opponent, take control of up to one target creature that player controls until end of turn. Untap those creatures. They have haste until end of turn. Ability ability = new EntersBattlefieldTriggeredAbility(new MoltenPrimordialEffect(), false); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MordantDragon.java b/Mage.Sets/src/mage/cards/m/MordantDragon.java index 2187359edef..3b3574bce72 100644 --- a/Mage.Sets/src/mage/cards/m/MordantDragon.java +++ b/Mage.Sets/src/mage/cards/m/MordantDragon.java @@ -1,31 +1,29 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.SavedDamageValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** * - * @author jeffwadsworth + * @author notgreat */ public final class MordantDragon extends CardImpl { @@ -43,7 +41,12 @@ public final class MordantDragon extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{R}"))); // Whenever Mordant Dragon deals combat damage to a player, you may have it deal that much damage to target creature that player controls. - this.addAbility(new MordantDragonTriggeredAbility()); + Effect effect = new DamageTargetEffect(SavedDamageValue.MUCH); + effect.setText("have it deal that much damage to target creature that player controls."); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, true, true); + ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private MordantDragon(final MordantDragon card) { @@ -55,72 +58,3 @@ public final class MordantDragon extends CardImpl { return new MordantDragon(this); } } - -class MordantDragonTriggeredAbility extends TriggeredAbilityImpl { - - public MordantDragonTriggeredAbility() { - super(Zone.BATTLEFIELD, new MordantDragonEffect(), true); - } - - private MordantDragonTriggeredAbility(final MordantDragonTriggeredAbility ability) { - super(ability); - } - - @Override - public MordantDragonTriggeredAbility copy() { - return new MordantDragonTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - Player opponent = game.getPlayer(event.getPlayerId()); - if (!damageEvent.isCombatDamage() - || !event.getSourceId().equals(this.getSourceId()) - || opponent == null) { - return false; - } - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - for (Effect effect : this.getAllEffects()) { - effect.setTargetPointer(new FixedTarget(event.getPlayerId())); - effect.setValue("damage", event.getAmount()); - } - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "you may have it deal that much damage to target creature that player controls."; - } -} - -class MordantDragonEffect extends OneShotEffect { - - MordantDragonEffect() { - super(Outcome.Damage); - staticText = "it deals that much damage to target creature that player controls"; - } - - private MordantDragonEffect(final MordantDragonEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - return new DamageTargetEffect((Integer) getValue("damage")).apply(game, source); - } - - @Override - public MordantDragonEffect copy() { - return new MordantDragonEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/n/NahirisWrath.java b/Mage.Sets/src/mage/cards/n/NahirisWrath.java index 253781c8899..015faadbce0 100644 --- a/Mage.Sets/src/mage/cards/n/NahirisWrath.java +++ b/Mage.Sets/src/mage/cards/n/NahirisWrath.java @@ -28,8 +28,8 @@ public final class NahirisWrath extends CardImpl { Effect effect = new DamageTargetEffect(DiscardCostCardManaValue.instance); effect.setText("{this} deals damage equal to the total mana value of the discarded cards to each of up to X target creatures and/or planeswalkers"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker(0, 1)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private NahirisWrath(final NahirisWrath card) { diff --git a/Mage.Sets/src/mage/cards/n/NeyamShaiMurad.java b/Mage.Sets/src/mage/cards/n/NeyamShaiMurad.java index c2b4e8f6320..f66a570ca28 100644 --- a/Mage.Sets/src/mage/cards/n/NeyamShaiMurad.java +++ b/Mage.Sets/src/mage/cards/n/NeyamShaiMurad.java @@ -1,22 +1,19 @@ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.Zone; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInGraveyard; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.constants.CardType; -import mage.constants.Outcome; + +import java.util.UUID; /** * @@ -38,7 +35,7 @@ public final class NeyamShaiMurad extends CardImpl { this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new NeyamShaiMuradEffect(), true, true) .withFlavorWord("Rogue Trader") - ); + ); //TODO: The first should target when triggered, not on resolution } private NeyamShaiMurad(final NeyamShaiMurad card) { diff --git a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java index 12183b242c9..9bff99fef2d 100644 --- a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java +++ b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java @@ -29,8 +29,8 @@ public final class NostalgicDreams extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); // Exile Nostalgic Dreams. this.getSpellAbility().addEffect(new ExileSpellEffect()); diff --git a/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java b/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java index 0350f512842..0a6cfc634b8 100644 --- a/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java +++ b/Mage.Sets/src/mage/cards/o/OpenIntoWonder.java @@ -31,8 +31,8 @@ public final class OpenIntoWonder extends CardImpl { Ability abilityToGain = new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1), false); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(abilityToGain, Duration.EndOfTurn, "Until end of turn, those creatures gain \"Whenever this creature deals combat damage to a player, draw a card.\"")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private OpenIntoWonder(final OpenIntoWonder card) { diff --git a/Mage.Sets/src/mage/cards/o/OpenSeason.java b/Mage.Sets/src/mage/cards/o/OpenSeason.java index 9a6316526d3..0ecff002ed3 100644 --- a/Mage.Sets/src/mage/cards/o/OpenSeason.java +++ b/Mage.Sets/src/mage/cards/o/OpenSeason.java @@ -35,8 +35,8 @@ public final class OpenSeason extends CardImpl { Effect effect = new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()); effect.setText("for each opponent, put a bounty counter on target creature that player controls"); Ability ability = new EntersBattlefieldTriggeredAbility(effect); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); // Creatures your opponent control with bounty counters on them can't activate abilities diff --git a/Mage.Sets/src/mage/cards/o/Outmaneuver.java b/Mage.Sets/src/mage/cards/o/Outmaneuver.java index 8fc92535bad..d08a604e652 100644 --- a/Mage.Sets/src/mage/cards/o/Outmaneuver.java +++ b/Mage.Sets/src/mage/cards/o/Outmaneuver.java @@ -31,8 +31,8 @@ public final class Outmaneuver extends CardImpl { // X target blocked creatures assign their combat damage this turn as though they weren't blocked. this.getSpellAbility().addEffect(new OutmaneuverEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private Outmaneuver(final Outmaneuver card) { diff --git a/Mage.Sets/src/mage/cards/p/PestInfestation.java b/Mage.Sets/src/mage/cards/p/PestInfestation.java index 5589131aa37..066a8c0077e 100644 --- a/Mage.Sets/src/mage/cards/p/PestInfestation.java +++ b/Mage.Sets/src/mage/cards/p/PestInfestation.java @@ -30,8 +30,8 @@ public final class PestInfestation extends CardImpl { .setText("destroy up to X target artifacts and/or enchantments.")); this.getSpellAbility().addEffect(new CreateTokenEffect(new Pest11GainLifeToken(), xValue) .setText("Create twice X 1/1 black and green Pest creature tokens with \"When this creature dies, you gain 1 life.\"")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private PestInfestation(final PestInfestation card) { diff --git a/Mage.Sets/src/mage/cards/p/PolisCrusher.java b/Mage.Sets/src/mage/cards/p/PolisCrusher.java index 1a1ca134934..00b0f5d917c 100644 --- a/Mage.Sets/src/mage/cards/p/PolisCrusher.java +++ b/Mage.Sets/src/mage/cards/p/PolisCrusher.java @@ -1,9 +1,10 @@ package mage.cards.p; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.condition.common.MonstrousCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.MonstrosityAbility; import mage.abilities.keyword.ProtectionAbility; @@ -12,26 +13,24 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.filter.common.FilterEnchantmentCard; +import mage.filter.common.FilterEnchantmentPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author LevelX2, notgreat */ public final class PolisCrusher extends CardImpl { - private static final FilterCard filter = new FilterCard("enchantments"); + private static final FilterCard filterCard = new FilterEnchantmentCard("enchantments"); + private static final FilterEnchantmentPermanent filterPermanent = new FilterEnchantmentPermanent("enchantment that player controls"); static { - filter.add(CardType.ENCHANTMENT.getPredicate()); + filterCard.add(CardType.ENCHANTMENT.getPredicate()); } public PolisCrusher(UUID ownerId, CardSetInfo setInfo) { @@ -45,13 +44,18 @@ public final class PolisCrusher extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // protection from enchantments - this.addAbility(new ProtectionAbility(filter)); + this.addAbility(new ProtectionAbility(filterCard)); // {4}{R}{G}: Monstrosity 3. this.addAbility(new MonstrosityAbility("{4}{R}{G}", 3)); // Whenever Polis Crusher deals combat damage to a player, if Polis Crusher is monstrous, destroy target enchantment that player controls. - this.addAbility(new PolisCrusherTriggeredAbility()); + TriggeredAbility ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filterPermanent)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + + this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, MonstrousCondition.instance, + "Whenever {this} deals combat damage to a player, if {this} is monstrous, destroy target enchantment that player controls.")); } private PolisCrusher(final PolisCrusher card) { @@ -63,51 +67,3 @@ public final class PolisCrusher extends CardImpl { return new PolisCrusher(this); } } - -class PolisCrusherTriggeredAbility extends TriggeredAbilityImpl { - - public PolisCrusherTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private PolisCrusherTriggeredAbility(final PolisCrusherTriggeredAbility ability) { - super(ability); - } - - @Override - public PolisCrusherTriggeredAbility copy() { - return new PolisCrusherTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkInterveningIfClause(Game game) { - return MonstrousCondition.instance.apply(game, this); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an enchantment controlled by " + player.getLogName()); - filter.add(CardType.ENCHANTMENT.getPredicate()); - filter.add(new ControllerIdPredicate(event.getTargetId())); - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player," - + " if {this} is monstrous, destroy target enchantment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/q/QuarantineField.java b/Mage.Sets/src/mage/cards/q/QuarantineField.java index e9324303ae3..0a40f8fa302 100644 --- a/Mage.Sets/src/mage/cards/q/QuarantineField.java +++ b/Mage.Sets/src/mage/cards/q/QuarantineField.java @@ -32,8 +32,8 @@ public final class QuarantineField extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect() .setText("for each isolation counter on it, exile up to one target nonland permanent an opponent controls until {this} leaves the battlefield") ); - ability.setTargetAdjuster(new TargetsCountAdjuster(new CountersSourceCount(CounterType.ISOLATION))); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); + ability.setTargetAdjuster(new TargetsCountAdjuster(new CountersSourceCount(CounterType.ISOLATION))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/q/QuestingBeast.java b/Mage.Sets/src/mage/cards/q/QuestingBeast.java index 6a2caf9753d..4be886eed59 100644 --- a/Mage.Sets/src/mage/cards/q/QuestingBeast.java +++ b/Mage.Sets/src/mage/cards/q/QuestingBeast.java @@ -2,8 +2,9 @@ package mage.cards.q; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsDamageToOpponentTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.SavedDamageValue; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.DauntAbility; @@ -13,23 +14,21 @@ import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterPermanent; import mage.filter.common.FilterPlaneswalkerPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.events.DamagedEvent; import mage.game.events.GameEvent; import mage.game.events.PreventDamageEvent; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPermanent; +import mage.target.common.TargetPlaneswalkerPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author TheElk801 + * @author TheElk801, notgreat */ public final class QuestingBeast extends CardImpl { + private static final FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent("planeswalker that player controls"); public QuestingBeast(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); @@ -55,7 +54,10 @@ public final class QuestingBeast extends CardImpl { this.addAbility(new SimpleStaticAbility(new QuestingBeastPreventionEffect())); // Whenever Questing Beast deals combat damage to an opponent, it deals that much damage to target planeswalker that player controls. - this.addAbility(new QuestingBeastTriggeredAbility()); + Ability ability = new DealsDamageToOpponentTriggeredAbility(new DamageTargetEffect(SavedDamageValue.MUCH), false, true, true); + ability.addTarget(new TargetPlaneswalkerPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private QuestingBeast(final QuestingBeast card) { @@ -100,48 +102,3 @@ class QuestingBeastPreventionEffect extends ContinuousRuleModifyingEffectImpl { && permanent.isControlledBy(source.getControllerId()); } } - -class QuestingBeastTriggeredAbility extends TriggeredAbilityImpl { - - QuestingBeastTriggeredAbility() { - super(Zone.BATTLEFIELD, null, true); - } - - private QuestingBeastTriggeredAbility(final QuestingBeastTriggeredAbility ability) { - super(ability); - } - - @Override - public QuestingBeastTriggeredAbility copy() { - return new QuestingBeastTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent == null - || !event.getSourceId().equals(this.getSourceId()) - || !opponent.hasOpponent(this.getControllerId(), game) - || !((DamagedEvent) event).isCombatDamage()) { - return false; - } - this.getEffects().clear(); - this.addEffect(new DamageTargetEffect(event.getAmount())); - FilterPermanent filter = new FilterPlaneswalkerPermanent("planeswalker " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to an opponent, " + - "it deals that much damage to target planeswalker that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RatsFeast.java b/Mage.Sets/src/mage/cards/r/RatsFeast.java index 057a5eb8cfb..df9354d5ed3 100644 --- a/Mage.Sets/src/mage/cards/r/RatsFeast.java +++ b/Mage.Sets/src/mage/cards/r/RatsFeast.java @@ -20,8 +20,8 @@ public final class RatsFeast extends CardImpl { // Exile X target cards from a single graveyard. this.getSpellAbility().addEffect(new ExileTargetEffect("Exile X target cards from a single graveyard")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInASingleGraveyard(1, 1, StaticFilters.FILTER_CARD_CARDS)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private RatsFeast(final RatsFeast card) { diff --git a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java index d9c9b735537..02c84b7e8e4 100644 --- a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java +++ b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java @@ -23,8 +23,8 @@ public final class ReleaseTheGremlins extends CardImpl { // Destroy X target artifacts. this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target artifacts")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetArtifactPermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); // Create X 2/2 red Gremlin creature tokens. this.getSpellAbility().addEffect(new CreateTokenEffect(new GremlinToken(), ManacostVariableValue.REGULAR)); diff --git a/Mage.Sets/src/mage/cards/r/RestlessDreams.java b/Mage.Sets/src/mage/cards/r/RestlessDreams.java index 71ccc958eea..278a177431d 100644 --- a/Mage.Sets/src/mage/cards/r/RestlessDreams.java +++ b/Mage.Sets/src/mage/cards/r/RestlessDreams.java @@ -27,8 +27,8 @@ public final class RestlessDreams extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target creature cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private RestlessDreams(final RestlessDreams card) { diff --git a/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java b/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java index 6c576b44c0e..6d30c3997a7 100644 --- a/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java +++ b/Mage.Sets/src/mage/cards/r/ReturnToTheRanks.java @@ -35,8 +35,8 @@ public final class ReturnToTheRanks extends CardImpl { Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect(); effect.setText("Return X target creature cards with mana value 2 or less from your graveyard to the battlefield"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filter)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private ReturnToTheRanks(final ReturnToTheRanks card) { diff --git a/Mage.Sets/src/mage/cards/r/RiptideEntrancer.java b/Mage.Sets/src/mage/cards/r/RiptideEntrancer.java index d4be40d10c4..66e9db86583 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideEntrancer.java +++ b/Mage.Sets/src/mage/cards/r/RiptideEntrancer.java @@ -1,9 +1,11 @@ package mage.cards.r; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.MorphAbility; @@ -12,20 +14,18 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author TheElk801 + * @author notgreat */ public final class RiptideEntrancer extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); public RiptideEntrancer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); @@ -36,7 +36,11 @@ public final class RiptideEntrancer extends CardImpl { this.toughness = new MageInt(1); // Whenever Riptide Entrancer deals combat damage to a player, you may sacrifice it. If you do, gain control of target creature that player controls. - this.addAbility(new RiptideEntrancerTriggeredAbility()); + Effect effect = new DoIfCostPaid(new GainControlTargetEffect(Duration.WhileOnBattlefield), new SacrificeSourceCost()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); // Morph {U}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{U}{U}"))); @@ -51,46 +55,3 @@ public final class RiptideEntrancer extends CardImpl { return new RiptideEntrancer(this); } } - -class RiptideEntrancerTriggeredAbility extends TriggeredAbilityImpl { - - public RiptideEntrancerTriggeredAbility() { - super(Zone.BATTLEFIELD, new DoIfCostPaid( - new GainControlTargetEffect(Duration.Custom), - new SacrificeSourceCost() - ), false); - } - - private RiptideEntrancerTriggeredAbility(final RiptideEntrancerTriggeredAbility ability) { - super(ability); - } - - @Override - public RiptideEntrancerTriggeredAbility copy() { - return new RiptideEntrancerTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null && event.getSourceId().equals(this.sourceId)) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may sacrifice it. " - + "If you do, gain control of target creature that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RotHulk.java b/Mage.Sets/src/mage/cards/r/RotHulk.java index ded6248367e..b90cd4d3f93 100644 --- a/Mage.Sets/src/mage/cards/r/RotHulk.java +++ b/Mage.Sets/src/mage/cards/r/RotHulk.java @@ -38,8 +38,8 @@ public final class RotHulk extends CardImpl { // When Rot Hulk enters the battlefield, return up to X target Zombie cards from your graveyard to the battlefield, where X is the number of opponents you have. Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect() .setText("return up to X target Zombie cards from your graveyard to the battlefield, where X is the number of opponents you have.")); - ability.setTargetAdjuster(new TargetsCountAdjuster(OpponentsCount.instance)); ability.addTarget(new TargetCardInYourGraveyard(0, 1, filterZombie)); + ability.setTargetAdjuster(new TargetsCountAdjuster(OpponentsCount.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RustmouthOgre.java b/Mage.Sets/src/mage/cards/r/RustmouthOgre.java index ab4917be6db..e2b48e23a17 100644 --- a/Mage.Sets/src/mage/cards/r/RustmouthOgre.java +++ b/Mage.Sets/src/mage/cards/r/RustmouthOgre.java @@ -1,38 +1,40 @@ package mage.cards.r; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author dustinconrad + * @author notgreat */ public final class RustmouthOgre extends CardImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public RustmouthOgre(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); this.subtype.add(SubType.OGRE); this.power = new MageInt(5); this.toughness = new MageInt(4); // Whenever Rustmouth Ogre deals combat damage to a player, you may destroy target artifact that player controls. - this.addAbility(new RustmouthOgreTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private RustmouthOgre(final RustmouthOgre card) { @@ -44,44 +46,3 @@ public final class RustmouthOgre extends CardImpl { return new RustmouthOgre(this); } } - -class RustmouthOgreTriggeredAbility extends TriggeredAbilityImpl { - - RustmouthOgreTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private RustmouthOgreTriggeredAbility(final RustmouthOgreTriggeredAbility ability) { - super(ability); - } - - @Override - public RustmouthOgreTriggeredAbility copy() { - return new RustmouthOgreTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact that player controls"); - filter.add(new ControllerIdPredicate(event.getPlayerId())); - filter.setMessage("artifact controlled by " + game.getPlayer(event.getTargetId()).getLogName()); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may destroy target artifact that player controls."; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RuthlessTechnomancer.java b/Mage.Sets/src/mage/cards/r/RuthlessTechnomancer.java index 3f338e4ca7b..d066f2f7331 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessTechnomancer.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessTechnomancer.java @@ -53,8 +53,8 @@ public final class RuthlessTechnomancer extends CardImpl { new ManaCostsImpl<>("{2}{B}") ); ability.addCost(new SacrificeXTargetCost(filter, false, 1)); - ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new PowerTargetAdjuster(ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SchemaThief.java b/Mage.Sets/src/mage/cards/s/SchemaThief.java index e681ba6ede4..c439e1bb4d1 100644 --- a/Mage.Sets/src/mage/cards/s/SchemaThief.java +++ b/Mage.Sets/src/mage/cards/s/SchemaThief.java @@ -1,30 +1,28 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author TheElk801 + * @author notgreat */ public final class SchemaThief extends CardImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public SchemaThief(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); @@ -38,7 +36,10 @@ public final class SchemaThief extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever Schema Thief deals combat damage to a player, create a token that's a copy of target artifact that player controls. - this.addAbility(new SchemaThiefTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenCopyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private SchemaThief(final SchemaThief card) { @@ -51,44 +52,3 @@ public final class SchemaThief extends CardImpl { } } -class SchemaThiefTriggeredAbility extends TriggeredAbilityImpl { - - SchemaThiefTriggeredAbility() { - super(Zone.BATTLEFIELD, new CreateTokenCopyTargetEffect(), false); - } - - private SchemaThiefTriggeredAbility(final SchemaThiefTriggeredAbility ability) { - super(ability); - } - - @Override - public SchemaThiefTriggeredAbility copy() { - return new SchemaThiefTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent == null - || !event.getSourceId().equals(this.getSourceId()) - || !((DamagedEvent) event).isCombatDamage()) { - return false; - } - FilterPermanent filter = new FilterArtifactPermanent("artifact " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, create a token " + - "that's a copy of target artifact that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/ScionOfCalamity.java b/Mage.Sets/src/mage/cards/s/ScionOfCalamity.java index b3a5f6319bf..f22ce9b6086 100644 --- a/Mage.Sets/src/mage/cards/s/ScionOfCalamity.java +++ b/Mage.Sets/src/mage/cards/s/ScionOfCalamity.java @@ -1,29 +1,28 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.MyriadAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * @author arcox + * @author notgreat */ public final class ScionOfCalamity extends CardImpl { + private static final FilterArtifactOrEnchantmentPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment that player controls"); + public ScionOfCalamity(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); @@ -35,7 +34,10 @@ public final class ScionOfCalamity extends CardImpl { this.addAbility(new MyriadAbility(true)); // Whenever Scion of Calamity deals combat damage to a player, destroy target artifact or enchantment that player controls. - this.addAbility(new ScionOfCalamityTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private ScionOfCalamity(final ScionOfCalamity card) { @@ -48,48 +50,3 @@ public final class ScionOfCalamity extends CardImpl { } } -class ScionOfCalamityTriggeredAbility extends TriggeredAbilityImpl { - - ScionOfCalamityTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), false); - } - - private ScionOfCalamityTriggeredAbility(final ScionOfCalamityTriggeredAbility ability) { - super(ability); - } - - @Override - public ScionOfCalamityTriggeredAbility copy() { - return new ScionOfCalamityTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an artifact or enchantment controlled by " + player.getLogName()); - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.ENCHANTMENT.getPredicate())); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "destroy target artifact or enchantment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java b/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java index b0ee690c84b..7f6fb900001 100644 --- a/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java +++ b/Mage.Sets/src/mage/cards/s/ScionOfDarkness.java @@ -1,8 +1,8 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; import mage.abilities.keyword.CyclingAbility; @@ -11,21 +11,21 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.filter.common.FilterCreatureCard; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author jeffwadsworth + * @author notgreat */ public final class ScionOfDarkness extends CardImpl { + private static final FilterCard filter + = new FilterCreatureCard("creature card from that player's graveyard"); + public ScionOfDarkness(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}"); this.subtype.add(SubType.AVATAR); @@ -37,7 +37,10 @@ public final class ScionOfDarkness extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever Scion of Darkness deals combat damage to a player, you may put target creature card from that player's graveyard onto the battlefield under your control. - this.addAbility(new ScionOfDarknessTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true, true); + ability.addTarget(new TargetCardInGraveyard(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); // Cycling {3} this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{3}"))); @@ -52,49 +55,3 @@ public final class ScionOfDarkness extends CardImpl { return new ScionOfDarkness(this); } } - -class ScionOfDarknessTriggeredAbility extends TriggeredAbilityImpl { - - public ScionOfDarknessTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), true); - } - - private ScionOfDarknessTriggeredAbility(final ScionOfDarknessTriggeredAbility ability) { - super(ability); - } - - @Override - public ScionOfDarknessTriggeredAbility copy() { - return new ScionOfDarknessTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterCard("creature in " + damagedPlayer.getName() + "'s graveyard"); - filter.add(CardType.CREATURE.getPredicate()); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - TargetCardInGraveyard target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "you may put target creature card from that player's " - + "graveyard onto the battlefield under your control."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/ScrapWelder.java b/Mage.Sets/src/mage/cards/s/ScrapWelder.java index 04f2e313da2..8d19b814347 100644 --- a/Mage.Sets/src/mage/cards/s/ScrapWelder.java +++ b/Mage.Sets/src/mage/cards/s/ScrapWelder.java @@ -45,8 +45,8 @@ public final class ScrapWelder extends CardImpl { // {T}, Sacrifice an artifact with mana value X: Return target artifact card with mana value less than X from your graveyard to the battlefield. It gains haste until end of turn. Ability ability = new SimpleActivatedAbility(new ScrapWelderEffect(), new TapSourceCost()); ability.addCost(new ScrapWelderCost()); - ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.FEWER_THAN)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_FROM_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.FEWER_THAN)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SequenceEngine.java b/Mage.Sets/src/mage/cards/s/SequenceEngine.java index 269e46d4bfe..bc18b054552 100644 --- a/Mage.Sets/src/mage/cards/s/SequenceEngine.java +++ b/Mage.Sets/src/mage/cards/s/SequenceEngine.java @@ -34,8 +34,8 @@ public final class SequenceEngine extends CardImpl { ability.addEffect(FractalToken.getEffect( ManacostVariableValue.REGULAR, "Put X +1/+1 counters on it" )); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInGraveyard(StaticFilters.FILTER_CARD_CREATURE_A_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SereneSunset.java b/Mage.Sets/src/mage/cards/s/SereneSunset.java index afa74182672..1eb3310b711 100644 --- a/Mage.Sets/src/mage/cards/s/SereneSunset.java +++ b/Mage.Sets/src/mage/cards/s/SereneSunset.java @@ -21,8 +21,8 @@ public final class SereneSunset extends CardImpl { // Prevent all combat damage X target creatures would deal this turn. this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true) .setText("prevent all combat damage X target creatures would deal this turn")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private SereneSunset(final SereneSunset card) { diff --git a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java index 8fbb1f1b035..2e599343b55 100644 --- a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java +++ b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java @@ -27,8 +27,8 @@ public final class ShatteredCrypt extends CardImpl { effect.setText("Return X target creature cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(ManacostVariableValue.REGULAR)); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURES_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private ShatteredCrypt(final ShatteredCrypt card) { diff --git a/Mage.Sets/src/mage/cards/s/ShigekiJukaiVisionary.java b/Mage.Sets/src/mage/cards/s/ShigekiJukaiVisionary.java index 03fd83fce65..bc338b3f904 100644 --- a/Mage.Sets/src/mage/cards/s/ShigekiJukaiVisionary.java +++ b/Mage.Sets/src/mage/cards/s/ShigekiJukaiVisionary.java @@ -60,8 +60,8 @@ public final class ShigekiJukaiVisionary extends CardImpl { "{X}{X}{G}{G}", new ReturnFromGraveyardToHandTargetEffect() .setText("return X target nonlegendary cards from your graveyard to your hand") ); - ability2.setTargetAdjuster(new XTargetsCountAdjuster()); ability2.addTarget(new TargetCardInYourGraveyard(filter)); + ability2.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/s/Silkguard.java b/Mage.Sets/src/mage/cards/s/Silkguard.java index 3fe996c0fe6..7b8b9f5d4bb 100644 --- a/Mage.Sets/src/mage/cards/s/Silkguard.java +++ b/Mage.Sets/src/mage/cards/s/Silkguard.java @@ -43,8 +43,8 @@ public final class Silkguard extends CardImpl { // Put a +1/+1 counter on each of up to X target creatures you control. this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()) .setText("put a +1/+1 counter on each of up to X target creatures you control")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 1)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); // Auras, Equipment, and modified creatures you control gain hexproof until end of turn. this.getSpellAbility().addEffect(new GainAbilityControlledEffect( diff --git a/Mage.Sets/src/mage/cards/s/SkirkCommando.java b/Mage.Sets/src/mage/cards/s/SkirkCommando.java index 335dd0893e1..1dd7cbb1ddd 100644 --- a/Mage.Sets/src/mage/cards/s/SkirkCommando.java +++ b/Mage.Sets/src/mage/cards/s/SkirkCommando.java @@ -1,8 +1,8 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; +import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DamageTargetEffect; @@ -12,18 +12,19 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author BursegSardaukar + * @author notgreat */ public final class SkirkCommando extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public SkirkCommando(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.GOBLIN); @@ -32,7 +33,10 @@ public final class SkirkCommando extends CardImpl { this.toughness = new MageInt(1); //Whenever Skirk Commando deals combat damage to a player, you may have it deal 2 damage to target creature that player controls. - this.addAbility(new SkirkCommandoTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DamageTargetEffect(2), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); //Morph {2}{R} (You may cast this card face down as a 2/2 creature for 3. Turn it face up any time for its morph cost.) this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{2}{R}"))); @@ -48,39 +52,3 @@ public final class SkirkCommando extends CardImpl { return new SkirkCommando(this); } } - -class SkirkCommandoTriggeredAbility extends DealsCombatDamageToAPlayerTriggeredAbility { - - public SkirkCommandoTriggeredAbility() { - super(new DamageTargetEffect(2), true, false); - } - - private SkirkCommandoTriggeredAbility(final SkirkCommandoTriggeredAbility ability) { - super(ability); - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (super.checkTrigger(event, game)) { - Player player = game.getPlayer(event.getPlayerId()); - if (player != null) { - getTargets().clear(); - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player " + player.getName() + " controls"); - filter.add(new ControllerIdPredicate(event.getPlayerId())); - addTarget(new TargetCreaturePermanent(filter)); - return true; - } - } - return false; - } - - @Override - public SkirkCommandoTriggeredAbility copy() { - return new SkirkCommandoTriggeredAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may have it deal 2 damage to target creature that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/Skullsnatcher.java b/Mage.Sets/src/mage/cards/s/Skullsnatcher.java index 592d4d15613..8a9a5332f67 100644 --- a/Mage.Sets/src/mage/cards/s/Skullsnatcher.java +++ b/Mage.Sets/src/mage/cards/s/Skullsnatcher.java @@ -1,10 +1,9 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.NinjutsuAbility; @@ -15,19 +14,18 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.card.OwnerIdPredicate; import mage.filter.predicate.permanent.UnblockedPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.target.common.TargetCardInOpponentsGraveyard; +import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author notgreat */ public final class Skullsnatcher extends CardImpl { + private static final FilterCard filterGraveyardCard = new FilterCard("cards from that player's graveyard"); private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("unblocked attacker you control"); static { @@ -44,11 +42,13 @@ public final class Skullsnatcher extends CardImpl { // Ninjutsu {B} ({B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.) this.addAbility(new NinjutsuAbility("{B}")); - + // Whenever Skullsnatcher deals combat damage to a player, exile up to two target cards from that player's graveyard. Effect effect = new ExileTargetEffect(null, "", Zone.GRAVEYARD); - effect.setText("exile up to two target cards from that player's graveyard"); - this.addAbility(new SkullsnatcherTriggeredAbility(effect)); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetCardInGraveyard(0, 2, filterGraveyardCard)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); } private Skullsnatcher(final Skullsnatcher card) { @@ -60,40 +60,3 @@ public final class Skullsnatcher extends CardImpl { return new Skullsnatcher(this); } } - -class SkullsnatcherTriggeredAbility extends TriggeredAbilityImpl { - - SkullsnatcherTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect, false); - setTriggerPhrase("Whenever {this} deals combat damage to a player, "); - } - - private SkullsnatcherTriggeredAbility(final SkullsnatcherTriggeredAbility ability) { - super(ability); - } - - @Override - public SkullsnatcherTriggeredAbility copy() { - return new SkullsnatcherTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (((DamagedPlayerEvent) event).isCombatDamage() - && event.getSourceId().equals(sourceId)) { - - FilterCard filter = new FilterCard("up to two target cards from that player's graveyard"); - filter.add(new OwnerIdPredicate(event.getPlayerId())); - filter.setMessage("up to two cards in " + game.getPlayer(event.getTargetId()).getLogName() + "'s graveyard"); - this.getTargets().clear(); - this.addTarget(new TargetCardInOpponentsGraveyard(0,2,filter)); - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SmokeSpiritsAid.java b/Mage.Sets/src/mage/cards/s/SmokeSpiritsAid.java index 499a7094ba4..56a840363e5 100644 --- a/Mage.Sets/src/mage/cards/s/SmokeSpiritsAid.java +++ b/Mage.Sets/src/mage/cards/s/SmokeSpiritsAid.java @@ -23,8 +23,8 @@ public final class SmokeSpiritsAid extends CardImpl { // For each of up to X target creatures, create a red Aura enchantment token named Smoke Blessing attached to that creature. Those tokens have enchant creature and "When enchanted creature dies, it deals 1 damage to its controller and you create a Treasure token." this.getSpellAbility().addEffect(new SmokeSpiritsAidEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 1)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private SmokeSpiritsAid(final SmokeSpiritsAid card) { diff --git a/Mage.Sets/src/mage/cards/s/SnappingThragg.java b/Mage.Sets/src/mage/cards/s/SnappingThragg.java index 5809d6322e7..e5849354032 100644 --- a/Mage.Sets/src/mage/cards/s/SnappingThragg.java +++ b/Mage.Sets/src/mage/cards/s/SnappingThragg.java @@ -1,30 +1,30 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; -import mage.constants.SubType; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.MorphAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Zone; +import mage.constants.SubType; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author TheElk801 + * @author notgreat */ public final class SnappingThragg extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public SnappingThragg(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); @@ -33,7 +33,10 @@ public final class SnappingThragg extends CardImpl { this.toughness = new MageInt(3); // Whenever Snapping Thragg deals combat damage to a player, you may have it deal 3 damage to target creature that player controls. - this.addAbility(new SnappingThraggTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DamageTargetEffect(3), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); // Morph {4}{R}{R} this.addAbility(new MorphAbility(this, new ManaCostsImpl<>("{4}{R}{R}"))); @@ -49,43 +52,3 @@ public final class SnappingThragg extends CardImpl { return new SnappingThragg(this); } } - -class SnappingThraggTriggeredAbility extends TriggeredAbilityImpl { - - public SnappingThraggTriggeredAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(3), true); - this.addTarget(new TargetCreaturePermanent()); - } - - private SnappingThraggTriggeredAbility(final SnappingThraggTriggeredAbility ability) { - super(ability); - } - - @Override - public SnappingThraggTriggeredAbility copy() { - return new SnappingThraggTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null && event.getSourceId().equals(this.sourceId)) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCreaturePermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may have it deal 3 damage to target creature that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SontaranGeneral.java b/Mage.Sets/src/mage/cards/s/SontaranGeneral.java index 58118c655d1..eb245b63b46 100644 --- a/Mage.Sets/src/mage/cards/s/SontaranGeneral.java +++ b/Mage.Sets/src/mage/cards/s/SontaranGeneral.java @@ -42,8 +42,8 @@ public final class SontaranGeneral extends CardImpl { .setText("for each opponent, goad up to one target creature that player controls.")); ability.addEffect(new CantBlockTargetEffect(Duration.EndOfTurn) .setText("Those creatures can't block this turn.")); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SorinVengefulBloodlord.java b/Mage.Sets/src/mage/cards/s/SorinVengefulBloodlord.java index eb40f97759f..010b3c39b77 100644 --- a/Mage.Sets/src/mage/cards/s/SorinVengefulBloodlord.java +++ b/Mage.Sets/src/mage/cards/s/SorinVengefulBloodlord.java @@ -54,8 +54,8 @@ public final class SorinVengefulBloodlord extends CardImpl { "Return target creature card with mana value X from your graveyard to the battlefield" )); ability.addEffect(new SorinVengefulBloodlordEffect()); - ability.setTargetAdjuster(new XManaValueTargetAdjuster()); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + ability.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SparkMage.java b/Mage.Sets/src/mage/cards/s/SparkMage.java index 49254a81f3d..e13fb79ac60 100644 --- a/Mage.Sets/src/mage/cards/s/SparkMage.java +++ b/Mage.Sets/src/mage/cards/s/SparkMage.java @@ -1,32 +1,30 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; -import mage.target.common.TargetCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author cbt33, Loki (Ashling the Extinguisher) + * @author notgreat */ public final class SparkMage extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature that player controls"); + public SparkMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); this.subtype.add(SubType.DWARF); this.subtype.add(SubType.WIZARD); @@ -34,7 +32,10 @@ public final class SparkMage extends CardImpl { this.toughness = new MageInt(1); // Whenever Spark Mage deals combat damage to a player, you may have Spark Mage deal 1 damage to target creature that player controls. - this.addAbility(new SparkMageTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DamageTargetEffect(1, "it"), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private SparkMage(final SparkMage card) { @@ -46,47 +47,3 @@ public final class SparkMage extends CardImpl { return new SparkMage(this); } } - -class SparkMageTriggeredAbility extends TriggeredAbilityImpl { - - public SparkMageTriggeredAbility() { - super(Zone.BATTLEFIELD, new DamageTargetEffect(1)); - this.addTarget(new TargetCreaturePermanent()); - } - - private SparkMageTriggeredAbility(final SparkMageTriggeredAbility ability) { - super(ability); - } - - @Override - public SparkMageTriggeredAbility copy() { - return new SparkMageTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null) { - FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.getTargets().add(new TargetCreaturePermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may have {this} deal 1 damage to target creature that player controls."; - } - -} diff --git a/Mage.Sets/src/mage/cards/s/SpellBlast.java b/Mage.Sets/src/mage/cards/s/SpellBlast.java index 05ac82f08e6..4d558826709 100644 --- a/Mage.Sets/src/mage/cards/s/SpellBlast.java +++ b/Mage.Sets/src/mage/cards/s/SpellBlast.java @@ -20,8 +20,8 @@ public final class SpellBlast extends CardImpl { // Counter target spell with converted mana cost X. this.getSpellAbility().addEffect(new CounterTargetEffect().setText("counter target spell with mana value X")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private SpellBlast(final SpellBlast card) { diff --git a/Mage.Sets/src/mage/cards/s/SpellBurst.java b/Mage.Sets/src/mage/cards/s/SpellBurst.java index ab5e2200461..9d36f10c0fe 100644 --- a/Mage.Sets/src/mage/cards/s/SpellBurst.java +++ b/Mage.Sets/src/mage/cards/s/SpellBurst.java @@ -24,8 +24,8 @@ public final class SpellBurst extends CardImpl { // Counter target spell with converted mana cost X. this.getSpellAbility().addEffect(new CounterTargetEffect().setText("counter target spell with mana value X")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetSpell()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private SpellBurst(final SpellBurst card) { diff --git a/Mage.Sets/src/mage/cards/s/StirTheGrave.java b/Mage.Sets/src/mage/cards/s/StirTheGrave.java index d5ba1bc299d..8ad37d0058f 100644 --- a/Mage.Sets/src/mage/cards/s/StirTheGrave.java +++ b/Mage.Sets/src/mage/cards/s/StirTheGrave.java @@ -22,8 +22,8 @@ public final class StirTheGrave extends CardImpl { // Return target creature card with converted mana cost X or less from your graveyard to the battlefield. this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect().setText("return target creature card with mana value X or less from your graveyard to the battlefield")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); } private StirTheGrave(final StirTheGrave card) { diff --git a/Mage.Sets/src/mage/cards/s/StolenByTheFae.java b/Mage.Sets/src/mage/cards/s/StolenByTheFae.java index 8584dbb5a17..7d533d2bd6f 100644 --- a/Mage.Sets/src/mage/cards/s/StolenByTheFae.java +++ b/Mage.Sets/src/mage/cards/s/StolenByTheFae.java @@ -25,8 +25,8 @@ public final class StolenByTheFae extends CardImpl { .setText("Return target creature with mana value X to its owner's hand")); this.getSpellAbility().addEffect(new CreateTokenEffect(new FaerieToken(), ManacostVariableValue.REGULAR) .setText("You create X 1/1 blue Faerie creature tokens with flying")); - this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XManaValueTargetAdjuster()); } private StolenByTheFae(final StolenByTheFae card) { diff --git a/Mage.Sets/src/mage/cards/s/SunderShaman.java b/Mage.Sets/src/mage/cards/s/SunderShaman.java index 79f4d679a1f..6921a07b61d 100644 --- a/Mage.Sets/src/mage/cards/s/SunderShaman.java +++ b/Mage.Sets/src/mage/cards/s/SunderShaman.java @@ -1,8 +1,8 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect; @@ -10,21 +10,20 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * @author TheElk801 + * @author notgreat */ public final class SunderShaman extends CardImpl { + private static final FilterArtifactOrEnchantmentPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment that player controls"); + public SunderShaman(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{R}{G}{G}"); @@ -37,7 +36,10 @@ public final class SunderShaman extends CardImpl { this.addAbility(new SimpleStaticAbility(new CantBeBlockedByMoreThanOneSourceEffect())); // Whenever Sunder Shaman deals combat damage to a player, destroy target artifact or enchantment that player controls. - this.addAbility(new SunderShamanTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private SunderShaman(final SunderShaman card) { @@ -49,49 +51,3 @@ public final class SunderShaman extends CardImpl { return new SunderShaman(this); } } - -class SunderShamanTriggeredAbility extends TriggeredAbilityImpl { - - SunderShamanTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), false); - } - - private SunderShamanTriggeredAbility(final SunderShamanTriggeredAbility ability) { - super(ability); - } - - @Override - public SunderShamanTriggeredAbility copy() { - return new SunderShamanTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an artifact or enchantment controlled by " + player.getLogName()); - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.ENCHANTMENT.getPredicate())); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "destroy target artifact or enchantment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java b/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java index 6e60cd54e5a..a827ad49a06 100644 --- a/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java +++ b/Mage.Sets/src/mage/cards/s/SupremeLeaderSnoke.java @@ -59,8 +59,8 @@ public final class SupremeLeaderSnoke extends CardImpl { ability3.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield).setText("It gains haste")); ability3.addEffect(new GainAbilityTargetEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()), Duration.WhileOnBattlefield) .setText("Sacrifice that creature at the beginning of the next end step")); - ability3.setTargetAdjuster(new XManaValueTargetAdjuster()); ability3.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE)); + ability3.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability3); } diff --git a/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java b/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java index c98b46e25bb..3161b61e39c 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java +++ b/Mage.Sets/src/mage/cards/s/SylvanPrimordial.java @@ -46,8 +46,8 @@ public final class SylvanPrimordial extends CardImpl { // When Sylvan Primordial enters the battlefield, for each opponent, destroy target noncreature permanent that player controls. For each permanent destroyed this way, search your library for a Forest card and put that card onto the battlefield tapped. Then shuffle your library. Ability ability = new EntersBattlefieldTriggeredAbility(new SylvanPrimordialEffect(), false); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SynodArtificer.java b/Mage.Sets/src/mage/cards/s/SynodArtificer.java index 86adc35729d..a73a1a1b414 100644 --- a/Mage.Sets/src/mage/cards/s/SynodArtificer.java +++ b/Mage.Sets/src/mage/cards/s/SynodArtificer.java @@ -45,8 +45,8 @@ public final class SynodArtificer extends CardImpl { tapEffect.setText("Tap X target noncreature artifacts."); Ability tapAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, tapEffect, new ManaCostsImpl<>("{X}")); tapAbility.addCost(new TapSourceCost()); - tapAbility.setTargetAdjuster(new XTargetsCountAdjuster()); tapAbility.addTarget(new TargetPermanent(filter)); + tapAbility.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(tapAbility); // {X}, {tap}: Untap X target noncreature artifacts. @@ -54,8 +54,8 @@ public final class SynodArtificer extends CardImpl { untapEffect.setText("Untap X target noncreature artifacts."); Ability untapAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, untapEffect, new ManaCostsImpl<>("{X}")); untapAbility.addCost(new TapSourceCost()); - untapAbility.setTargetAdjuster(new XTargetsCountAdjuster()); untapAbility.addTarget(new TargetPermanent(filter)); + untapAbility.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(untapAbility); } diff --git a/Mage.Sets/src/mage/cards/t/TameshiRealityArchitect.java b/Mage.Sets/src/mage/cards/t/TameshiRealityArchitect.java index 6ac1c25bc9e..c7f6e50133d 100644 --- a/Mage.Sets/src/mage/cards/t/TameshiRealityArchitect.java +++ b/Mage.Sets/src/mage/cards/t/TameshiRealityArchitect.java @@ -56,8 +56,8 @@ public final class TameshiRealityArchitect extends CardImpl { ability.addCost(new ReturnToHandChosenControlledPermanentCost( new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND) )); - ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetCardInYourGraveyard(new FilterArtifactOrEnchantmentCard())); + ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TamiyoCompleatedSage.java b/Mage.Sets/src/mage/cards/t/TamiyoCompleatedSage.java index 0f54ce2ab1e..701c6f0c230 100644 --- a/Mage.Sets/src/mage/cards/t/TamiyoCompleatedSage.java +++ b/Mage.Sets/src/mage/cards/t/TamiyoCompleatedSage.java @@ -57,8 +57,8 @@ public final class TamiyoCompleatedSage extends CardImpl { // −X: Exile target nonland permanent card with mana value X from your graveyard. Create a token that's a copy of that card. Ability ability2 = new LoyaltyAbility(new TamiyoCompleatedSageEffect()); - ability2.setTargetAdjuster(new XManaValueTargetAdjuster()); ability2.addTarget(new TargetCardInYourGraveyard(filter)); + ability2.setTargetAdjuster(new XManaValueTargetAdjuster()); this.addAbility(ability2); // −7: Create Tamiyo's Notebook, a legendary colorless artifact token with "Spells you cast cost {2} less to cast" and "{T}: Draw a card." diff --git a/Mage.Sets/src/mage/cards/t/TemporalFirestorm.java b/Mage.Sets/src/mage/cards/t/TemporalFirestorm.java index c91b2727a3f..ac5d7f964e6 100644 --- a/Mage.Sets/src/mage/cards/t/TemporalFirestorm.java +++ b/Mage.Sets/src/mage/cards/t/TemporalFirestorm.java @@ -37,8 +37,8 @@ public final class TemporalFirestorm extends CardImpl { // Choose up to X creatures and/or planeswalkers you control, where X is the number of times this spell was kicked. Those permanents phase out. this.getSpellAbility().addEffect(new PhaseOutTargetEffect().setText("choose up to X creatures and/or " + "planeswalkers you control, where X is the number of times this spell was kicked. Those permanents phase out")); - this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter, true)); + this.getSpellAbility().setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); // Temporal Firestorm deals 5 damage to each creature and each planeswalker. this.getSpellAbility().addEffect(new DamageAllEffect( diff --git a/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java b/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java index e9b46964d57..5beed5e7eb5 100644 --- a/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java +++ b/Mage.Sets/src/mage/cards/t/TemptedByTheOriq.java @@ -31,8 +31,8 @@ public final class TemptedByTheOriq extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, gain control of up to one target creature " + "or planeswalker that player controls with mana value 3 or less")); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private TemptedByTheOriq(final TemptedByTheOriq card) { diff --git a/Mage.Sets/src/mage/cards/t/TheBalrogOfMoria.java b/Mage.Sets/src/mage/cards/t/TheBalrogOfMoria.java index 6260877a7e6..8a70505c8ef 100644 --- a/Mage.Sets/src/mage/cards/t/TheBalrogOfMoria.java +++ b/Mage.Sets/src/mage/cards/t/TheBalrogOfMoria.java @@ -51,8 +51,8 @@ public final class TheBalrogOfMoria extends CardImpl { .setText("for each opponent, exile up to one target creature that player controls."), false ); - reflexiveAbility.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); reflexiveAbility.addTarget(new TargetCreaturePermanent(0,1)); + reflexiveAbility.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(new DiesSourceTriggeredAbility( new DoWhenCostPaid( diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java index 66a4d251f2d..26c265dabe9 100644 --- a/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java +++ b/Mage.Sets/src/mage/cards/t/TheBattleOfNaboo.java @@ -29,8 +29,8 @@ public final class TheBattleOfNaboo extends CardImpl { effect.setText("Return X target creatures to their owner's hands"); this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new TheBattleOfNabooEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private TheBattleOfNaboo(final TheBattleOfNaboo card) { diff --git a/Mage.Sets/src/mage/cards/t/TheHorusHeresy.java b/Mage.Sets/src/mage/cards/t/TheHorusHeresy.java index 25a095df240..757e0711fff 100644 --- a/Mage.Sets/src/mage/cards/t/TheHorusHeresy.java +++ b/Mage.Sets/src/mage/cards/t/TheHorusHeresy.java @@ -57,8 +57,8 @@ public final class TheHorusHeresy extends CardImpl { // I -- For each opponent, gain control of up to one target nonlegendary creature that player controls for as long as The Horus Heresy remains on the battlefield. sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, ability -> { ability.addEffect(new TheHorusHeresyControlEffect()); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetPermanent(0, 1, filterNonlegendary)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); }); // II -- Draw a card for each creature you control but don't own. diff --git a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java b/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java index bdcc3f39766..44ab5956a2c 100644 --- a/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java +++ b/Mage.Sets/src/mage/cards/t/TheTrueScriptures.java @@ -46,8 +46,8 @@ public final class TheTrueScriptures extends CardImpl { ability -> { ability.addEffect(new DestroyTargetEffect().setTargetPointer(new EachTargetPointer()) .setText("for each opponent, destroy up to one target creature or planeswalker that player controls")); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetCreatureOrPlaneswalker(0,1)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } ); diff --git a/Mage.Sets/src/mage/cards/t/ThievingSkydiver.java b/Mage.Sets/src/mage/cards/t/ThievingSkydiver.java index 329d4511b01..defeac76ce7 100644 --- a/Mage.Sets/src/mage/cards/t/ThievingSkydiver.java +++ b/Mage.Sets/src/mage/cards/t/ThievingSkydiver.java @@ -51,8 +51,8 @@ public final class ThievingSkydiver extends CardImpl { "If that artifact is an Equipment, attach it to {this}." ); ability.addEffect(new ThievingSkydiverEffect()); - ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); ability.addTarget(new TargetArtifactPermanent()); + ability.setTargetAdjuster(new XManaValueTargetAdjuster(ComparisonType.OR_LESS)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/Thrive.java b/Mage.Sets/src/mage/cards/t/Thrive.java index bee5cf6044c..b0d449acc3e 100644 --- a/Mage.Sets/src/mage/cards/t/Thrive.java +++ b/Mage.Sets/src/mage/cards/t/Thrive.java @@ -24,8 +24,8 @@ public final class Thrive extends CardImpl { Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setText("Put a +1/+1 counter on each of X target creatures"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private Thrive(final Thrive card) { diff --git a/Mage.Sets/src/mage/cards/t/ThroatSlitter.java b/Mage.Sets/src/mage/cards/t/ThroatSlitter.java index aad4084d2ce..f887b058182 100644 --- a/Mage.Sets/src/mage/cards/t/ThroatSlitter.java +++ b/Mage.Sets/src/mage/cards/t/ThroatSlitter.java @@ -1,36 +1,38 @@ package mage.cards.t; -import java.util.UUID; import mage.MageInt; import mage.ObjectColor; -import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.NinjutsuAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author notgreat */ public final class ThroatSlitter extends CardImpl { + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("nonblack creature that player controls"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + public ThroatSlitter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}"); this.subtype.add(SubType.RAT); this.subtype.add(SubType.NINJA); @@ -41,7 +43,10 @@ public final class ThroatSlitter extends CardImpl { this.addAbility(new NinjutsuAbility("{2}{B}")); // Whenever Throat Slitter deals combat damage to a player, destroy target nonblack creature that player controls. - this.addAbility(new ThroatSlitterTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private ThroatSlitter(final ThroatSlitter card) { @@ -53,45 +58,3 @@ public final class ThroatSlitter extends CardImpl { return new ThroatSlitter(this); } } - -class ThroatSlitterTriggeredAbility extends TriggeredAbilityImpl { - - ThroatSlitterTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), false); - } - - private ThroatSlitterTriggeredAbility(final ThroatSlitterTriggeredAbility ability) { - super(ability); - } - - @Override - public ThroatSlitterTriggeredAbility copy() { - return new ThroatSlitterTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (((DamagedPlayerEvent) event).isCombatDamage() - && event.getSourceId().equals(sourceId)) { - - FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature that player controls"); - filter.add(new ControllerIdPredicate(event.getPlayerId())); - filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); - filter.setMessage("nonblack creature controlled by " + game.getPlayer(event.getTargetId()).getLogName()); - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, destroy target nonblack creature that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TimeReaper.java b/Mage.Sets/src/mage/cards/t/TimeReaper.java new file mode 100644 index 00000000000..7cf745398b7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TimeReaper.java @@ -0,0 +1,65 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.PutOnLibraryTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.card.FaceDownPredicate; +import mage.target.common.TargetCardInExile; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class TimeReaper extends CardImpl { + + private static final FilterCard filter = new FilterCard("face-up exiled card"); + + static { + filter.add(Predicates.not(FaceDownPredicate.instance)); + } + + public TimeReaper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + + this.subtype.add(SubType.ALIEN); + this.subtype.add(SubType.HORROR); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Consume Anomaly -- Whenever Time Reaper deals combat damage to a player, put target face-up card they own in exile on the bottom of their library. If you do, you gain 3 life. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new PutOnLibraryTargetEffect(false), false, true); + ability.addEffect(new GainLifeEffect(3)); //I don't think the move can fail? If there's no target then the trigger won't happen + ability.addTarget(new TargetCardInExile(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + ability.withFlavorWord("Consume Anomaly"); + this.addAbility(ability); + } + + private TimeReaper(final TimeReaper card) { + super(card); + } + + @Override + public TimeReaper copy() { + return new TimeReaper(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TinybonesThePickpocket.java b/Mage.Sets/src/mage/cards/t/TinybonesThePickpocket.java index 735802e6a5c..3a48422bda3 100644 --- a/Mage.Sets/src/mage/cards/t/TinybonesThePickpocket.java +++ b/Mage.Sets/src/mage/cards/t/TinybonesThePickpocket.java @@ -1,30 +1,37 @@ package mage.cards.t; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MayCastTargetCardEffect; import mage.abilities.keyword.DeathtouchAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.CastManaAdjustment; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.common.FilterPermanentCard; import mage.filter.predicate.Predicates; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.Target; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author Susucr + * @author notgreat */ public final class TinybonesThePickpocket extends CardImpl { + private static final FilterCard filter + = new FilterPermanentCard("nonland permanent card from that player's graveyard"); + + static { + filter.add(Predicates.not(CardType.LAND.getPredicate())); + } + public TinybonesThePickpocket(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); @@ -38,7 +45,11 @@ public final class TinybonesThePickpocket extends CardImpl { this.addAbility(DeathtouchAbility.getInstance()); // Whenever Tinybones, the Pickpocket deals combat damage to a player, you may cast target nonland permanent card from that player's graveyard, and mana of any type can be spent to cast that spell. - this.addAbility(new TinybonesThePickpocketTriggeredAbility()); + OneShotEffect effect = new MayCastTargetCardEffect(CastManaAdjustment.AS_THOUGH_ANY_MANA_TYPE, false); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetCardInGraveyard(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); } private TinybonesThePickpocket(final TinybonesThePickpocket card) { @@ -50,52 +61,3 @@ public final class TinybonesThePickpocket extends CardImpl { return new TinybonesThePickpocket(this); } } - -/** - * Similar to {@link mage.cards.w.WrexialTheRisenDeep} - */ -class TinybonesThePickpocketTriggeredAbility extends TriggeredAbilityImpl { - - TinybonesThePickpocketTriggeredAbility() { - super( - Zone.BATTLEFIELD, - new MayCastTargetCardEffect(CastManaAdjustment.AS_THOUGH_ANY_MANA_TYPE, false) - .setText("you may cast target nonland permanent card from " - + "that player's graveyard, and mana of any type can be spent to cast that spell"), - false - ); - setTriggerPhrase("Whenever {this} deals combat damage to a player, "); - } - - private TinybonesThePickpocketTriggeredAbility(final TinybonesThePickpocketTriggeredAbility ability) { - super(ability); - } - - @Override - public TinybonesThePickpocketTriggeredAbility copy() { - return new TinybonesThePickpocketTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterPermanentCard("nonland permanent card from " + damagedPlayer.getName() + "'s graveyard"); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - filter.add(Predicates.not(CardType.LAND.getPredicate())); - Target target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TolarianContempt.java b/Mage.Sets/src/mage/cards/t/TolarianContempt.java index 9ea4c4cab77..091ff026d9e 100644 --- a/Mage.Sets/src/mage/cards/t/TolarianContempt.java +++ b/Mage.Sets/src/mage/cards/t/TolarianContempt.java @@ -47,8 +47,8 @@ public final class TolarianContempt extends CardImpl { // At the beginning of your end step, for each opponent, choose up to one target creature they control with a rejection counter on it. That creature's owner puts it on the top or bottom of their library. Ability ability = new BeginningOfEndStepTriggeredAbility(new TolarianContemptEffect(), TargetController.YOU, false); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetPermanent(0,1, filterRejection)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TrygonPredator.java b/Mage.Sets/src/mage/cards/t/TrygonPredator.java index 9f17afbfcc8..c3d22b61ee4 100644 --- a/Mage.Sets/src/mage/cards/t/TrygonPredator.java +++ b/Mage.Sets/src/mage/cards/t/TrygonPredator.java @@ -1,34 +1,31 @@ package mage.cards.t; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.players.Player; +import mage.filter.common.FilterArtifactOrEnchantmentPermanent; import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** - * - * @author LevelX2 + * @author notgreat */ public final class TrygonPredator extends CardImpl { + private static final FilterArtifactOrEnchantmentPermanent filter + = new FilterArtifactOrEnchantmentPermanent("artifact or enchantment that player controls"); + public TrygonPredator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}"); this.subtype.add(SubType.BEAST); this.power = new MageInt(2); @@ -37,7 +34,10 @@ public final class TrygonPredator extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Whenever Trygon Predator deals combat damage to a player, you may destroy target artifact or enchantment that player controls. - this.addAbility(new TrygonPredatorTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DestroyTargetEffect(), true, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + this.addAbility(ability); } private TrygonPredator(final TrygonPredator card) { @@ -49,48 +49,3 @@ public final class TrygonPredator extends CardImpl { return new TrygonPredator(this); } } - -class TrygonPredatorTriggeredAbility extends TriggeredAbilityImpl { - - public TrygonPredatorTriggeredAbility() { - super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true); - } - - private TrygonPredatorTriggeredAbility(final TrygonPredatorTriggeredAbility ability) { - super(ability); - } - - @Override - public TrygonPredatorTriggeredAbility copy() { - return new TrygonPredatorTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.sourceId) && ((DamagedPlayerEvent) event).isCombatDamage()) { - Player player = game.getPlayer(event.getTargetId()); - if (player != null) { - FilterPermanent filter = new FilterPermanent("an artifact or enchantment controlled by " + player.getLogName()); - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.ENCHANTMENT.getPredicate())); - filter.add(new ControllerIdPredicate(event.getTargetId())); - - this.getTargets().clear(); - this.addTarget(new TargetPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may destroy target artifact or enchantment that player controls."; - } -} diff --git a/Mage.Sets/src/mage/cards/t/TurbulentDreams.java b/Mage.Sets/src/mage/cards/t/TurbulentDreams.java index df1d4de6f10..eaf810befd6 100644 --- a/Mage.Sets/src/mage/cards/t/TurbulentDreams.java +++ b/Mage.Sets/src/mage/cards/t/TurbulentDreams.java @@ -27,8 +27,8 @@ public final class TurbulentDreams extends CardImpl { Effect effect = new ReturnToHandTargetEffect(); effect.setText("Return X target nonland permanents to their owners' hands"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetNonlandPermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private TurbulentDreams(final TurbulentDreams card) { diff --git a/Mage.Sets/src/mage/cards/v/VengefulDreams.java b/Mage.Sets/src/mage/cards/v/VengefulDreams.java index 0082e66b608..a1d4a4c2363 100644 --- a/Mage.Sets/src/mage/cards/v/VengefulDreams.java +++ b/Mage.Sets/src/mage/cards/v/VengefulDreams.java @@ -28,8 +28,8 @@ public final class VengefulDreams extends CardImpl { Effect effect = new ExileTargetEffect(); effect.setText("Exile X target attacking creatures"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_ATTACKING_CREATURES)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private VengefulDreams(final VengefulDreams card) { diff --git a/Mage.Sets/src/mage/cards/v/VitalityHunter.java b/Mage.Sets/src/mage/cards/v/VitalityHunter.java index 3c97b91f27d..13633f11dba 100644 --- a/Mage.Sets/src/mage/cards/v/VitalityHunter.java +++ b/Mage.Sets/src/mage/cards/v/VitalityHunter.java @@ -40,8 +40,8 @@ public final class VitalityHunter extends CardImpl { new AddCountersTargetEffect(CounterType.LIFELINK.createInstance()) .setText("put a lifelink counter on each of up to X target creatures") ); - ability.setTargetAdjuster(new TargetsCountAdjuster(GetMonstrosityXValue.instance)); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new TargetsCountAdjuster(GetMonstrosityXValue.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VolcanicEruption.java b/Mage.Sets/src/mage/cards/v/VolcanicEruption.java index bcf35b44949..6b84d3b68e8 100644 --- a/Mage.Sets/src/mage/cards/v/VolcanicEruption.java +++ b/Mage.Sets/src/mage/cards/v/VolcanicEruption.java @@ -31,8 +31,8 @@ public final class VolcanicEruption extends CardImpl { // Destroy X target Mountains. Volcanic Eruption deals damage to each creature and each player equal to the number of Mountains put into a graveyard this way. this.getSpellAbility().addEffect(new VolcanicEruptionEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetLandPermanent(filter)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private VolcanicEruption(final VolcanicEruption card) { diff --git a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java index 94532a7c9c0..64d2a602871 100644 --- a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java +++ b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java @@ -43,8 +43,8 @@ public final class VoyagerDrake extends CardImpl { ).setText("up to X target creatures gain flying until end of turn, " + "where X is the number of times {this} was kicked.") ); - ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); ability.addTarget(new TargetCreaturePermanent(0, 1)); + ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VronosMaskedInquisitor.java b/Mage.Sets/src/mage/cards/v/VronosMaskedInquisitor.java index 33878eda595..ffdfca7bf68 100644 --- a/Mage.Sets/src/mage/cards/v/VronosMaskedInquisitor.java +++ b/Mage.Sets/src/mage/cards/v/VronosMaskedInquisitor.java @@ -56,8 +56,8 @@ public final class VronosMaskedInquisitor extends CardImpl { // −2: For each opponent, return up to one target nonland permanent that player controls to its owner's hand. LoyaltyAbility ability2 = new LoyaltyAbility(new ReturnToHandTargetEffect().setTargetPointer(new EachTargetPointer()) .setText("for each opponent, return up to one target nonland permanent that player controls to its owner's hand"), -2); - ability2.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability2.addTarget(new TargetNonlandPermanent(0,1)); + ability2.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.addAbility(ability2); // −7: Target artifact you control becomes a 9/9 Construct artifact creature and gains vigilance, indestructible, and "This creature can't be blocked." diff --git a/Mage.Sets/src/mage/cards/w/WakeTheDead.java b/Mage.Sets/src/mage/cards/w/WakeTheDead.java index 433d928ddc5..4cd41314906 100644 --- a/Mage.Sets/src/mage/cards/w/WakeTheDead.java +++ b/Mage.Sets/src/mage/cards/w/WakeTheDead.java @@ -42,8 +42,8 @@ public final class WakeTheDead extends CardImpl { // Return X target creature cards from your graveyard to the battlefield. Sacrifice those creatures at the beginning of the next end step. this.getSpellAbility().addEffect(new WakeTheDeadReturnFromGraveyardToBattlefieldTargetEffect()); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private WakeTheDead(final WakeTheDead card) { diff --git a/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java b/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java index 32f3bf9f0d6..bc917b1bf03 100644 --- a/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java +++ b/Mage.Sets/src/mage/cards/w/WaveOfIndifference.java @@ -24,8 +24,8 @@ public final class WaveOfIndifference extends CardImpl { Effect effect = new CantBlockTargetEffect(Duration.EndOfTurn); effect.setText("X target creatures can't block this turn"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private WaveOfIndifference(final WaveOfIndifference card) { diff --git a/Mage.Sets/src/mage/cards/w/WaxmaneBaku.java b/Mage.Sets/src/mage/cards/w/WaxmaneBaku.java index b1e995181bc..a1b9525baf1 100644 --- a/Mage.Sets/src/mage/cards/w/WaxmaneBaku.java +++ b/Mage.Sets/src/mage/cards/w/WaxmaneBaku.java @@ -38,8 +38,8 @@ public final class WaxmaneBaku extends CardImpl { // {1}, Remove X ki counters from Waxmane Baku: Tap X target creatures. Ability ability = new SimpleActivatedAbility(new TapTargetEffect("tap X target creatures"), new GenericManaCost(1)); ability.addCost(new RemoveVariableCountersSourceCost(CounterType.KI)); - ability.setTargetAdjuster(new XTargetsCountAdjuster()); ability.addTarget(new TargetCreaturePermanent()); + ability.setTargetAdjuster(new XTargetsCountAdjuster()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WelcomeTo.java b/Mage.Sets/src/mage/cards/w/WelcomeTo.java index fbf900f99c2..f34639a8f4d 100644 --- a/Mage.Sets/src/mage/cards/w/WelcomeTo.java +++ b/Mage.Sets/src/mage/cards/w/WelcomeTo.java @@ -63,8 +63,8 @@ public final class WelcomeTo extends CardImpl { ).setText("For each opponent, up to one target noncreature artifact they control becomes " + "a 0/4 Wall artifact creature with defender for as long as you control this Saga.")); ability.getEffects().setTargetPointer(new EachTargetPointer()); - ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); ability.addTarget(new TargetPermanent(0, 1, filterNoncreatureArtifact)); + ability.setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); }); // II -- Create a 3/3 green Dinosaur creature token with trample. It gains haste until end of turn. diff --git a/Mage.Sets/src/mage/cards/w/WildestDreams.java b/Mage.Sets/src/mage/cards/w/WildestDreams.java index b71233be7b8..7e4c60e943a 100644 --- a/Mage.Sets/src/mage/cards/w/WildestDreams.java +++ b/Mage.Sets/src/mage/cards/w/WildestDreams.java @@ -25,8 +25,8 @@ public final class WildestDreams extends CardImpl { Effect effect = new ReturnFromGraveyardToHandTargetEffect(); effect.setText("Return X target cards from your graveyard to your hand"); this.getSpellAbility().addEffect(effect); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addEffect(new ExileSpellEffect()); } diff --git a/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java b/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java index 11407c6e74a..778655197e5 100644 --- a/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java +++ b/Mage.Sets/src/mage/cards/w/WindgracesJudgment.java @@ -23,8 +23,8 @@ public final class WindgracesJudgment extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("For any number of opponents, destroy target nonland permanent that player controls") ); - this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); this.getSpellAbility().addTarget(new TargetNonlandPermanent(0, 1)); + this.getSpellAbility().setTargetAdjuster(new EachOpponentPermanentTargetsAdjuster()); } private WindgracesJudgment(final WindgracesJudgment card) { diff --git a/Mage.Sets/src/mage/cards/w/WordOfBinding.java b/Mage.Sets/src/mage/cards/w/WordOfBinding.java index afbd0e89928..96beb36cf20 100644 --- a/Mage.Sets/src/mage/cards/w/WordOfBinding.java +++ b/Mage.Sets/src/mage/cards/w/WordOfBinding.java @@ -20,8 +20,8 @@ public final class WordOfBinding extends CardImpl { // Tap X target creatures. this.getSpellAbility().addEffect(new TapTargetEffect("tap X target creatures")); - this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster()); } private WordOfBinding(final WordOfBinding card) { diff --git a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java index 5cfca700972..15a2c841e0b 100644 --- a/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java +++ b/Mage.Sets/src/mage/cards/w/WrexialTheRisenDeep.java @@ -1,31 +1,34 @@ package mage.cards.w; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.MayCastTargetCardEffect; import mage.abilities.effects.common.replacement.ThatSpellGraveyardExileReplacementEffect; import mage.abilities.keyword.IslandwalkAbility; import mage.abilities.keyword.SwampwalkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.CastManaAdjustment; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; -import mage.filter.predicate.Predicates; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.Target; +import mage.filter.common.FilterInstantOrSorceryCard; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author jeffwadsworth, xenohedron + * @author notgreat */ public final class WrexialTheRisenDeep extends CardImpl { + private static final FilterCard filter + = new FilterInstantOrSorceryCard("instant or sorcery card from that player's graveyard"); + public WrexialTheRisenDeep(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}{B}"); this.supertype.add(SuperType.LEGENDARY); @@ -41,7 +44,14 @@ public final class WrexialTheRisenDeep extends CardImpl { // Whenever Wrexial, the Risen Deep deals combat damage to a player, you may cast target instant or sorcery card from that player's graveyard without paying its mana cost. // If that card would be put into a graveyard this turn, exile it instead. - this.addAbility(new WrexialTheRisenDeepTriggeredAbility()); + OneShotEffect effect = new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST, true); + effect.setText("you may cast target instant or sorcery card from " + + "that player's graveyard without paying its mana cost. " + + ThatSpellGraveyardExileReplacementEffect.RULE_A); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, false, true); + ability.addTarget(new TargetCardInGraveyard(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); } private WrexialTheRisenDeep(final WrexialTheRisenDeep card) { @@ -53,49 +63,3 @@ public final class WrexialTheRisenDeep extends CardImpl { return new WrexialTheRisenDeep(this); } } - -class WrexialTheRisenDeepTriggeredAbility extends TriggeredAbilityImpl { - - WrexialTheRisenDeepTriggeredAbility() { - super(Zone.BATTLEFIELD, new MayCastTargetCardEffect(CastManaAdjustment.WITHOUT_PAYING_MANA_COST, true) - .setText("you may cast target instant or sorcery card from " - + "that player's graveyard without paying its mana cost. " - + ThatSpellGraveyardExileReplacementEffect.RULE_A), false); - setTriggerPhrase("Whenever {this} deals combat damage to a player, "); - } - - private WrexialTheRisenDeepTriggeredAbility(final WrexialTheRisenDeepTriggeredAbility ability) { - super(ability); - } - - @Override - public WrexialTheRisenDeepTriggeredAbility copy() { - return new WrexialTheRisenDeepTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterCard("instant or sorcery card from that player's graveyard"); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - filter.add(Predicates.or( - CardType.INSTANT.getPredicate(), - CardType.SORCERY.getPredicate() - )); - Target target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/z/ZarethSanTheTrickster.java b/Mage.Sets/src/mage/cards/z/ZarethSanTheTrickster.java index d1d9d6bab99..a40f80a5084 100644 --- a/Mage.Sets/src/mage/cards/z/ZarethSanTheTrickster.java +++ b/Mage.Sets/src/mage/cards/z/ZarethSanTheTrickster.java @@ -2,7 +2,7 @@ package mage.cards.z; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ReturnToHandChosenControlledPermanentCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -16,23 +16,23 @@ import mage.constants.*; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterPermanentCard; -import mage.filter.predicate.card.OwnerIdPredicate; import mage.filter.predicate.permanent.UnblockedPredicate; import mage.game.Game; -import mage.game.events.DamagedEvent; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetControlledPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; import java.util.UUID; /** - * @author TheElk801 + * @author TheElk801, notgreat */ public final class ZarethSanTheTrickster extends CardImpl { + private static final FilterCard filterCardGraveyard + = new FilterPermanentCard("permanent card from that player's graveyard"); private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.ROGUE, "an unblocked attacking Rogue you control"); static { @@ -59,7 +59,10 @@ public final class ZarethSanTheTrickster extends CardImpl { this.addAbility(ability); // Whenever Zareth San deals combat damage to a player, you may put target permanent card from that player's graveyard onto the battlefield under your control. - this.addAbility(new ZarethSanTheTricksterTriggeredAbility()); + Ability ability2 = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect(), true, true); + ability2.addTarget(new TargetCardInGraveyard(filterCardGraveyard)); + ability2.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability2); } private ZarethSanTheTrickster(final ZarethSanTheTrickster card) { @@ -109,47 +112,3 @@ class ZarethSanTheTricksterEffect extends OneShotEffect { return true; } } - -class ZarethSanTheTricksterTriggeredAbility extends TriggeredAbilityImpl { - - ZarethSanTheTricksterTriggeredAbility() { - super(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), true); - } - - private ZarethSanTheTricksterTriggeredAbility(final ZarethSanTheTricksterTriggeredAbility ability) { - super(ability); - } - - @Override - public ZarethSanTheTricksterTriggeredAbility copy() { - return new ZarethSanTheTricksterTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent == null - || !event.getSourceId().equals(this.sourceId) - || !((DamagedEvent) event).isCombatDamage()) { - return false; - } - FilterCard filter = new FilterPermanentCard( - "permanent card in " + opponent.getLogName() + "'s graveyard" - ); - filter.add(new OwnerIdPredicate(opponent.getId())); - this.getTargets().clear(); - this.addTarget(new TargetCardInGraveyard(filter)); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, you may put target permanent card " + - "from that player's graveyard onto the battlefield under your control."; - } -} diff --git a/Mage.Sets/src/mage/cards/z/ZethiArcaneBlademaster.java b/Mage.Sets/src/mage/cards/z/ZethiArcaneBlademaster.java index 1600b43f2fa..31f5819e3c0 100644 --- a/Mage.Sets/src/mage/cards/z/ZethiArcaneBlademaster.java +++ b/Mage.Sets/src/mage/cards/z/ZethiArcaneBlademaster.java @@ -44,8 +44,8 @@ public final class ZethiArcaneBlademaster extends CardImpl { // When Chun-Li enters the battlefield, exile up to X target instant cards from your graveyard, where X is the number of times Chun-Li was kicked. Put a kick counter on each of them. Ability ability = new EntersBattlefieldTriggeredAbility(new ZethiArcaneBlademasterExileEffect()); - ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); ability.addTarget(new TargetCardInYourGraveyard(0, 1, filter)); + ability.setTargetAdjuster(new TargetsCountAdjuster(MultikickerCount.instance)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/z/ZombieCannibal.java b/Mage.Sets/src/mage/cards/z/ZombieCannibal.java index 50066edead1..d2bac983887 100644 --- a/Mage.Sets/src/mage/cards/z/ZombieCannibal.java +++ b/Mage.Sets/src/mage/cards/z/ZombieCannibal.java @@ -1,8 +1,9 @@ package mage.cards.z; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -10,12 +11,10 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.predicate.card.OwnerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; import mage.target.common.TargetCardInGraveyard; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; + +import java.util.UUID; /** * @@ -23,6 +22,7 @@ import mage.target.common.TargetCardInGraveyard; */ public final class ZombieCannibal extends CardImpl { + private static final FilterCard filterGraveyardCard = new FilterCard("card from that player's graveyard"); public ZombieCannibal(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}"); this.subtype.add(SubType.ZOMBIE); @@ -31,7 +31,11 @@ public final class ZombieCannibal extends CardImpl { this.toughness = new MageInt(1); // Whenever Zombie Cannibal deals combat damage to a player, you may exile target card from that player's graveyard. - this.addAbility(new ZombieCannibalTriggeredAbility()); + Effect effect = new ExileTargetEffect(null, "", Zone.GRAVEYARD); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(effect, true, true); + ability.addTarget(new TargetCardInGraveyard(filterGraveyardCard)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster(true)); + this.addAbility(ability); } private ZombieCannibal(final ZombieCannibal card) { @@ -43,47 +47,3 @@ public final class ZombieCannibal extends CardImpl { return new ZombieCannibal(this); } } - -class ZombieCannibalTriggeredAbility extends TriggeredAbilityImpl { - - public ZombieCannibalTriggeredAbility() { - super(Zone.BATTLEFIELD, new ExileTargetEffect(null, "", Zone.GRAVEYARD), true); - } - - private ZombieCannibalTriggeredAbility(final ZombieCannibalTriggeredAbility ability) { - super(ability); - } - - @Override - public ZombieCannibalTriggeredAbility copy() { - return new ZombieCannibalTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getSourceId().equals(this.sourceId) || !((DamagedPlayerEvent) event).isCombatDamage()) { - return false; - } - Player damagedPlayer = game.getPlayer(event.getTargetId()); - if (damagedPlayer == null) { - return false; - } - FilterCard filter = new FilterCard("card in " + damagedPlayer.getName() + "'s graveyard"); - filter.add(new OwnerIdPredicate(damagedPlayer.getId())); - TargetCardInGraveyard target = new TargetCardInGraveyard(filter); - this.getTargets().clear(); - this.addTarget(target); - return true; - } - - @Override - public String getRule() { - return "Whenever {this} deals combat damage to a player, " - + "you may exile target card from that player's graveyard."; - } -} diff --git a/Mage.Sets/src/mage/sets/DoctorWho.java b/Mage.Sets/src/mage/sets/DoctorWho.java index 2f46779c101..e26cddee066 100644 --- a/Mage.Sets/src/mage/sets/DoctorWho.java +++ b/Mage.Sets/src/mage/sets/DoctorWho.java @@ -278,6 +278,7 @@ public final class DoctorWho extends ExpansionSet { cards.add(new SetCardInfo("Throes of Chaos", 227, Rarity.UNCOMMON, mage.cards.t.ThroesOfChaos.class)); cards.add(new SetCardInfo("Time Beetle", 58, Rarity.UNCOMMON, mage.cards.t.TimeBeetle.class)); cards.add(new SetCardInfo("Time Lord Regeneration", 59, Rarity.UNCOMMON, mage.cards.t.TimeLordRegeneration.class)); + cards.add(new SetCardInfo("Time Reaper", 71, Rarity.RARE, mage.cards.t.TimeReaper.class)); cards.add(new SetCardInfo("Time Wipe", 238, Rarity.RARE, mage.cards.t.TimeWipe.class)); cards.add(new SetCardInfo("Traverse Eternity", 60, Rarity.RARE, mage.cards.t.TraverseEternity.class)); cards.add(new SetCardInfo("Trenzalore Clocktower", 190, Rarity.RARE, mage.cards.t.TrenzaloreClocktower.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/TolarianContemptTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/TolarianContemptTest.java index 7e6e78a3a26..d857753a42e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/TolarianContemptTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mat/TolarianContemptTest.java @@ -4,6 +4,7 @@ import mage.constants.PhaseStep; import mage.constants.Zone; import mage.counters.CounterType; import org.junit.Test; +import org.mage.test.player.TestPlayer; import org.mage.test.serverside.base.CardTestCommander4Players; /** @@ -13,7 +14,6 @@ public class TolarianContemptTest extends CardTestCommander4Players { @Test public void testEachOpponent() { - addCard(Zone.HAND, playerA, "Tolarian Contempt"); addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.BATTLEFIELD, playerD, "Raging Goblin"); @@ -21,8 +21,9 @@ public class TolarianContemptTest extends CardTestCommander4Players { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tolarian Contempt", true); - addTarget(playerA, "Raging Goblin"); - addTarget(playerA, "Memnite"); + addTarget(playerA, "Raging Goblin"); //target playerD + addTarget(playerA, "Memnite"); //target playerC + addTarget(playerA, TestPlayer.TARGET_SKIP); //target playerB setChoice(playerD, true); setChoice(playerC, true); diff --git a/Mage/src/main/java/mage/abilities/Ability.java b/Mage/src/main/java/mage/abilities/Ability.java index 5776af2c7ca..059e089684f 100644 --- a/Mage/src/main/java/mage/abilities/Ability.java +++ b/Mage/src/main/java/mage/abilities/Ability.java @@ -515,6 +515,10 @@ public interface Ability extends Controllable, Serializable { boolean canFizzle(); + /** + * Adds a target adjuster to this ability. + * If using a generic adjuster, only use after adding the blueprint target! + */ Ability setTargetAdjuster(TargetAdjuster targetAdjuster); TargetAdjuster getTargetAdjuster(); diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index c52f49cd113..efef9970e41 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -33,6 +33,7 @@ import mage.target.Target; import mage.target.TargetCard; import mage.target.Targets; import mage.target.common.TargetCardInLibrary; +import mage.target.targetadjustment.GenericTargetAdjuster; import mage.target.targetadjustment.TargetAdjuster; import mage.util.CardUtil; import mage.util.GameLog; @@ -1430,7 +1431,11 @@ public abstract class AbilityImpl implements Ability { @Override public AbilityImpl setTargetAdjuster(TargetAdjuster targetAdjuster) { + if (targetAdjuster instanceof GenericTargetAdjuster && this.getTargets().isEmpty()) { + throw new IllegalStateException("Target adjuster being added but no targets are set!"); + } this.targetAdjuster = targetAdjuster; + this.targetAdjuster.addDefaultTargets(this); return this; } diff --git a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility.java index 7e8783c74e2..338745a31dd 100644 --- a/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility.java @@ -7,20 +7,29 @@ import mage.game.Game; import mage.game.events.DamagedEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @author xenohedron */ public class DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility extends TriggeredAbilityImpl { + protected final boolean setTargetPointer; + public DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility(Effect effect, boolean optional) { + this(effect, optional, false); + } + + public DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); setTriggerPhrase("Whenever {this} deals combat damage to a player or planeswalker, "); + this.setTargetPointer = setTargetPointer; } protected DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility(final DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility ability) { super(ability); + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -47,6 +56,9 @@ public class DealsCombatDamageToAPlayerOrPlaneswalkerTriggeredAbility extends Tr } } getAllEffects().setValue("damage", event.getAmount()); + if (setTargetPointer) { + getAllEffects().setTargetPointer(new FixedTarget(event.getPlayerId())); + } return true; } diff --git a/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java b/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java index 456ed666798..09906bdad14 100644 --- a/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java +++ b/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java @@ -1,24 +1,23 @@ package mage.game.permanent.token; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.MenaceAbility; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.common.FilterArtifactPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; -import mage.game.Game; -import mage.game.events.DamagedPlayerEvent; -import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.common.TargetArtifactPermanent; +import mage.target.TargetPermanent; +import mage.target.targetadjustment.DamagedPlayerControlsTargetAdjuster; public class DragonMenaceAndStealArtifactToken extends TokenImpl { + private static final FilterArtifactPermanent filter + = new FilterArtifactPermanent("artifact that player controls"); + public DragonMenaceAndStealArtifactToken() { super("Dragon Token", "6/6 black and red Dragon creature token with flying, menace, and \"Whenever this creature deals combat damage to a player, gain control of target artifact that player controls.\""); cardType.add(CardType.CREATURE); @@ -30,7 +29,10 @@ public class DragonMenaceAndStealArtifactToken extends TokenImpl { addAbility(FlyingAbility.getInstance()); addAbility(new MenaceAbility(false)); - addAbility(new DragonTokenTriggeredAbility()); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new GainControlTargetEffect(Duration.EndOfGame), false, true); + ability.addTarget(new TargetPermanent(filter)); + ability.setTargetAdjuster(new DamagedPlayerControlsTargetAdjuster()); + addAbility(ability); } private DragonMenaceAndStealArtifactToken(final DragonMenaceAndStealArtifactToken token) { @@ -42,48 +44,3 @@ public class DragonMenaceAndStealArtifactToken extends TokenImpl { } } - -class DragonTokenTriggeredAbility extends TriggeredAbilityImpl { - - public DragonTokenTriggeredAbility() { - super(Zone.BATTLEFIELD, new GainControlTargetEffect(Duration.EndOfGame)); - this.addTarget(new TargetArtifactPermanent()); - } - - protected DragonTokenTriggeredAbility(final DragonTokenTriggeredAbility ability) { - super(ability); - } - - @Override - public DragonTokenTriggeredAbility copy() { - return new DragonTokenTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; - if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { - Player opponent = game.getPlayer(event.getPlayerId()); - if (opponent != null) { - FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact " + opponent.getLogName() + " controls"); - filter.add(new ControllerIdPredicate(opponent.getId())); - - this.getTargets().clear(); - this.addTarget(new TargetArtifactPermanent(filter)); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever this creature deals combat damage to a player, gain control of target artifact that player controls."; - } - -} diff --git a/Mage/src/main/java/mage/target/targetadjustment/DamagedPlayerControlsTargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/DamagedPlayerControlsTargetAdjuster.java new file mode 100644 index 00000000000..93f4edd807c --- /dev/null +++ b/Mage/src/main/java/mage/target/targetadjustment/DamagedPlayerControlsTargetAdjuster.java @@ -0,0 +1,61 @@ +package mage.target.targetadjustment; + +import mage.abilities.Ability; +import mage.filter.Filter; +import mage.filter.predicate.card.OwnerIdPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.targetpointer.FirstTargetPointer; +import mage.util.CardUtil; + +import java.util.UUID; + +/** + * @author notgreat + */ +public class DamagedPlayerControlsTargetAdjuster extends GenericTargetAdjuster { + private final boolean owner; + + /** + * Use with {@link mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility} with setTargetPointer enabled, + * or {@link mage.abilities.common.OneOrMoreDealDamageTriggeredAbility} with "SetTargetPointer.PLAYER" or similar. + * Adjusts the target to only target something the damaged player controls (or owns with alternative constructor) + * And then removes the effects' target pointer that the triggered ability set + */ + public DamagedPlayerControlsTargetAdjuster() { + this(false); + } + + public DamagedPlayerControlsTargetAdjuster(boolean owner) { + this.owner = owner; + } + + @Override + public void addDefaultTargets(Ability ability) { + super.addDefaultTargets(ability); + CardUtil.AssertNoControllerOwnerPredicates(blueprintTarget); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + UUID opponentId = ability.getEffects().get(0).getTargetPointer().getFirst(game, ability); + Player opponent = game.getPlayer(opponentId); + ability.getTargets().clear(); + ability.getAllEffects().setTargetPointer(new FirstTargetPointer()); + if (opponent == null) { + return; + } + Target newTarget = blueprintTarget.copy(); + Filter filter = newTarget.getFilter(); + if (owner) { + filter.add(new OwnerIdPredicate(opponentId)); + newTarget.withTargetName(filter.getMessage() + " (owned by " + opponent.getLogName() + ")"); + } else { + filter.add(new ControllerIdPredicate(opponentId)); + newTarget.withTargetName(filter.getMessage() + " (controlled by " + opponent.getLogName() + ")"); + } + ability.addTarget(newTarget); + } +} diff --git a/Mage/src/main/java/mage/target/targetadjustment/EachOpponentPermanentTargetsAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/EachOpponentPermanentTargetsAdjuster.java index 7c8599135f7..7ac8388f541 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/EachOpponentPermanentTargetsAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/EachOpponentPermanentTargetsAdjuster.java @@ -4,17 +4,18 @@ import mage.abilities.Ability; import mage.filter.Filter; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; +import mage.target.Target; import mage.target.TargetPermanent; +import mage.util.CardUtil; import java.util.UUID; /** * @author notgreat */ -public class EachOpponentPermanentTargetsAdjuster implements TargetAdjuster { - private TargetPermanent blueprintTarget = null; +public class EachOpponentPermanentTargetsAdjuster extends GenericTargetAdjuster { + /** * Duplicates the permanent target for each opponent. * Filtering of permanent's controllers will be handled inside, so @@ -24,23 +25,27 @@ public class EachOpponentPermanentTargetsAdjuster implements TargetAdjuster { } @Override - public void adjustTargets(Ability ability, Game game) { - if (blueprintTarget == null) { - blueprintTarget = (TargetPermanent) ability.getTargets().get(0).copy(); + public void addDefaultTargets(Ability ability) { + super.addDefaultTargets(ability); + if (!(blueprintTarget instanceof TargetPermanent)) { + throw new IllegalArgumentException("EachOpponentPermanentTargetsAdjuster must use Permanent target - " + blueprintTarget); } + CardUtil.AssertNoControllerOwnerPredicates(blueprintTarget); + } + + @Override + public void adjustTargets(Ability ability, Game game) { ability.getTargets().clear(); for (UUID opponentId : game.getOpponents(ability.getControllerId())) { Player opponent = game.getPlayer(opponentId); if (opponent == null) { continue; } - TargetPermanent newTarget = blueprintTarget.copy(); - Filter filter = newTarget.getFilter(); + Target newTarget = blueprintTarget.copy(); + Filter filter = newTarget.getFilter(); filter.add(new ControllerIdPredicate(opponentId)); - if (!newTarget.possibleTargets(ability.getControllerId(), ability, game).isEmpty()) { - newTarget.withTargetName(filter.getMessage() + " controlled by " + opponent.getLogName()); - ability.addTarget(newTarget); - } + newTarget.withTargetName(filter.getMessage() + " controlled by " + opponent.getLogName()); + ability.addTarget(newTarget); } } } diff --git a/Mage/src/main/java/mage/target/targetadjustment/GenericTargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/GenericTargetAdjuster.java new file mode 100644 index 00000000000..83184a706ec --- /dev/null +++ b/Mage/src/main/java/mage/target/targetadjustment/GenericTargetAdjuster.java @@ -0,0 +1,17 @@ +package mage.target.targetadjustment; + +import mage.abilities.Ability; +import mage.target.Target; + +public abstract class GenericTargetAdjuster implements TargetAdjuster { + protected Target blueprintTarget = null; + + @Override + public void addDefaultTargets(Ability ability) { + if (blueprintTarget == null) { + blueprintTarget = ability.getTargets().get(0).copy(); + } else { + throw new IllegalStateException("Wrong code usage: target adjuster already has blueprint target - " + blueprintTarget); + } + } +} diff --git a/Mage/src/main/java/mage/target/targetadjustment/ManaValueTargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/ManaValueTargetAdjuster.java index be57da31065..d8daaa12003 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/ManaValueTargetAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/ManaValueTargetAdjuster.java @@ -12,8 +12,7 @@ import mage.target.Target; /** * @author TheElk801, notgreat */ -public class ManaValueTargetAdjuster implements TargetAdjuster { - private Target blueprintTarget = null; +public class ManaValueTargetAdjuster extends GenericTargetAdjuster { private final DynamicValue dynamicValue; private final ComparisonType comparison; @@ -30,10 +29,6 @@ public class ManaValueTargetAdjuster implements TargetAdjuster { @Override public void adjustTargets(Ability ability, Game game) { - if (blueprintTarget == null) { - blueprintTarget = ability.getTargets().get(0).copy(); - blueprintTarget.clearChosen(); - } Target newTarget = blueprintTarget.copy(); int amount = dynamicValue.calculate(game, ability, ability.getEffects().get(0)); Filter filter = newTarget.getFilter(); diff --git a/Mage/src/main/java/mage/target/targetadjustment/PowerTargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/PowerTargetAdjuster.java index f211f47f203..8b49eb8ce32 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/PowerTargetAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/PowerTargetAdjuster.java @@ -13,8 +13,7 @@ import mage.target.Target; /** * @author TheElk801, notgreat */ -public class PowerTargetAdjuster implements TargetAdjuster { - private Target blueprintTarget = null; +public class PowerTargetAdjuster extends GenericTargetAdjuster { private final DynamicValue dynamicValue; private final ComparisonType comparison; @@ -33,12 +32,9 @@ public class PowerTargetAdjuster implements TargetAdjuster { this(ManacostVariableValue.REGULAR, comparison); } + @Override public void adjustTargets(Ability ability, Game game) { - if (blueprintTarget == null) { - blueprintTarget = ability.getTargets().get(0).copy(); - blueprintTarget.clearChosen(); - } Target newTarget = blueprintTarget.copy(); int amount = dynamicValue.calculate(game, ability, ability.getEffects().get(0)); Filter filter = newTarget.getFilter(); diff --git a/Mage/src/main/java/mage/target/targetadjustment/TargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/TargetAdjuster.java index 31a3ffee340..cebcb8f6042 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/TargetAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/TargetAdjuster.java @@ -13,4 +13,10 @@ public interface TargetAdjuster extends Serializable { // Warning: This is not Copyable, do not use changeable data inside (only use static objects like Filter) void adjustTargets(Ability ability, Game game); + + /** + * Add default blueprint target to the ability + */ + default void addDefaultTargets(Ability ability) { + } } diff --git a/Mage/src/main/java/mage/target/targetadjustment/TargetsCountAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/TargetsCountAdjuster.java index cc394888a5a..c84fbd949d5 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/TargetsCountAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/TargetsCountAdjuster.java @@ -9,8 +9,7 @@ import mage.target.Target; /** * @author TheElk801, notgreat */ -public class TargetsCountAdjuster implements TargetAdjuster { - private Target blueprintTarget = null; +public class TargetsCountAdjuster extends GenericTargetAdjuster { private final DynamicValue dynamicValue; /** @@ -26,10 +25,6 @@ public class TargetsCountAdjuster implements TargetAdjuster { @Override public void adjustTargets(Ability ability, Game game) { - if (blueprintTarget == null) { - blueprintTarget = ability.getTargets().get(0).copy(); - blueprintTarget.clearChosen(); - } Target newTarget = blueprintTarget.copy(); int count = dynamicValue.calculate(game, ability, ability.getEffects().get(0)); newTarget.setMaxNumberOfTargets(count); diff --git a/Mage/src/main/java/mage/target/targetadjustment/ToughnessTargetAdjuster.java b/Mage/src/main/java/mage/target/targetadjustment/ToughnessTargetAdjuster.java index b5ccda395ba..11bb667d5ca 100644 --- a/Mage/src/main/java/mage/target/targetadjustment/ToughnessTargetAdjuster.java +++ b/Mage/src/main/java/mage/target/targetadjustment/ToughnessTargetAdjuster.java @@ -13,8 +13,7 @@ import mage.target.Target; /** * @author TheElk801, notgreat */ -public class ToughnessTargetAdjuster implements TargetAdjuster { - private Target blueprintTarget = null; +public class ToughnessTargetAdjuster extends GenericTargetAdjuster { private final DynamicValue dynamicValue; private final ComparisonType comparison; @@ -35,10 +34,6 @@ public class ToughnessTargetAdjuster implements TargetAdjuster { @Override public void adjustTargets(Ability ability, Game game) { - if (blueprintTarget == null) { - blueprintTarget = ability.getTargets().get(0).copy(); - blueprintTarget.clearChosen(); - } Target newTarget = blueprintTarget.copy(); int amount = dynamicValue.calculate(game, ability, ability.getEffects().get(0)); Filter filter = newTarget.getFilter(); diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 634a12b7181..9c9b75cfaac 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -26,7 +26,11 @@ import mage.counters.Counter; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.StaticFilters; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.card.OwnerIdPredicate; import mage.filter.predicate.mageobject.NamePredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.CardState; import mage.game.Game; import mage.game.GameState; @@ -2079,6 +2083,15 @@ public final class CardUtil { return stream.filter(clazz::isInstance).map(clazz::cast).filter(Objects::nonNull); } + public static void AssertNoControllerOwnerPredicates(Target target) { + List list = new ArrayList<>(); + Predicates.collectAllComponents(target.getFilter().getPredicates(), target.getFilter().getExtraPredicates(), list); + if (list.stream().anyMatch(p -> p instanceof TargetController.ControllerPredicate || p instanceof TargetController.OwnerPredicate + || p instanceof OwnerIdPredicate || p instanceof ControllerIdPredicate)) { + throw new IllegalArgumentException("Wrong code usage: target adjuster will add controller/owner predicate, but target's filter already has one - " + target); + } + } + /** * Move card or permanent to dest zone and add counter to it *