From 59ef2a2889159d9b7007a57d8bcb213d64201dea Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 17 Oct 2015 16:30:28 +0200 Subject: [PATCH] * Reworked ENTERS_THE_BATTLEFIELD event for replacement effects. Some rework to card movement. --- .../sets/alarareborn/ArsenalThresher.java | 3 +- .../src/mage/sets/apocalypse/Anavolver.java | 4 +- .../src/mage/sets/apocalypse/Cetavolver.java | 4 +- .../src/mage/sets/apocalypse/Degavolver.java | 4 +- .../src/mage/sets/apocalypse/Necravolver.java | 4 +- .../src/mage/sets/apocalypse/Rakavolver.java | 4 +- .../avacynrestored/TamiyoTheMoonSage.java | 12 +- .../avacynrestored/TibaltTheFiendBlooded.java | 21 ++-- .../GideonAllyOfZendikar.java | 6 +- .../KioraMasterOfTheDepths.java | 6 +- .../battleforzendikar/ObNixilisReignited.java | 6 +- .../sets/battleforzendikar/OranRiefHydra.java | 19 ++-- .../sets/battleforzendikar/PrismArray.java | 2 +- .../sets/battleforzendikar/SkyriderElf.java | 2 +- .../battleforzendikar/TajuruStalwart.java | 2 +- .../battleforzendikar/UlamogsDespoiler.java | 2 +- .../battleforzendikar/WoodlandWanderer.java | 2 +- .../sets/betrayersofkamigawa/OrbOfDreams.java | 20 ++-- .../bornofthegods/KioraTheCrashingWave.java | 23 ++-- .../mage/sets/bornofthegods/Ornitharch.java | 1 - .../OtherworldlyJourney.java | 28 +++-- .../ShimatsuTheBloodcloaked.java | 31 +++--- .../sets/commander/ChorusOfTheConclave.java | 57 +++++----- .../mage/sets/commander/TheMimeoplasm.java | 3 +- .../sets/commander2013/NayaSoulbeast.java | 3 +- .../mage/sets/commander2013/OpalPalace.java | 22 ++-- .../mage/sets/commander2014/BitterFeud.java | 3 +- .../commander2014/DarettiScrapSavant.java | 7 +- .../commander2014/FreyaliseLlanowarsFury.java | 13 +-- .../commander2014/MasterworkOfIngenuity.java | 13 +-- .../commander2014/NahiriTheLithomancer.java | 20 ++-- .../commander2014/NecromanticSelection.java | 7 +- .../ObNixilisOfTheBlackOath.java | 14 +-- .../commander2014/TeferiTemporalArchmage.java | 7 +- .../mage/sets/conflux/ApocalypseHydra.java | 7 +- .../sets/conflux/NicolBolasPlaneswalker.java | 21 ++-- .../mage/sets/conspiracy/AcademyElite.java | 2 +- .../src/mage/sets/conspiracy/DackFayden.java | 35 +++--- .../sets/conspiracy/ExtractFromDarkness.java | 12 +- .../conspiracy/MuzzioVisionaryArchitect.java | 20 ++-- .../darkascension/SorinLordOfInnistrad.java | 23 ++-- .../src/mage/sets/darksteel/AEtherVial.java | 24 ++-- .../src/mage/sets/dissension/ProteanHulk.java | 32 +++--- .../src/mage/sets/dragonsmaze/BeckCall.java | 12 +- .../sets/dragonsmaze/ProgenitorMimic.java | 13 +-- .../src/mage/sets/dragonsmaze/RalZarek.java | 24 ++-- .../dragonsoftarkir/NarsetTranscendent.java | 6 +- .../sets/dragonsoftarkir/SarkhanUnbroken.java | 8 +- .../mage/sets/eventide/CankerAbomination.java | 3 +- .../mage/sets/fatereforged/CitadelSiege.java | 2 +- .../sets/fatereforged/FrontierMastodon.java | 2 +- .../mage/sets/fatereforged/FrontierSiege.java | 2 +- .../sets/fatereforged/MonasterySiege.java | 2 +- .../mage/sets/fatereforged/OutpostSiege.java | 2 +- .../mage/sets/fatereforged/PalaceSiege.java | 2 +- .../fatereforged/UginTheSpiritDragon.java | 11 +- .../src/mage/sets/fifthdawn/Acquire.java | 10 +- .../src/mage/sets/fifthedition/Kismet.java | 11 +- .../mage/sets/fifthedition/PrimalClay.java | 6 +- .../src/mage/sets/futuresight/CloudKey.java | 3 +- .../mage/sets/futuresight/KavuPrimarch.java | 2 +- .../sets/futuresight/RavagingRiftwurm.java | 2 +- .../sets/gameday/ScaleguardSentinels.java | 2 +- .../mage/sets/gatecrash/BlindObedience.java | 20 ++-- .../src/mage/sets/gatecrash/DomriRade.java | 7 +- .../src/mage/sets/gatecrash/FathomMage.java | 7 +- .../gatecrash/GideonChampionOfJustice.java | 13 ++- .../mage/sets/gatecrash/MasterBiomancer.java | 89 ++++++++------- .../mage/sets/gatecrash/ZameckGuildmage.java | 63 +++-------- .../mage/sets/innistrad/DearlyDeparted.java | 81 +++----------- .../mage/sets/innistrad/EssenceOfTheWild.java | 85 ++------------- .../src/mage/sets/innistrad/EvilTwin.java | 13 +-- .../mage/sets/innistrad/GarrukRelentless.java | 8 +- .../mage/sets/innistrad/LilianaOfTheVeil.java | 32 +++--- .../src/mage/sets/invasion/AlloyGolem.java | 2 +- .../src/mage/sets/invasion/ArdentSoldier.java | 2 +- .../mage/sets/invasion/BenalishLancer.java | 2 +- .../src/mage/sets/invasion/Duskwalker.java | 2 +- .../mage/sets/invasion/FaerieSquadron.java | 2 +- .../src/mage/sets/invasion/KavuAggressor.java | 2 +- .../src/mage/sets/invasion/KavuTitan.java | 2 +- .../src/mage/sets/invasion/PouncingKavu.java | 2 +- .../mage/sets/invasion/PrisonBarricade.java | 2 +- .../mage/sets/invasion/UrborgSkeleton.java | 2 +- .../mage/sets/invasion/VodalianSerpent.java | 2 +- .../mage/sets/jacevsvraska/BodyDouble.java | 16 +-- .../journeyintonyx/AjaniMentorOfHeroes.java | 18 ++- .../journeyintonyx/BloodcrazedHoplite.java | 2 +- .../mage/sets/judgment/BalthorTheDefiled.java | 22 ++-- .../khansoftarkir/CleverImpersonator.java | 9 +- .../SarkhanTheDragonspeaker.java | 14 +-- .../khansoftarkir/SorinSolemnVisitor.java | 16 +-- .../sets/khansoftarkir/WarNameAspirant.java | 1 - .../mage/sets/limitedalpha/AnimateDead.java | 52 +++++---- .../mage/sets/limitedalpha/CopyArtifact.java | 89 ++------------- .../mage/sets/magic2010/AjaniGoldmane.java | 40 ++++--- .../mage/sets/magic2010/ChandraNalaar.java | 24 ++-- .../sets/magic2010/GarrukWildspeaker.java | 60 +++++----- .../src/mage/sets/magic2010/JaceBeleren.java | 23 ++-- .../src/mage/sets/magic2010/LilianaVess.java | 6 +- .../src/mage/sets/magic2011/InfernoTitan.java | 16 +-- .../src/mage/sets/magic2011/SunTitan.java | 16 +-- .../sets/magic2012/ChandraTheFirebrand.java | 23 ++-- .../sets/magic2012/GarrukPrimalHunter.java | 22 ++-- .../mage/sets/magic2012/JaceMemoryAdept.java | 16 +-- .../mage/sets/magic2012/PhantasmalImage.java | 103 ++++++------------ .../src/mage/sets/magic2012/SuturedGhoul.java | 3 +- .../sets/magic2013/AjaniCallerOfThePride.java | 8 +- .../magic2013/LilianaOfTheDarkRealms.java | 29 +++-- .../sets/magic2014/ChandraPyromaster.java | 6 +- .../sets/magic2014/GarrukCallerOfBeasts.java | 15 ++- .../sets/magic2014/ImposingSovereign.java | 10 +- .../mage/sets/magic2014/SavageSummoning.java | 2 +- .../mage/sets/magic2015/AjaniSteadfast.java | 22 ++-- .../sets/magic2015/GarrukApexPredator.java | 6 +- .../src/mage/sets/magic2015/GenesisHydra.java | 8 +- .../mage/sets/magic2015/HushwingGryff.java | 2 +- .../magic2015/JaceTheLivingGuildpact.java | 19 ++-- .../sets/magic2015/MercurialPretender.java | 63 ++--------- .../mage/sets/magic2015/NissaWorldwaker.java | 21 ++-- .../magicorigins/ChandraRoaringFlame.java | 36 +++--- .../sets/magicorigins/GideonBattleForged.java | 6 +- .../sets/magicorigins/HallowedMoonlight.java | 4 +- .../magicorigins/JaceTelepathUnbound.java | 6 +- .../LilianaDefiantNecromancer.java | 6 +- .../sets/magicorigins/NissaSageAnimist.java | 6 +- .../src/mage/sets/mirrodin/ProteusStaff.java | 22 ++-- .../TezzeretAgentOfBolas.java | 23 ++-- .../mage/sets/modernmasters/Epochrasite.java | 2 +- .../modernmasters2015/WorldheartPhoenix.java | 2 +- .../sets/morningtide/BramblewoodParagon.java | 24 ++-- .../sets/morningtide/OonasBlackguard.java | 4 +- .../sets/morningtide/RecrossThePaths.java | 16 +-- .../mage/sets/morningtide/SageOfFables.java | 13 +-- .../src/mage/sets/nemesis/ParallaxWave.java | 19 +--- .../src/mage/sets/newphyrexia/DueRespect.java | 15 ++- .../mage/sets/newphyrexia/KarnLiberated.java | 6 +- .../mage/sets/newphyrexia/OmenMachine.java | 15 ++- .../src/mage/sets/newphyrexia/TorporOrb.java | 12 +- .../sets/newphyrexia/UrabraskTheHidden.java | 20 ++-- .../mage/sets/planarchaos/FrozenAEther.java | 15 +-- .../sets/planarchaos/VoidstoneGargoyle.java | 3 +- .../sets/planechase2012/PrimalPlasma.java | 6 +- .../planechase2012/SakashimasStudent.java | 39 ++----- .../mage/sets/planeshift/ArcticMerfolk.java | 3 +- .../src/mage/sets/planeshift/DralnusPet.java | 4 +- .../mage/sets/planeshift/PhyrexianScuta.java | 3 +- .../mage/sets/ravnica/CopyEnchantment.java | 27 ++--- .../mage/sets/ravnica/LoxodonGatekeeper.java | 24 ++-- .../returntoravnica/CorpsejackMenace.java | 46 ++++---- .../JaceArchitectOfThought.java | 6 +- .../returntoravnica/TabletOfTheGuilds.java | 3 +- .../sets/returntoravnica/VraskaTheUnseen.java | 6 +- .../sets/riseoftheeldrazi/GideonJura.java | 26 ++--- .../sets/riseoftheeldrazi/SarkhanTheMad.java | 6 +- .../sets/riseoftheeldrazi/WallOfOmens.java | 18 +-- .../SakashimaTheImpostor.java | 98 +++++------------ .../sets/scarsofmirrodin/ElspethTirel.java | 28 +++-- .../sets/scarsofmirrodin/KothOfTheHammer.java | 18 +-- .../scarsofmirrodin/VenserTheSojourner.java | 6 +- .../sets/shadowmoor/FlourishingDefenses.java | 6 +- .../mage/sets/shadowmoor/GlamerSpinners.java | 5 +- .../sets/shardsofalara/AjaniVengeant.java | 69 ++++++------ .../shardsofalara/ElspethKnightErrant.java | 26 ++--- .../mage/sets/shardsofalara/SarkhanVol.java | 80 +++++++------- .../sets/shardsofalara/TezzeretTheSeeker.java | 6 +- .../sets/speedvscunning/AquamorphEntity.java | 14 +-- .../src/mage/sets/tempest/Dracoplasm.java | 32 +++--- Mage.Sets/src/mage/sets/tempest/RootMaze.java | 9 +- .../src/mage/sets/tenthedition/Clone.java | 21 ++-- .../sets/tenthedition/SculptingSteel.java | 19 +--- .../sets/theros/AshiokNightmareWeaver.java | 6 +- .../mage/sets/theros/ElspethSunsChampion.java | 10 +- .../mage/sets/theros/XenagosTheReveler.java | 21 ++-- .../mage/sets/timespiral/Hypergenesis.java | 9 +- .../src/mage/sets/timespiral/Vesuva.java | 23 ++-- .../mage/sets/urzasdestiny/AcademyRector.java | 2 +- .../sets/vintagemasters/DacksDuplicate.java | 14 +-- .../mage/sets/weatherlight/CallOfTheWild.java | 30 +++-- .../sets/worldwake/JaceTheMindSculptor.java | 23 ++-- .../sets/worldwake/JwariShapeshifter.java | 19 +--- .../src/mage/sets/zendikar/AetherFigment.java | 27 +++-- .../src/mage/sets/zendikar/ChandraAblaze.java | 6 +- .../src/mage/sets/zendikar/NissaRevane.java | 19 ++-- .../src/mage/sets/zendikar/SorinMarkov.java | 14 +-- .../abilities/enters/MasterBiomancerTest.java | 34 +++--- .../cards/abilities/keywords/SuspendTest.java | 2 + .../cards/copy/KikiJikiMirrorBreakerTest.java | 2 +- .../org/mage/test/cards/copy/VesuvaTest.java | 1 - .../cards/replacement/PillarOfFlameTest.java | 21 +++- .../test/cards/replacement/TorporOrbTest.java | 20 ++-- .../test/cards/triggers/FathomMageTest.java | 18 +-- .../java/org/mage/test/player/TestPlayer.java | 15 +++ .../base/impl/CardTestPlayerAPIImpl.java | 6 +- Mage/src/mage/abilities/AbilityImpl.java | 4 + .../common/DiesTriggeredAbility.java | 2 +- .../common/EntersBattlefieldAbility.java | 31 +++--- ...lkerEntersWithLoyalityCountersAbility.java | 30 +++++ .../common/CastFromHandCondition.java | 9 +- .../abilities/costs/AlternativeCost2Impl.java | 2 - .../abilities/effects/ContinuousEffects.java | 2 +- .../effects/EntersBattlefieldEffect.java | 24 ++-- .../common/AddManaInAnyCombinationEffect.java | 17 ++- .../effects/common/AmplifyEffect.java | 28 ++--- .../common/ChooseBasicLandTypeEffect.java | 3 +- .../effects/common/ChooseColorEffect.java | 3 +- .../common/ChooseCreatureTypeEffect.java | 3 +- .../effects/common/ChooseLandTypeEffect.java | 3 +- .../effects/common/ChooseOpponentEffect.java | 3 +- .../effects/common/ChoosePlayerEffect.java | 3 +- .../abilities/effects/common/CopyEffect.java | 28 +++-- .../effects/common/CopyPermanentEffect.java | 7 +- .../effects/common/DevourEffect.java | 43 ++++---- .../common/DiscardOntoBattlefieldEffect.java | 4 +- .../EntersBattlefieldWithXCountersEffect.java | 7 +- ...ExileAndReturnTransformedSourceEffect.java | 2 +- .../LookLibraryAndPickControllerEffect.java | 26 +---- .../effects/common/NameACardEffect.java | 3 +- .../PutPermanentOnBattlefieldEffect.java | 17 ++- ...ttlefieldUnderYourControlTargetEffect.java | 3 +- .../effects/common/TapSourceEffect.java | 3 +- .../common/TapSourceUnlessPaysEffect.java | 6 +- .../continuous/GainAbilitySourceEffect.java | 3 +- .../counter/AddCountersSourceEffect.java | 6 +- .../abilities/keyword/AmplifyAbility.java | 6 +- .../abilities/keyword/AuraSwapAbility.java | 4 +- .../abilities/keyword/BloodthirstAbility.java | 6 +- .../mage/abilities/keyword/DashAbility.java | 26 +++-- .../mage/abilities/keyword/DevourAbility.java | 52 ++++----- .../mage/abilities/keyword/EvolveAbility.java | 81 +++++++------- .../mage/abilities/keyword/GraftAbility.java | 78 ++++++------- .../abilities/keyword/HideawayAbility.java | 13 +-- .../mage/abilities/keyword/KickerAbility.java | 2 +- .../abilities/keyword/ModularAbility.java | 2 +- .../abilities/keyword/SunburstAbility.java | 3 +- .../abilities/keyword/TributeAbility.java | 5 +- .../abilities/keyword/UnleashAbility.java | 66 +++++------ Mage/src/mage/cards/CardImpl.java | 7 +- Mage/src/mage/game/Game.java | 4 + Mage/src/mage/game/GameImpl.java | 20 +++- .../mage/game/permanent/PermanentImpl.java | 3 + Mage/src/mage/game/permanent/token/Token.java | 51 +++++---- Mage/src/mage/game/stack/Spell.java | 9 +- Mage/src/mage/players/Player.java | 12 ++ Mage/src/mage/players/PlayerImpl.java | 97 ++++++++++------- .../util/functions/AddSubtypeApplier.java | 40 +++++++ .../mage/util/functions/CardTypeApplier.java | 28 ++++- 247 files changed, 1842 insertions(+), 2287 deletions(-) create mode 100644 Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java create mode 100644 Mage/src/mage/util/functions/AddSubtypeApplier.java diff --git a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java index f4203cb0d58..af33a411bba 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java +++ b/Mage.Sets/src/mage/sets/alarareborn/ArsenalThresher.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.Cards; @@ -97,7 +96,7 @@ class ArsenalThresherEffect extends OneShotEffect { if (controller == null) { return false; } - Permanent arsenalThresher = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent arsenalThresher = game.getPermanentEntering(source.getSourceId()); FilterArtifactCard filter = new FilterArtifactCard(); filter.add(new AnotherCardPredicate()); if (controller.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", source, game)) { diff --git a/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java index 0452fbb018e..a746e9877c9 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Anavolver.java @@ -68,14 +68,14 @@ public class Anavolver extends CardImpl { // If Anavolver was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying. EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{U}"), true, "If {this} was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying.", + new KickedCostCondition("{1}{U}"), "If {this} was kicked with its {1}{U} kicker, it enters the battlefield with two +1/+1 counters on it and with flying.", "{this} enters the battlefield with two +1/+1 counters on it and with flying"); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Anavolver was kicked with its {B} kicker, it enters the battlefield with a +1/+1 counter on it and with "Pay 3 life: Regenerate Anavolver." EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{B}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{B}"), "If {this} was kicked with its {B} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Pay 3 life: Regenerate Anavolver.\"", "{this} enters the battlefield with a +1/+1 counter on it and with \"Pay 3 life: Regenerate Anavolver.\""); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new PayLifeCost(3)), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java index 8a040de3b0d..16029793e73 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Cetavolver.java @@ -65,14 +65,14 @@ public class Cetavolver extends CardImpl { // If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike. EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{R}"), true, "If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike.", + new KickedCostCondition("{1}{R}"), "If Cetavolver was kicked with its {1}{R} kicker, it enters the battlefield with two +1/+1 counters on it and with first strike.", "{this} enters the battlefield with two +1/+1 counters on it and with first strike"); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Cetavolver was kicked with its {G} kicker, it enters the battlefield with a +1/+1 counter on it and with trample. EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{G}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{G}"), "If Cetavolver was kicked with its {G} kicker, it enters the battlefield with a +1/+1 counter on it and with trample.", "{this} enters the battlefield with a +1/+1 counter on it and with trample"); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java index 87577042db5..c0b557454ac 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Degavolver.java @@ -69,14 +69,14 @@ public class Degavolver extends CardImpl { // If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with "Pay 3 life: Regenerate Degavolver." EntersBattlefieldAbility ability1 = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2),false), - new KickedCostCondition("{1}{B}"), true, "If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\"", + new KickedCostCondition("{1}{B}"), "If Degavolver was kicked with its {1}{B} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\"", "{this} enters the battlefield with two +1/+1 counters on it and with \"Pay 3 life: Regenerate Degavolver.\""); ((EntersBattlefieldEffect)ability1.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new PayLifeCost(3)), Duration.WhileOnBattlefield)); this.addAbility(ability1); // If Degavolver was kicked with its {R} kicker, it enters the battlefield with a +1/+1 counter on it and with first strike. EntersBattlefieldAbility ability2 = new EntersBattlefieldAbility( - new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{R}"), true, + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1),false), new KickedCostCondition("{R}"), "If Degavolver was kicked with its {R} kicker, it enters the battlefield with a +1/+1 counter on it and with first strike.", "{this} enters the battlefield with a +1/+1 counter on it and with first strike"); ((EntersBattlefieldEffect)ability2.getEffects().get(0)).addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); diff --git a/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java b/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java index 03427cbaf88..1a37ec37553 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Necravolver.java @@ -64,12 +64,12 @@ public class Necravolver extends CardImpl { this.addAbility(kickerAbility); // If Necravolver was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new KickedCostCondition("{1}{G}"), true, "If {this} was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample.", ""); + new KickedCostCondition("{1}{G}"), "If {this} was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample.", ""); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); // If Necravolver was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with "Whenever Necravolver deals damage, you gain that much life." ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - new KickedCostCondition("{W}"), true, "If {this} was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); + new KickedCostCondition("{W}"), "If {this} was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); ability.addEffect(new GainAbilitySourceEffect(new DealsDamageGainLifeSourceTriggeredAbility(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java b/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java index 62444bed93b..e020d9fd2ff 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Rakavolver.java @@ -64,12 +64,12 @@ public class Rakavolver extends CardImpl { this.addAbility(kickerAbility); // If Rakavolver was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with "Whenever Rakavolver deals damage, you gain that much life." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new KickedCostCondition("{1}{W}"), true, "If {this} was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); + new KickedCostCondition("{1}{W}"), "If {this} was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with \"Whenever {this} deals damage, you gain that much life.\"", ""); ability.addEffect(new GainAbilitySourceEffect(new DealsDamageGainLifeSourceTriggeredAbility(), Duration.WhileOnBattlefield)); this.addAbility(ability); // If Rakavolver was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying. ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - new KickedCostCondition("{U}"), true, "If {this} was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying.", ""); + new KickedCostCondition("{U}"), "If {this} was kicked with its {U} kicker, it enters the battlefield with a +1/+1 counter on it and with flying.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java b/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java index 9e716508d32..19905589e8d 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TamiyoTheMoonSage.java @@ -30,19 +30,18 @@ package mage.sets.avacynrestored; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect; import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect.HandSizeModification; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -50,7 +49,6 @@ import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TappedPredicate; @@ -71,8 +69,7 @@ public class TamiyoTheMoonSage extends CardImpl { this.expansionSetCode = "AVR"; this.subtype.add("Tamiyo"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Tap target permanent. It doesn't untap during its controller's next untap step. LoyaltyAbility ability = new LoyaltyAbility(new TapTargetEffect(), 1); @@ -130,7 +127,8 @@ class TappedCreaturesControlledByTargetCount implements DynamicValue { } /** - * Emblem with "You have no maximum hand size" and "Whenever a card is put into your graveyard from anywhere, you may return it to your hand." + * Emblem with "You have no maximum hand size" and "Whenever a card is put into + * your graveyard from anywhere, you may return it to your hand." */ class TamiyoTheMoonSageEmblem extends Emblem { diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java b/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java index b899d7e651a..b17f824dd78 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TibaltTheFiendBlooded.java @@ -29,29 +29,27 @@ package mage.sets.avacynrestored; import java.util.List; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -70,8 +68,7 @@ public class TibaltTheFiendBlooded extends CardImpl { this.expansionSetCode = "AVR"; this.subtype.add("Tibalt"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); // +1: Draw a card, then discard a card at random. LoyaltyAbility ability = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java index 9da9eacd178..07c4d334a5e 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/GideonAllyOfZendikar.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; @@ -39,14 +39,12 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.command.Emblem; import mage.game.permanent.token.Token; @@ -61,7 +59,7 @@ public class GideonAllyOfZendikar extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Gideon"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, Gideon, Ally of Zendikar becomes a 5/5 Human Soldier Ally creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn. LoyaltyAbility ability = new LoyaltyAbility(new BecomesCreatureSourceEffect(new GideonAllyOfZendikarToken(), "planeswalker", Duration.EndOfTurn), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java index 557c17be929..ead4e657e67 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/KioraMasterOfTheDepths.java @@ -32,13 +32,12 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterLandCard; @@ -73,7 +71,7 @@ public class KioraMasterOfTheDepths extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Kiora"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Untap up to one target creature and up to one target land. LoyaltyAbility ability1 = new LoyaltyAbility(new KioraUntapEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java index 419aaba047a..242438d7fdd 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/ObNixilisReignited.java @@ -30,18 +30,16 @@ package mage.sets.battleforzendikar; import java.util.UUID; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -60,7 +58,7 @@ public class ObNixilisReignited extends CardImpl { this.expansionSetCode = "BFZ"; this.subtype.add("Nixilis"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: You draw a card and you lose 1 life. Effect effect = new DrawCardSourceControllerEffect(1); diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java b/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java index b3f7679d293..a997e01fd4b 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/OranRiefHydra.java @@ -60,8 +60,8 @@ public class OranRiefHydra extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - - // Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. + + // Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. // If that land is a Forest, put two +1/+1 counters on Oran-Rief Hydra instead. this.addAbility(new OranRiefHydraTriggeredAbility()); } @@ -77,9 +77,9 @@ public class OranRiefHydra extends CardImpl { } class OranRiefHydraTriggeredAbility extends TriggeredAbilityImpl { - - private static final String text = "Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on Oran-Rief Hydra. " - + "If that land is a Forest, put two +1/+1 counters on Oran-Rief Hydra instead."; + + private static final String text = "Landfall - Whenever a land enters the battlefield under your control, put a +1/+1 counter on {this}. " + + "If that land is a Forest, put two +1/+1 counters on {this} instead."; public OranRiefHydraTriggeredAbility() { super(Zone.BATTLEFIELD, new OranRiefHydraEffect()); @@ -106,12 +106,13 @@ class OranRiefHydraTriggeredAbility extends TriggeredAbilityImpl { && permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(getControllerId())) { Permanent sourcePermanent = game.getPermanent(getSourceId()); - if (sourcePermanent != null) + if (sourcePermanent != null) { for (Effect effect : getEffects()) { - if (effect instanceof OranRiefHydraEffect) { - effect.setTargetPointer(new FixedTarget(permanent, game)); + if (effect instanceof OranRiefHydraEffect) { + effect.setTargetPointer(new FixedTarget(permanent, game)); + } + return true; } - return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java b/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java index f1594a72cf4..c86c1acfc31 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/PrismArray.java @@ -57,7 +57,7 @@ public class PrismArray extends CardImpl { // Converge - Prism Array enters the battlefield with a crystal counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.CRYSTAL.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); // Remove a crystal counter from Prism Array: Tap target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java b/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java index e08242cc827..d02eccfbc59 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/SkyriderElf.java @@ -59,7 +59,7 @@ public class SkyriderElf extends CardImpl { // Converge-Skyrider Elf enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java b/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java index 15981c7815d..73947b4132e 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/TajuruStalwart.java @@ -55,7 +55,7 @@ public class TajuruStalwart extends CardImpl { // Converge - Tajuru Stalwart enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge - {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge - {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java b/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java index c879bbeb29e..bcf90209c59 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/UlamogsDespoiler.java @@ -64,7 +64,7 @@ public class UlamogsDespoiler extends CardImpl { this.toughness = new MageInt(5); // As Ulamog's Despoiler enters the battlefield, you may put two cards your opponents own from exile into their owners' graveyards. If you do, Ulamog's Despoiler enters the battlefield with four +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new UlamogsDespoilerEffect(), null, true, + this.addAbility(new EntersBattlefieldAbility(new UlamogsDespoilerEffect(), null, "As {this} enters the battlefield, you may put two cards your opponents own from exile into their owners' graveyards. If you do, {this} enters the battlefield with four +1/+1 counters on it", null)); } diff --git a/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java b/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java index 5fa4a7be4c8..0ddd17b5cbf 100644 --- a/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java +++ b/Mage.Sets/src/mage/sets/battleforzendikar/WoodlandWanderer.java @@ -59,7 +59,7 @@ public class WoodlandWanderer extends CardImpl { // Converge - Woodland Wanderer enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(), ColorsOfManaSpentToCastCount.getInstance(), true), - null, true, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); + null, "Converge — {this} enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.", null)); } public WoodlandWanderer(final WoodlandWanderer card) { diff --git a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java index b896f12a2c3..00f69ecb32e 100644 --- a/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java +++ b/Mage.Sets/src/mage/sets/betrayersofkamigawa/OrbOfDreams.java @@ -28,12 +28,15 @@ package mage.sets.betrayersofkamigawa; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -47,7 +50,7 @@ public class OrbOfDreams extends CardImpl { public OrbOfDreams(UUID ownerId) { super(ownerId, 156, "Orb of Dreams", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); this.expansionSetCode = "BOK"; - + // Permanents enter the battlefield tapped. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OrbOfDreamsEffect())); } @@ -60,7 +63,7 @@ public class OrbOfDreams extends CardImpl { public OrbOfDreams copy() { return new OrbOfDreams(this); } - + private class OrbOfDreamsEffect extends ReplacementEffectImpl { OrbOfDreamsEffect() { @@ -79,23 +82,22 @@ public class OrbOfDreams extends CardImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null) { permanent.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return true; } - } + } } - diff --git a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java index e7d04f82ebb..ccfb16f61e7 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/KioraTheCrashingWave.java @@ -32,20 +32,18 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.PreventionEffectImpl; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.PlayAdditionalLandsControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -64,6 +62,7 @@ import mage.util.CardUtil; public class KioraTheCrashingWave extends CardImpl { private static final FilterPermanent filter = new FilterPermanent("permanent an opponent control"); + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); } @@ -73,8 +72,7 @@ public class KioraTheCrashingWave extends CardImpl { this.expansionSetCode = "BNG"; this.subtype.add("Kiora"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); // +1: Until your next turn, prevent all damage that would be dealt to and dealt by target permanent an opponent controls. LoyaltyAbility ability = new LoyaltyAbility(new KioraPreventionEffect(), 1); @@ -89,7 +87,6 @@ public class KioraTheCrashingWave extends CardImpl { // -5: You get an emblem with "At the beginning of your end step, put a 9/9 blue Kraken creature token onto the battlefield." this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KioraEmblem()), -5)); - } public KioraTheCrashingWave(final KioraTheCrashingWave card) { @@ -126,10 +123,10 @@ class KioraPreventionEffect extends PreventionEffectImpl { @Override public void init(Ability source, Game game) { super.init(source, game); - for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { + for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented."), game); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(), CardUtil.addToolTipMarkTags("All damage that would be dealt to and dealt by this permanent is prevented."), game); } } } @@ -138,7 +135,7 @@ class KioraPreventionEffect extends PreventionEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (super.applies(event, source, game) && event instanceof DamageEvent) { Permanent targetPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetPermanent != null + if (targetPermanent != null && (event.getSourceId().equals(targetPermanent.getId()) || event.getTargetId().equals(targetPermanent.getId()))) { return true; } @@ -149,10 +146,10 @@ class KioraPreventionEffect extends PreventionEffectImpl { @Override public boolean isInactive(Ability source, Game game) { if (super.isInactive(source, game)) { - for(UUID targetId :this.getTargetPointer().getTargets(game, source)) { + for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(),"", game); + permanent.addInfo(new StringBuilder("kioraPrevention").append(getId()).toString(), "", game); } } return true; @@ -162,9 +159,11 @@ class KioraPreventionEffect extends PreventionEffectImpl { } /** - * Emblem: "At the beginning of your end step, put a 9/9 blue Kraken creature token onto the battlefield." + * Emblem: "At the beginning of your end step, put a 9/9 blue Kraken creature + * token onto the battlefield." */ class KioraEmblem extends Emblem { + public KioraEmblem() { this.setName("EMBLEM: Kiora, the Crashing Wave"); Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.COMMAND, new CreateTokenEffect(new KioraKrakenToken()), TargetController.YOU, null, false); diff --git a/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java b/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java index 971027d4b3f..930ff9345d3 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/Ornitharch.java @@ -29,7 +29,6 @@ package mage.sets.bornofthegods; import java.util.UUID; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.TriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.common.TributeNotPaidCondition; diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java b/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java index 00a11497edb..1444229d62b 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/OtherworldlyJourney.java @@ -25,14 +25,10 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.championsofkamigawa; import java.util.UUID; import mage.MageObjectReference; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; @@ -40,8 +36,10 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.ExileZone; @@ -61,7 +59,7 @@ public class OtherworldlyJourney extends CardImpl { super(ownerId, 37, "Otherworldly Journey", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.expansionSetCode = "CHK"; this.subtype.add("Arcane"); - + // Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it. this.getSpellAbility().addEffect(new OtherworldlyJourneyEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -82,7 +80,7 @@ class OtherworldlyJourneyEffect extends OneShotEffect { private static final String effectText = "Exile target creature. At the beginning of the next end step, return that card to the battlefield under its owner's control with a +1/+1 counter on it"; - OtherworldlyJourneyEffect ( ) { + OtherworldlyJourneyEffect() { super(Outcome.Benefit); staticText = effectText; } @@ -102,12 +100,12 @@ class OtherworldlyJourneyEffect extends OneShotEffect { Card card = game.getCard(permanent.getId()); if (card != null) { //create delayed triggered ability - DelayedTriggeredAbility delayedAbility = - new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OtherworldlyJourneyReturnFromExileEffect(new MageObjectReference(card, game))); + DelayedTriggeredAbility delayedAbility + = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new OtherworldlyJourneyReturnFromExileEffect(new MageObjectReference(card, game))); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + game.addDelayedTriggeredAbility(delayedAbility); } } return true; @@ -126,6 +124,7 @@ class OtherworldlyJourneyEffect extends OneShotEffect { class OtherworldlyJourneyReturnFromExileEffect extends OneShotEffect { MageObjectReference objectToReturn; + public OtherworldlyJourneyReturnFromExileEffect(MageObjectReference objectToReturn) { super(Outcome.PutCardInPlay); this.objectToReturn = objectToReturn; @@ -148,19 +147,18 @@ class OtherworldlyJourneyReturnFromExileEffect extends OneShotEffect { if (card != null && objectToReturn.refersTo(card, game)) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { - game.addEffect(new OtherworldlyJourneyEntersBattlefieldEffect(objectToReturn), source); - owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + game.addEffect(new OtherworldlyJourneyEntersBattlefieldEffect(objectToReturn), source); + owner.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null); } } return true; } } - class OtherworldlyJourneyEntersBattlefieldEffect extends ReplacementEffectImpl { - + MageObjectReference objectToReturn; - + public OtherworldlyJourneyEntersBattlefieldEffect(MageObjectReference objectToReturn) { super(Duration.Custom, Outcome.BoostCreature); this.objectToReturn = objectToReturn; @@ -187,7 +185,7 @@ class OtherworldlyJourneyEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(), game); discard(); // use only once diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java b/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java index 49f139f2639..f25c4609992 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/ShimatsuTheBloodcloaked.java @@ -28,13 +28,16 @@ package mage.sets.championsofkamigawa; import java.util.UUID; - -import mage.constants.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; @@ -61,7 +64,7 @@ public class ShimatsuTheBloodcloaked extends CardImpl { this.toughness = new MageInt(0); // As Shimatsu the Bloodcloaked enters the battlefield, sacrifice any number of permanents. Shimatsu enters the battlefield with that many +1/+1 counters on it. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ShimatsuTheBloodcloakedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ShimatsuTheBloodcloakedEffect())); } public ShimatsuTheBloodcloaked(final ShimatsuTheBloodcloaked card) { @@ -75,16 +78,16 @@ public class ShimatsuTheBloodcloaked extends CardImpl { } class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { - + public ShimatsuTheBloodcloakedEffect() { - super(Duration.WhileOnBattlefield, Outcome.BoostCreature); + super(Duration.EndOfGame, Outcome.BoostCreature); this.staticText = "As {this} enters the battlefield, sacrifice any number of permanents. {this} enters the battlefield with that many +1/+1 counters on it"; } - + public ShimatsuTheBloodcloakedEffect(final ShimatsuTheBloodcloakedEffect effect) { super(effect); } - + @Override public ShimatsuTheBloodcloakedEffect copy() { return new ShimatsuTheBloodcloakedEffect(this); @@ -94,15 +97,15 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(source.getSourceId()); + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledPermanent(), true); @@ -112,8 +115,8 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { controller.chooseTarget(Outcome.Detriment, target, source, game); if (target.getTargets().size() > 0) { int sacrificedCreatures = target.getTargets().size(); - game.informPlayers(new StringBuilder(controller.getLogName()).append(" sacrifices ").append(sacrificedCreatures).append(" creatures for ").append(creature.getName()).toString()); - for (UUID targetId: target.getTargets()) { + game.informPlayers(controller.getLogName() + " sacrifices " + sacrificedCreatures + " creatures for " + creature.getLogName()); + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature == null || !targetCreature.sacrifice(source.getSourceId(), game)) { return false; @@ -124,5 +127,5 @@ class ShimatsuTheBloodcloakedEffect extends ReplacementEffectImpl { } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java index 70fc31b6951..466966ec6dd 100644 --- a/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java +++ b/Mage.Sets/src/mage/sets/commander/ChorusOfTheConclave.java @@ -101,33 +101,6 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl { return new ChorusOfTheConclaveReplacementEffect(this); } - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - int xCost = 0; - Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - if (you.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", source, game)) { - xCost += playerPaysXGenericMana(you, source, game); - // save the x value to be available for ETB replacement effect - Object object = game.getState().getValue("spellX" + source.getSourceId()); - Map spellX; - if (object != null && object instanceof Map) { - spellX = (Map) object; - } else { - spellX = new HashMap<>(); - } - spellX.put(event.getSourceId().toString() + game.getState().getZoneChangeCounter(event.getSourceId()), xCost); - game.getState().setValue("spellX" + source.getSourceId(), spellX); - } - } - return false; - } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.CAST_SPELL; @@ -144,6 +117,28 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl { return false; } + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int xCost = 0; + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.chooseUse(Outcome.Benefit, "Do you wish to pay the additonal cost to add +1/+1 counters to the creature you cast?", source, game)) { + xCost += playerPaysXGenericMana(controller, source, game); + // save the x value to be available for ETB replacement effect + Object object = game.getState().getValue("spellX" + source.getSourceId()); + Map spellX; + if (object != null && object instanceof Map) { + spellX = (Map) object; + } else { + spellX = new HashMap<>(); + } + spellX.put(event.getSourceId().toString() + game.getState().getZoneChangeCounter(event.getSourceId()), xCost); + game.getState().setValue("spellX" + source.getSourceId(), spellX); + } + } + return false; + } + protected static int playerPaysXGenericMana(Player player, Ability source, Game game) { int xValue = 0; boolean payed = false; @@ -191,16 +186,18 @@ class ChorusOfTheConclaveReplacementEffect2 extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { Map spellX = (Map) game.getState().getValue("spellX" + source.getSourceId()); - return spellX != null && event.getSourceId() != null && spellX.containsKey(event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 2)); + return spellX != null + && event.getSourceId() != null + && spellX.containsKey(event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 1)); } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getSourceId()); + Permanent creature = game.getPermanentEntering(event.getSourceId()); Map spellX = (Map) game.getState().getValue("spellX" + source.getSourceId()); MageObject sourceObject = source.getSourceObject(game); if (sourceObject != null && creature != null && spellX != null) { - String key = event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 2); + String key = event.getSourceId().toString() + (game.getState().getZoneChangeCounter(event.getSourceId()) - 1); int xValue = spellX.get(key); if (xValue > 0) { creature.addCounters(CounterType.P1P1.createInstance(xValue), game); diff --git a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java index 238bb1bc6c3..7ff4058deb2 100644 --- a/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java +++ b/Mage.Sets/src/mage/sets/commander/TheMimeoplasm.java @@ -32,7 +32,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; import mage.cards.Card; @@ -98,7 +97,7 @@ class TheMimeoplasmEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { if (new CardsInAllGraveyardsCount(new FilterCreatureCard()).calculate(game, source, this) >= 2) { if (controller.chooseUse(Outcome.Benefit, "Do you want to exile two creature cards from graveyards?", source, game)) { diff --git a/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java b/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java index b375229ce70..4143523f77c 100644 --- a/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java +++ b/Mage.Sets/src/mage/sets/commander2013/NayaSoulbeast.java @@ -66,8 +66,9 @@ public class NayaSoulbeast extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); - // When you cast Naya Soulbeast, each player reveals the top card of his or her library. Naya Soulbeast enters the battlefield with X +1/+1 counters on it, where X is the total converted mana cost of all cards revealed this way. + // When you cast Naya Soulbeast, each player reveals the top card of his or her library. Ability ability = new CastSourceTriggeredAbility(new NayaSoulbeastCastEffect(), false); + // Naya Soulbeast enters the battlefield with X +1/+1 counters on it, where X is the total converted mana cost of all cards revealed this way. ability.addEffect(new NayaSoulbeastReplacementEffect()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java index 4601e1a29d5..0086d731e92 100644 --- a/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java +++ b/Mage.Sets/src/mage/sets/commander2013/OpalPalace.java @@ -74,7 +74,7 @@ public class OpalPalace extends CardImpl { ability = new SimpleStaticAbility(Zone.ALL, new OpalPalaceEntersBattlefieldEffect()); ability.setRuleVisible(false); this.addAbility(ability); - + } public OpalPalace(final OpalPalace card) { @@ -91,10 +91,10 @@ class OpalPalaceWatcher extends Watcher { public List commanderId = new ArrayList<>(); private final String originalId; - + public OpalPalaceWatcher(String originalId) { super("ManaPaidFromOpalPalaceWatcher", WatcherScope.CARD); - this.originalId = originalId; + this.originalId = originalId; } public OpalPalaceWatcher(final OpalPalaceWatcher watcher) { @@ -116,16 +116,16 @@ class OpalPalaceWatcher extends Watcher { if (spell != null) { Card card = spell.getCard(); if (card != null) { - for (UUID playerId :game.getPlayerList()) { + for (UUID playerId : game.getPlayerList()) { Player player = game.getPlayer(playerId); if (player != null) { if (player.getCommanderId() != null && player.getCommanderId().equals(card.getId())) { commanderId.add(card.getId()); break; } - } + } } - } + } } } } @@ -153,19 +153,19 @@ class OpalPalaceEntersBattlefieldEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { OpalPalaceWatcher watcher = (OpalPalaceWatcher) game.getState().getWatchers().get("ManaPaidFromOpalPalaceWatcher", source.getSourceId()); - return watcher != null && - watcher.commanderId.contains(event.getTargetId()); + return watcher != null + && watcher.commanderId.contains(event.getTargetId()); } @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null) { - Integer castCount = (Integer)game.getState().getValue(permanent.getId() + "_castCount"); + Integer castCount = (Integer) game.getState().getValue(permanent.getId() + "_castCount"); if (castCount != null && castCount > 0) { permanent.addCounters(CounterType.P1P1.createInstance(castCount), game); } diff --git a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java index 22d87b793ea..0ce63beead1 100644 --- a/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java +++ b/Mage.Sets/src/mage/sets/commander2014/BitterFeud.java @@ -32,7 +32,6 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.Card; @@ -92,7 +91,7 @@ class BitterFeudEntersBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { TargetPlayer target = new TargetPlayer(2, 2, true); controller.chooseTarget(outcome, target, source, game); diff --git a/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java b/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java index 48b846573c7..a4d4ceab35c 100644 --- a/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java +++ b/Mage.Sets/src/mage/sets/commander2014/DarettiScrapSavant.java @@ -33,13 +33,12 @@ import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; @@ -75,7 +73,7 @@ public class DarettiScrapSavant extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Daretti"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Discard up to two cards, then draw that many cards. this.addAbility(new LoyaltyAbility(new DarettiDiscardDrawEffect(), 2)); @@ -179,7 +177,6 @@ class DarettiSacrificeEffect extends OneShotEffect { class DarettiScrapSavantEmblem extends Emblem { // You get an emblem with "Whenever an artifact is put into your graveyard from the battlefield, return that card to the battlefield at the beginning of the next end step." - public DarettiScrapSavantEmblem() { this.setName("Emblem - Daretti"); this.getAbilities().add(new DarettiScrapSavantTriggeredAbility()); diff --git a/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java b/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java index adf5daa6ca5..e8d82a0618a 100644 --- a/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java +++ b/Mage.Sets/src/mage/sets/commander2014/FreyaliseLlanowarsFury.java @@ -32,19 +32,17 @@ import mage.MageInt; import mage.ObjectColor; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.mana.GreenManaAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.counters.CounterType; -import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterArtifactOrEnchantmentPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.permanent.token.Token; import mage.target.TargetPermanent; @@ -56,6 +54,7 @@ import mage.target.TargetPermanent; public class FreyaliseLlanowarsFury extends CardImpl { private static final FilterControlledCreaturePermanent filterGreen = new FilterControlledCreaturePermanent("green creature you control"); + static { filterGreen.add(new ColorPredicate(ObjectColor.GREEN)); } @@ -65,8 +64,8 @@ public class FreyaliseLlanowarsFury extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Freyalise"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); + // +2: Put a 1/1 green Elf Druid creature token onto the battlefield with "{T}: Add {G} to your mana pool." this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new FreyaliseLlanowarsFuryToken()), 2)); // -2: Destroy target artifact or enchantment. @@ -106,4 +105,4 @@ class FreyaliseLlanowarsFuryToken extends Token { // {T}: Add {G} to your mana pool. this.addAbility(new GreenManaAbility()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java b/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java index 7485d6c1534..1ec61bbb10e 100644 --- a/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java +++ b/Mage.Sets/src/mage/sets/commander2014/MasterworkOfIngenuity.java @@ -28,14 +28,11 @@ package mage.sets.commander2014; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -45,6 +42,7 @@ import mage.filter.predicate.mageobject.SubtypePredicate; * @author LevelX2 */ public class MasterworkOfIngenuity extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("artifact"); static { @@ -58,12 +56,7 @@ public class MasterworkOfIngenuity extends CardImpl { this.subtype.add("Equipment"); // You may have Masterwork of Ingenuity enter the battlefield as a copy of any Equipment on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(filter), - "You may have {this} enter the battlefield as a copy of any Equipment on the battlefield", - true)); - this.addAbility(ability); - + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public MasterworkOfIngenuity(final MasterworkOfIngenuity card) { diff --git a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java index c9f5dad4248..890dd2eab04 100644 --- a/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java +++ b/Mage.Sets/src/mage/sets/commander2014/NahiriTheLithomancer.java @@ -27,15 +27,11 @@ */ package mage.sets.commander2014; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.Effect; @@ -43,7 +39,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.IndestructibleAbility; @@ -55,7 +50,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -80,8 +74,7 @@ public class NahiriTheLithomancer extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Nahiri"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Put a 1/1 white Kor Soldier creature token onto the battlefield. You may attach an Equipment you control to it. this.addAbility(new LoyaltyAbility(new NahiriTheLithomancerFirstAbilityEffect(), 2)); @@ -111,6 +104,7 @@ public class NahiriTheLithomancer extends CardImpl { class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { private static final FilterControlledPermanent filter = new FilterControlledPermanent("an Equipment you control"); + static { filter.add(new SubtypePredicate("Equipment")); } @@ -139,8 +133,8 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { if (tokenPermanent != null) { //TODO: Make sure the Equipment can legally enchant the token, preferably on targetting. Target target = new TargetControlledPermanent(0, 1, filter, true); - if (target.canChoose(source.getSourceId(), controller.getId(), game) && - controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", source, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) + && controller.chooseUse(outcome, "Attach an Equipment you control to the created Token?", source, game)) { if (target.choose(Outcome.Neutral, source.getControllerId(), source.getSourceId(), game)) { Permanent equipmentPermanent = game.getPermanent(target.getFirstTarget()); if (equipmentPermanent != null) { @@ -164,6 +158,7 @@ class NahiriTheLithomancerFirstAbilityEffect extends OneShotEffect { class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("an Equipment"); + static { filter.add(new SubtypePredicate("Equipment")); } @@ -193,8 +188,7 @@ class NahiriTheLithomancerSecondAbilityEffect extends OneShotEffect { if (card != null) { controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); } - } - else { + } else { Target target = new TargetCardInYourGraveyard(0, 1, filter); target.choose(Outcome.PutCardInPlay, source.getControllerId(), source.getSourceId(), game); Card card = controller.getGraveyard().get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java b/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java index b595331cf91..240f34a2f5f 100644 --- a/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java +++ b/Mage.Sets/src/mage/sets/commander2014/NecromanticSelection.java @@ -71,7 +71,6 @@ public class NecromanticSelection extends CardImpl { super(ownerId, 26, "Necromantic Selection", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{B}{B}{B}"); this.expansionSetCode = "C14"; - // Destroy all creatures, then return a creature card put into a graveyard this way to the battlefield under your control. It's a black Zombie in addition to its other colors and types. Exile Necromantic Selection. this.getSpellAbility().addEffect(new NecromanticSelectionEffect()); this.getSpellAbility().addEffect(ExileSpellEffect.getInstance()); @@ -110,7 +109,7 @@ class NecromanticSelectionEffect extends OneShotEffect { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null && controller != null) { Cards cards = new CardsImpl(); - for(Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), controller.getId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), controller.getId(), source.getSourceId(), game)) { permanent.destroy(source.getSourceId(), game, false); if (game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { cards.add(permanent); @@ -118,7 +117,7 @@ class NecromanticSelectionEffect extends OneShotEffect { } FilterCard filter = new FilterCreatureCard("creature card put into a graveyard with " + sourceObject.getLogName()); ArrayList> cardIdPredicates = new ArrayList<>(); - for(UUID cardId: cards) { + for (UUID cardId : cards) { cardIdPredicates.add(new CardIdPredicate(cardId)); } filter.add(Predicates.or(cardIdPredicates)); @@ -126,7 +125,7 @@ class NecromanticSelectionEffect extends OneShotEffect { if (controller.chooseTarget(outcome, target, source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); ContinuousEffect effect = new NecromanticSelectionContinuousEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java index 2593433d2ea..2a1e6544c52 100644 --- a/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java +++ b/Mage.Sets/src/mage/sets/commander2014/ObNixilisOfTheBlackOath.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.mana.ManaCostsImpl; @@ -44,14 +44,11 @@ import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.token.DemonToken; @@ -69,8 +66,7 @@ public class ObNixilisOfTheBlackOath extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Nixilis"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Each opponent loses 1 life. You gain life equal to the life lost this way. this.addAbility(new LoyaltyAbility(new ObNixilisOfTheBlackOathEffect1(), 2)); @@ -113,7 +109,7 @@ class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int loseLife = 0; - for (UUID opponentId: game.getOpponents(source.getControllerId())) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); if (opponent != null) { loseLife += opponent.loseLife(1, game); @@ -134,13 +130,15 @@ class ObNixilisOfTheBlackOathEffect1 extends OneShotEffect { } class ObNixilisOfTheBlackOathEmblem extends Emblem { + // You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power." + public ObNixilisOfTheBlackOathEmblem() { this.setName("EMBLEM: Ob Nixilis of the Black Oath"); DynamicValue xValue = new SacrificeCostCreaturesPower(); Effect effect = new GainLifeEffect(xValue); effect.setText("You gain X life"); - Ability ability = new SimpleActivatedAbility(Zone.COMMAND, effect, new ManaCostsImpl("{1}{B}")); + Ability ability = new SimpleActivatedAbility(Zone.COMMAND, effect, new ManaCostsImpl("{1}{B}")); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent())); effect = new DrawCardSourceControllerEffect(xValue); effect.setText("and draw X cards, where X is the sacrificed creature's power"); diff --git a/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java b/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java index 4990384fa41..bf6477bc1ea 100644 --- a/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java +++ b/Mage.Sets/src/mage/sets/commander2014/TeferiTemporalArchmage.java @@ -31,14 +31,13 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.AsThoughEffectType; import mage.constants.CardType; @@ -46,7 +45,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.game.Game; @@ -64,7 +62,7 @@ public class TeferiTemporalArchmage extends CardImpl { this.expansionSetCode = "C14"; this.subtype.add("Teferi"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library. this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect( @@ -96,7 +94,6 @@ public class TeferiTemporalArchmage extends CardImpl { class TeferiTemporalArchmageEmblem extends Emblem { // "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant." - public TeferiTemporalArchmageEmblem() { this.setName("EMBLEM: Teferi, Temporal Archmage"); this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new TeferiTemporalArchmageAsThoughEffect())); diff --git a/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java b/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java index a195c86159a..5c3a39ffaad 100644 --- a/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java +++ b/Mage.Sets/src/mage/sets/conflux/ApocalypseHydra.java @@ -63,7 +63,8 @@ public class ApocalypseHydra extends CardImpl { this.toughness = new MageInt(0); // Apocalypse Hydra enters the battlefield with X +1/+1 counters on it. If X is 5 or more, it enters the battlefield with an additional X +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new ApocalypseHydraEffect(), true)); + this.addAbility(new EntersBattlefieldAbility(new ApocalypseHydraEffect())); + // {1}{R}, Remove a +1/+1 counter from Apocalypse Hydra: Apocalypse Hydra deals 1 damage to target creature or player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{1}{R}")); ability.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance())); @@ -94,12 +95,12 @@ class ApocalypseHydraEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { int amount = spellAbility.getManaCostsToPay().getX(); if (amount > 0) { if (amount < 5) { diff --git a/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java b/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java index 892139f72c1..07e9f18043d 100644 --- a/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java +++ b/Mage.Sets/src/mage/sets/conflux/NicolBolasPlaneswalker.java @@ -28,19 +28,17 @@ package mage.sets.conflux; import java.util.UUID; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.DestroyTargetEffect; -import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.abilities.effects.common.SacrificeEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -65,8 +63,7 @@ public class NicolBolasPlaneswalker extends CardImpl { this.expansionSetCode = "CON"; this.subtype.add("Bolas"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +3: Destroy target noncreature permanent. LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), 3); diff --git a/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java b/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java index 97809e24314..3ca79dcdde7 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java +++ b/Mage.Sets/src/mage/sets/conspiracy/AcademyElite.java @@ -103,7 +103,7 @@ class AcademyEliteEffect1 extends OneShotEffect { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { CardsInAllGraveyardsCount instantsAndSorceries = new CardsInAllGraveyardsCount(new FilterInstantOrSorceryCard("instant or sorcery cards")); int instantsAndSorceriesCount = instantsAndSorceries.calculate(game, source, this); if (instantsAndSorceriesCount > 0) { diff --git a/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java b/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java index e9d62fe6ab5..05b0faad94c 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java +++ b/Mage.Sets/src/mage/sets/conspiracy/DackFayden.java @@ -34,13 +34,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -50,7 +49,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -73,8 +71,7 @@ public class DackFayden extends CardImpl { this.expansionSetCode = "CNS"; this.subtype.add("Dack"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Target player draws two cards, then discards two cards. LoyaltyAbility ability = new LoyaltyAbility(new DrawCardTargetEffect(2), 1); @@ -83,14 +80,14 @@ public class DackFayden extends CardImpl { ability.addEffect(effect); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - + // -2: Gain control of target artifact. effect = new GainControlTargetEffect(Duration.EndOfGame, true); effect.setText("Gain control of target artifact"); ability = new LoyaltyAbility(effect, -2); ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); - + // -6: You get an emblem with "Whenever you cast a spell that targets one or more permanents, gain control of those permanents." effect = new GetEmblemEffect(new DackFaydenEmblem()); effect.setText("You get an emblem with \"Whenever you cast a spell that targets one or more permanents, gain control of those permanents.\""); @@ -109,7 +106,7 @@ public class DackFayden extends CardImpl { } class DackFaydenEmblem extends Emblem { - + DackFaydenEmblem() { this.setName("EMBLEM: Dack Fayden"); this.getAbilities().add(new DackFaydenEmblemTriggeredAbility()); @@ -117,15 +114,15 @@ class DackFaydenEmblem extends Emblem { } class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { - + DackFaydenEmblemTriggeredAbility() { super(Zone.COMMAND, new DackFaydenEmblemEffect(), false); } - + DackFaydenEmblemTriggeredAbility(final DackFaydenEmblemTriggeredAbility ability) { super(ability); } - + @Override public DackFaydenEmblemTriggeredAbility copy() { return new DackFaydenEmblemTriggeredAbility(this); @@ -135,7 +132,7 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { public boolean checkEventType(GameEvent event, Game game) { return event.getType() == EventType.SPELL_CAST; } - + @Override public boolean checkTrigger(GameEvent event, Game game) { boolean returnValue = false; @@ -175,7 +172,7 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { } return returnValue; } - + @Override public String getRule() { return "Whenever you cast a spell that targets one or more permanents, gain control of those permanents."; @@ -183,24 +180,24 @@ class DackFaydenEmblemTriggeredAbility extends TriggeredAbilityImpl { } class DackFaydenEmblemEffect extends ContinuousEffectImpl { - + protected List permanents; - + DackFaydenEmblemEffect() { super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); this.staticText = "gain control of those permanents"; } - + DackFaydenEmblemEffect(final DackFaydenEmblemEffect effect) { super(effect); this.permanents = effect.permanents; } - + @Override public DackFaydenEmblemEffect copy() { return new DackFaydenEmblemEffect(this); } - + @Override public boolean apply(Game game, Ability source) { for (UUID permanentId : this.permanents) { @@ -211,7 +208,7 @@ class DackFaydenEmblemEffect extends ContinuousEffectImpl { } return true; } - + public void setPermanents(List targettedPermanents) { this.permanents = new ArrayList<>(targettedPermanents); } diff --git a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java index 9b30e45ef2c..4fe08b08edc 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java +++ b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java @@ -30,7 +30,6 @@ package mage.sets.conspiracy; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -114,17 +113,16 @@ class ExtractFromDarknessReturnFromGraveyardToBattlefieldEffect extends OneShotE @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Target target = new TargetCardInGraveyard(new FilterCreatureCard()); target.setNotTarget(true); if (target.canChoose(source.getSourceId(), source.getControllerId(), game) - && player.chooseTarget(outcome, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); + && controller.chooseTarget(outcome, target, source, game)) { + return controller.moveCards(game.getCard(target.getFirstTarget()), Zone.BATTLEFIELD, source, game); } return true; } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java b/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java index 71a562bab0f..437601df097 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java +++ b/Mage.Sets/src/mage/sets/conspiracy/MuzzioVisionaryArchitect.java @@ -99,14 +99,14 @@ class MuzzioVisionaryArchitectEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (player == null || sourcePermanent == null) { + if (controller == null || sourcePermanent == null) { return false; } int highCMC = 0; - List controlledArtifacts = game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), player.getId(), game); + List controlledArtifacts = game.getBattlefield().getAllActivePermanents(new FilterArtifactPermanent(), controller.getId(), game); for (Permanent permanent : controlledArtifacts) { if (permanent.getSpellAbility() != null) { int cmc = permanent.getSpellAbility().getManaCosts().convertedManaCost(); @@ -119,26 +119,26 @@ class MuzzioVisionaryArchitectEffect extends OneShotEffect { Cards cards = new CardsImpl(); for (int i = 0; i < highCMC; i++) { - Card card = player.getLibrary().removeFromTop(game); + Card card = controller.getLibrary().removeFromTop(game); if (card != null) { cards.add(card); } } - player.lookAtCards(sourcePermanent.getName(), cards, game); + controller.lookAtCards(sourcePermanent.getIdName(), cards, game); if (!cards.isEmpty()) { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterArtifactCard("artifact card to put onto the battlefield")); - if (target.canChoose(source.getSourceId(), player.getId(), game) && player.choose(Outcome.Benefit, cards, target, game)) { + if (target.canChoose(source.getSourceId(), controller.getId(), game) && controller.choose(Outcome.Benefit, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { - player.revealCards(sourcePermanent.getName(), new CardsImpl(card), game); + controller.revealCards(sourcePermanent.getIdName(), new CardsImpl(card), game); cards.remove(card); - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } } - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java b/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java index d351fa80033..f5a89e1c6dc 100644 --- a/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java +++ b/Mage.Sets/src/mage/sets/darkascension/SorinLordOfInnistrad.java @@ -27,25 +27,24 @@ */ package mage.sets.darkascension; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.LifelinkAbility; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -56,8 +55,6 @@ import mage.game.permanent.token.Token; import mage.players.Player; import mage.target.TargetPermanent; -import java.util.UUID; - /** * * @author BetaSteward @@ -77,8 +74,7 @@ public class SorinLordOfInnistrad extends CardImpl { this.expansionSetCode = "DKA"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Put a 1/1 black Vampire creature token with lifelink onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new VampireToken()), 1)); @@ -103,6 +99,7 @@ public class SorinLordOfInnistrad extends CardImpl { } class VampireToken extends Token { + VampireToken() { super("Vampire", "a 1/1 black Vampire creature token with lifelink"); cardType.add(CardType.CREATURE); @@ -142,7 +139,7 @@ class SorinLordOfInnistradEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (UUID targetId: source.getTargets().get(0).getTargets()) { + for (UUID targetId : source.getTargets().get(0).getTargets()) { Permanent perm = game.getPermanent(targetId); if (perm != null) { perm.destroy(source.getSourceId(), game, false); @@ -150,7 +147,7 @@ class SorinLordOfInnistradEffect extends OneShotEffect { } Player player = game.getPlayer(source.getControllerId()); if (player != null) { - for (UUID targetId: source.getTargets().get(0).getTargets()) { + for (UUID targetId : source.getTargets().get(0).getTargets()) { if (game.getState().getZone(targetId) == Zone.GRAVEYARD) { Card card = game.getCard(targetId); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java index baa5d24d1c4..8c1332a991b 100644 --- a/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java +++ b/Mage.Sets/src/mage/sets/darksteel/AEtherVial.java @@ -28,11 +28,6 @@ package mage.sets.darksteel; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.TargetController; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; @@ -41,6 +36,11 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.common.FilterCreatureCard; @@ -107,18 +107,20 @@ class AEtherVialEffect extends OneShotEffect { filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, count)); String choiceText = "Put a " + filter.getMessage() + " from your hand onto the battlefield?"; - Player player = game.getPlayer(source.getControllerId()); - if (player == null || player.getHand().count(filter, game) == 0 - || !player.chooseUse(this.outcome, choiceText, source, game)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } + if (controller.getHand().count(filter, game) == 0 + || !controller.chooseUse(this.outcome, choiceText, source, game)) { + return true; + } TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(this.outcome, target, source.getSourceId(), game)) { + if (controller.choose(this.outcome, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - return true; + return controller.moveCards(card, Zone.BATTLEFIELD, source, game); } } return false; diff --git a/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java b/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java index 4a7804b3443..064145d1981 100644 --- a/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java +++ b/Mage.Sets/src/mage/sets/dissension/ProteanHulk.java @@ -78,47 +78,42 @@ public class ProteanHulk extends CardImpl { } class ProteanHulkEffect extends OneShotEffect { - + ProteanHulkEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "search your library for any number of creature cards with total converted mana cost 6 or less and put them onto the battlefield. Then shuffle your library"; } - + ProteanHulkEffect(final ProteanHulkEffect effect) { super(effect); } - + @Override public ProteanHulkEffect copy() { return new ProteanHulkEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { Cards cardsPicked = this.ProteanHulkSearch(game, source); - for (UUID cardId : cardsPicked) { - Card card = game.getCard(cardId); - if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.PICK, source.getSourceId()); - } - } - player.shuffleLibrary(game); + controller.moveCards(cardsPicked.getCards(game), Zone.BATTLEFIELD, source, game); + controller.shuffleLibrary(game); return true; } return false; } - + Cards ProteanHulkSearch(Game game, Ability source) { - Cards cardsPicked = new CardsImpl(Zone.PICK); + Cards cardsPicked = new CardsImpl(Zone.LIBRARY); Player player = game.getPlayer(source.getControllerId()); if (player != null) { GameEvent event = GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, source.getControllerId(), source.getControllerId(), source.getControllerId(), Integer.MAX_VALUE); if (!game.replaceEvent(event)) { int manaCostLeftToFetch = 6; int librarySearchLimit = event.getAmount(); - + FilterCard filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (6 CMC left)"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); @@ -131,15 +126,14 @@ class ProteanHulkEffect extends OneShotEffect { break; } cardsPicked.add(card); - game.setZone(card.getId(), Zone.PICK); game.getState().getLookedAt(source.getControllerId()).add("Protean Hulk", cardsPicked); - + librarySearchLimit--; if (librarySearchLimit == 0) { break; } manaCostLeftToFetch -= card.getManaCost().convertedManaCost(); - filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less ("+ manaCostLeftToFetch +" CMC left)"); + filter = new FilterCreatureCard("number of creature cards with total converted mana cost 6 or less (" + manaCostLeftToFetch + " CMC left)"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, manaCostLeftToFetch + 1)); target = new TargetCardInLibrary(0, 1, filter); target.setCardLimit(librarySearchLimit); diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java b/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java index 45ce77a9176..d79ba674371 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/BeckCall.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.dragonsmaze; import java.util.UUID; @@ -39,13 +38,11 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; -import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.permanent.token.BirdToken; - - public class BeckCall extends SplitCard { public BeckCall(UUID ownerId) { @@ -58,7 +55,7 @@ public class BeckCall extends SplitCard { // Call // Put four 1/1 white Bird creature tokens with flying onto the battlefield. - getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new BirdToken(),4)); + getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new BirdToken(), 4)); } @@ -94,10 +91,7 @@ class BeckTriggeredAbility extends DelayedTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { UUID targetId = event.getTargetId(); Permanent permanent = game.getPermanent(targetId); - if (filter.match(permanent, getSourceId(), getControllerId(), game)) { - return true; - } - return false; + return filter.match(permanent, getSourceId(), getControllerId(), game); } @Override diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java index 0553d75993b..9df44c4d7df 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/ProgenitorMimic.java @@ -30,18 +30,16 @@ package mage.sets.dragonsmaze; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.TokenPredicate; @@ -72,17 +70,16 @@ public class ProgenitorMimic extends CardImpl { // put a token onto the battlefield that's a copy of this creature." Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); effect.setText("put a token onto the battlefield that's a copy of this creature"); + AbilityApplier applier = new AbilityApplier( new ConditionalTriggeredAbility( new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, false), new SourceMatchesFilterCondition(filter), "At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.") ); - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(applier), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains \"At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.\"", - true))); + effect = new CopyPermanentEffect(); + effect.setText("as a copy of any creature on the battlefield except it gains \"At the beginning of your upkeep, if this creature isn't a token, put a token onto the battlefield that's a copy of this creature.\""); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(applier), true)); } public ProgenitorMimic(final ProgenitorMimic card) { diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java b/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java index 829bc093bde..121946e99aa 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/RalZarek.java @@ -28,17 +28,15 @@ package mage.sets.dragonsmaze; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -58,8 +56,7 @@ public class RalZarek extends CardImpl { this.expansionSetCode = "DGM"; this.subtype.add("Ral"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Tap target permanent, then untap another target permanent. LoyaltyAbility ability1 = new LoyaltyAbility(new RalZarekTapUntapEffect(), 1); @@ -86,7 +83,6 @@ public class RalZarek extends CardImpl { } } - class RalZarekTapUntapEffect extends OneShotEffect { public RalZarekTapUntapEffect() { @@ -112,10 +108,10 @@ class RalZarekTapUntapEffect extends OneShotEffect { i++; Permanent permanent = game.getPermanent(targetId); if (permanent != null) { - if (i==1) { + if (i == 1) { permanent.tap(game); } - if (i==2) { + if (i == 2) { permanent.untap(game); } } @@ -146,7 +142,7 @@ class RalZarekExtraTurnsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (int i=0; i<5; i++) { + for (int i = 0; i < 5; i++) { if (controller.flipCoin(game)) { game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false)); } diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java index 639d3f36c38..3873609cb39 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/NarsetTranscendent.java @@ -32,7 +32,7 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; @@ -40,7 +40,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.ReboundAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -52,7 +51,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.events.GameEvent; @@ -71,7 +69,7 @@ public class NarsetTranscendent extends CardImpl { this.expansionSetCode = "DTK"; this.subtype.add("Narset"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); // +1: Look at the top card of your library. If it's a noncreature, nonland card, you may reveal it and put it into your hand. this.addAbility(new LoyaltyAbility(new NarsetTranscendentEffect1(), 1)); diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java index 095e054558d..ccd28a1c476 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/SarkhanUnbroken.java @@ -33,10 +33,9 @@ import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.choices.Choice; @@ -44,7 +43,6 @@ import mage.choices.ChoiceImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; @@ -69,7 +67,7 @@ public class SarkhanUnbroken extends CardImpl { this.expansionSetCode = "DTK"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Draw a card, then add one mana of any color to your mana pool. this.addAbility(new LoyaltyAbility(new SarkhanUnbrokenAbility1(), 1)); @@ -127,7 +125,7 @@ class SarkhanUnbrokenAbility1 extends OneShotEffect { Mana mana = new Mana(); controller.choose(Outcome.Benefit, manaChoice, game); - + if (manaChoice.getChoice() == null) { return false; } diff --git a/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java b/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java index 812f571064a..3af4a21d774 100644 --- a/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java +++ b/Mage.Sets/src/mage/sets/eventide/CankerAbomination.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -95,7 +94,7 @@ class CankerAbominationEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent cankerAbomination = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent cankerAbomination = game.getPermanentEntering(source.getSourceId()); if (controller != null && cankerAbomination != null) { Target target = new TargetOpponent(); target.setNotTarget(true); diff --git a/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java b/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java index 8914495c7f5..01b26cd052d 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/CitadelSiege.java @@ -61,7 +61,7 @@ public class CitadelSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Citadel Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, "As {this} enters the battlefield, choose Khans or Dragons.","")); // * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control. diff --git a/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java b/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java index 9de1b018b1e..008f8a3c2c4 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java +++ b/Mage.Sets/src/mage/sets/fatereforged/FrontierMastodon.java @@ -53,7 +53,7 @@ public class FrontierMastodon extends CardImpl { // Ferocious - Frontier Mastodon enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - FerociousCondition.getInstance(), true, + FerociousCondition.getInstance(), "Ferocious — {this} enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater.","" )); } diff --git a/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java b/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java index f02ca1e3c0b..1a98c5c215c 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/FrontierSiege.java @@ -76,7 +76,7 @@ public class FrontierSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Frontier Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of each of your main phases, add {G}{G} to your mana pool. diff --git a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java index 799cfbb802d..9753a5cf199 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MonasterySiege.java @@ -62,7 +62,7 @@ public class MonasterySiege extends CardImpl { this.expansionSetCode = "FRF"; // As Monastery Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of your draw step, draw an additional card, then discard a card. diff --git a/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java b/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java index a2598cdb69a..4ee0f6accad 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/OutpostSiege.java @@ -69,7 +69,7 @@ public class OutpostSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Outpost Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?", "Khans", "Dragons"), null, "As {this} enters the battlefield, choose Khans or Dragons.", "")); // * Khans - At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card. diff --git a/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java b/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java index 3b153f3e251..d23bb16257a 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java +++ b/Mage.Sets/src/mage/sets/fatereforged/PalaceSiege.java @@ -59,7 +59,7 @@ public class PalaceSiege extends CardImpl { this.expansionSetCode = "FRF"; // As Palace Siege enters the battlefield, choose Khans or Dragons. - this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true, + this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, "As {this} enters the battlefield, choose Khans or Dragons.","")); // * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand. diff --git a/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java b/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java index 90ffdb0ca48..2ebf0e1caa3 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java +++ b/Mage.Sets/src/mage/sets/fatereforged/UginTheSpiritDragon.java @@ -30,19 +30,17 @@ package mage.sets.fatereforged; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter.ComparisonType; import mage.filter.FilterPermanent; import mage.filter.common.FilterPermanentCard; @@ -59,7 +57,6 @@ import mage.target.common.TargetCreatureOrPlayer; * * @author LevelX2 */ - public class UginTheSpiritDragon extends CardImpl { public UginTheSpiritDragon(UUID ownerId) { @@ -67,7 +64,7 @@ public class UginTheSpiritDragon extends CardImpl { this.expansionSetCode = "FRF"; this.subtype.add("Ugin"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(7)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(7)); // +2: Ugin, the Spirit Dragon deals 3 damage to target creature or player. LoyaltyAbility ability = new LoyaltyAbility(new DamageTargetEffect(3), 2); @@ -126,7 +123,7 @@ class UginTheSpiritDragonEffect2 extends OneShotEffect { FilterPermanent filter = new FilterPermanent("permanent with converted mana cost X or less that's one or more colors"); filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, cmc + 1)); filter.add(Predicates.not(new ColorlessPredicate())); - for(Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { controller.moveCardToExileWithInfo(permanent, null, "", source.getSourceId(), game, Zone.BATTLEFIELD, true); } return true; @@ -157,7 +154,7 @@ class UginTheSpiritDragonEffect3 extends OneShotEffect { controller.drawCards(7, game); TargetCardInHand target = new TargetCardInHand(0, 7, new FilterPermanentCard("permanent cards")); if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { - for (UUID targetId: target.getTargets()) { + for (UUID targetId : target.getTargets()) { Card card = game.getCard(targetId); if (card != null) { controller.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getControllerId()); diff --git a/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java b/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java index 2ed36891b4a..bae08d67839 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/Acquire.java @@ -1,5 +1,6 @@ package mage.sets.fifthdawn; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -15,17 +16,15 @@ import mage.players.Player; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * @author andyfries */ -public class Acquire extends CardImpl{ +public class Acquire extends CardImpl { + public Acquire(UUID ownerId) { super(ownerId, 21, "Acquire", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{3}{U}{U}"); this.expansionSetCode = "5DN"; - // Search target opponent's library for an artifact card and put that card onto the battlefield under your control. // Then that player shuffles his or her library. this.getSpellAbility().addEffect(new AcquireEffect()); @@ -68,7 +67,7 @@ class AcquireEffect extends OneShotEffect { controller.searchLibrary(target, game, opponent.getId()); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - controller.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); } opponent.shuffleLibrary(game); return true; @@ -81,4 +80,3 @@ class AcquireEffect extends OneShotEffect { return new AcquireEffect(this); } } - diff --git a/Mage.Sets/src/mage/sets/fifthedition/Kismet.java b/Mage.Sets/src/mage/sets/fifthedition/Kismet.java index 9e327b22775..673526b4b61 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/Kismet.java +++ b/Mage.Sets/src/mage/sets/fifthedition/Kismet.java @@ -79,26 +79,25 @@ class KismetEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } return false; } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && (permanent.getCardType().contains(CardType.ARTIFACT) || - permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND))) { + if (permanent != null && (permanent.getCardType().contains(CardType.ARTIFACT) + || permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java index 561def505a0..998dd517b31 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java +++ b/Mage.Sets/src/mage/sets/fifthedition/PrimalClay.java @@ -65,7 +65,7 @@ public class PrimalClay extends CardImpl { this.toughness = new MageInt(0); // As Primal Clay enters the battlefield, it becomes your choice of a 3/3 artifact creature, a 2/2 artifact creature with flying, or a 1/6 Wall artifact creature with defender in addition to its other types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalPlasmaReplacementEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new PrimalPlasmaReplacementEffect())); } public PrimalClay(final PrimalClay card) { @@ -101,7 +101,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(event.getTargetId()); if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -116,7 +116,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what " + permanent.getIdName() + " becomes to"); diff --git a/Mage.Sets/src/mage/sets/futuresight/CloudKey.java b/Mage.Sets/src/mage/sets/futuresight/CloudKey.java index 33e946d9393..b357c8b83f1 100644 --- a/Mage.Sets/src/mage/sets/futuresight/CloudKey.java +++ b/Mage.Sets/src/mage/sets/futuresight/CloudKey.java @@ -11,7 +11,6 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.cards.Card; @@ -75,7 +74,7 @@ class CloudKeyChooseTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java b/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java index deca054ff68..c9055368a95 100644 --- a/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java +++ b/Mage.Sets/src/mage/sets/futuresight/KavuPrimarch.java @@ -61,7 +61,7 @@ public class KavuPrimarch extends CardImpl { // If Kavu Primarch was kicked, it enters the battlefield with four +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),KickedCondition.getInstance(), true, + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),KickedCondition.getInstance(), "If Kavu Primarch was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); } diff --git a/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java b/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java index 30c9a66fcf0..a1f6e59f044 100644 --- a/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java +++ b/Mage.Sets/src/mage/sets/futuresight/RavagingRiftwurm.java @@ -64,7 +64,7 @@ public class RavagingRiftwurm extends CardImpl { this.addAbility(new VanishingSacrificeAbility()); // If Ravaging Riftwurm was kicked, it enters the battlefield with three additional time counters on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.TIME.createInstance(3)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with three additional time counters on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with three additional time counters on it.", "")); } public RavagingRiftwurm(final RavagingRiftwurm card) { diff --git a/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java b/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java index 5167e1c6d68..27985e968f3 100644 --- a/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java +++ b/Mage.Sets/src/mage/sets/gameday/ScaleguardSentinels.java @@ -73,7 +73,7 @@ public class ScaleguardSentinels extends CardImpl { // Scaleguard Sentinels enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast Scaleguard Sentinels. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), - ScaleguardSentinelsCondition.getInstance(), true, + ScaleguardSentinelsCondition.getInstance(), "{this} enters the battlefield with a +1/+1 counter on it if you revealed a Dragon card or controlled a Dragon as you cast {this}", ""), new DragonOnTheBattlefieldWhileSpellWasCastWatcher()); diff --git a/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java b/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java index 3bc36d45269..537b7304668 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java +++ b/Mage.Sets/src/mage/sets/gatecrash/BlindObedience.java @@ -28,16 +28,16 @@ package mage.sets.gatecrash; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.ExtortAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -52,7 +52,6 @@ public class BlindObedience extends CardImpl { super(ownerId, 6, "Blind Obedience", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); this.expansionSetCode = "GTC"; - // Extort (Whenever you cast a spell, you may pay {WB}. If you do, each opponent loses 1 life and you gain that much life.) this.addAbility(new ExtortAbility()); @@ -72,6 +71,7 @@ public class BlindObedience extends CardImpl { } class BlindObedienceTapEffect extends ReplacementEffectImpl { + BlindObedienceTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts and creatures your opponents control enter the battlefield tapped"; @@ -83,22 +83,22 @@ class BlindObedienceTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null && (permanent.getCardType().contains(CardType.CREATURE) || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } diff --git a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java index 0d92cdf0bac..cf84a981cc3 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java +++ b/Mage.Sets/src/mage/sets/gatecrash/DomriRade.java @@ -31,13 +31,12 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.FightTargetsEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.HexproofAbility; @@ -50,7 +49,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; @@ -70,7 +68,7 @@ public class DomriRade extends CardImpl { this.expansionSetCode = "GTC"; this.subtype.add("Domri"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Look at the top card of your library. If it's a creature card, you may reveal it and put it into your hand. this.addAbility(new LoyaltyAbility(new DomriRadeEffect1(), 1)); @@ -138,7 +136,6 @@ class DomriRadeEffect1 extends OneShotEffect { class DomriRadeEmblem extends Emblem { // "Creatures you control have double strike, trample, hexproof and haste." - public DomriRadeEmblem() { this.setName("EMBLEM: Domri Rade"); FilterPermanent filter = new FilterControlledCreaturePermanent("Creatures"); diff --git a/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java b/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java index 67f67d0d830..5f125a6fec3 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java +++ b/Mage.Sets/src/mage/sets/gatecrash/FathomMage.java @@ -1,5 +1,5 @@ /* -/* + /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are @@ -60,7 +60,7 @@ public class FathomMage extends CardImpl { // Evolve (Whenever a creature enters the battlefield under your control, if that creature // has greater power or toughness than this creature, put a +1/+1 counter on this creature.) this.addAbility(new EvolveAbility()); - + //Whenever a +1/+1 counter is placed on Fathom Mage, you may draw a card. this.addAbility(new FathomMageTriggeredAbility()); } @@ -75,11 +75,10 @@ public class FathomMage extends CardImpl { } } - class FathomMageTriggeredAbility extends TriggeredAbilityImpl { public FathomMageTriggeredAbility() { - super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), true); + super(Zone.ALL, new DrawCardSourceControllerEffect(1), true); } public FathomMageTriggeredAbility(FathomMageTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java index 60ce90daeed..9467a3ccfcc 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java +++ b/Mage.Sets/src/mage/sets/gatecrash/GideonChampionOfJustice.java @@ -27,10 +27,11 @@ */ package mage.sets.gatecrash; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.common.CountersCount; import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount; @@ -41,7 +42,11 @@ import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -49,8 +54,6 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.Token; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author LevelX2 @@ -62,7 +65,7 @@ public class GideonChampionOfJustice extends CardImpl { this.expansionSetCode = "GTC"; this.subtype.add("Gideon"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a loyalty counter on Gideon, Champion of Justice for each creature target opponent controls. LoyaltyAbility ability1 = new LoyaltyAbility( diff --git a/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java b/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java index eeb0b6346dd..0052145c333 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java +++ b/Mage.Sets/src/mage/sets/gatecrash/MasterBiomancer.java @@ -1,30 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.sets.gatecrash; import java.util.UUID; @@ -48,31 +48,31 @@ import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** -* -* @author LevelX2 -*/ + * + * @author LevelX2 + */ public class MasterBiomancer extends CardImpl { public MasterBiomancer(UUID ownerId) { - super(ownerId, 176, "Master Biomancer", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); - this.expansionSetCode = "GTC"; - this.subtype.add("Elf"); - this.subtype.add("Wizard"); + super(ownerId, 176, "Master Biomancer", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); + this.expansionSetCode = "GTC"; + this.subtype.add("Elf"); + this.subtype.add("Wizard"); - this.power = new MageInt(2); - this.toughness = new MageInt(4); + this.power = new MageInt(2); + this.toughness = new MageInt(4); - // Each other creature you control enters the battlefield with a number of additional +1/+1 counters on it equal to Master Biomancer's power and as a Mutant in addition to its other types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MasterBiomancerEntersBattlefieldEffect())); + // Each other creature you control enters the battlefield with a number of additional +1/+1 counters on it equal to Master Biomancer's power and as a Mutant in addition to its other types. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MasterBiomancerEntersBattlefieldEffect())); } public MasterBiomancer(final MasterBiomancer card) { - super(card); + super(card); } @Override public MasterBiomancer copy() { - return new MasterBiomancer(this); + return new MasterBiomancer(this); } } @@ -86,16 +86,16 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { public MasterBiomancerEntersBattlefieldEffect(MasterBiomancerEntersBattlefieldEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = game.getPermanentEntering(event.getTargetId()); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && !event.getTargetId().equals(source.getSourceId()); } @@ -103,7 +103,7 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Permanent sourceCreature = game.getPermanent(source.getSourceId()); - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (sourceCreature != null && creature != null) { int power = sourceCreature.getPower().getValue(); if (power > 0) { @@ -116,7 +116,6 @@ class MasterBiomancerEntersBattlefieldEffect extends ReplacementEffectImpl { return false; } - @Override public MasterBiomancerEntersBattlefieldEffect copy() { return new MasterBiomancerEntersBattlefieldEffect(this); diff --git a/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java b/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java index 48c906b6fec..cf831b2939c 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java +++ b/Mage.Sets/src/mage/sets/gatecrash/ZameckGuildmage.java @@ -28,29 +28,24 @@ package mage.sets.gatecrash; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.RemoveCounterCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.Effects; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.targetpointer.FixedTarget; /** * @@ -58,8 +53,6 @@ import mage.target.targetpointer.FixedTarget; */ public class ZameckGuildmage extends CardImpl { - private static final String ruleText = "This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it"; - public ZameckGuildmage(UUID ownerId) { super(ownerId, 209, "Zameck Guildmage", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{G}{U}"); this.expansionSetCode = "GTC"; @@ -69,9 +62,8 @@ public class ZameckGuildmage extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - // {G}{U}: This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), ruleText), new ManaCostsImpl("{G}{U}"))); + this.addAbility(new SimpleActivatedAbility(Zone.ALL, new ZameckGuildmageEntersBattlefieldEffect(), new ManaCostsImpl("{G}{U}"))); // {G}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{G}{U}")); @@ -89,25 +81,15 @@ public class ZameckGuildmage extends CardImpl { } } -class EntersBattlefieldEffect extends ReplacementEffectImpl { +class ZameckGuildmageEntersBattlefieldEffect extends ReplacementEffectImpl { - protected Effects baseEffects = new Effects(); - protected String text; - - public EntersBattlefieldEffect(Effect baseEffect, String text) { - super(Duration.EndOfTurn, baseEffect.getOutcome()); - this.baseEffects.add(baseEffect); - this.text = text; + public ZameckGuildmageEntersBattlefieldEffect() { + super(Duration.EndOfTurn, Outcome.BoostCreature); + this.staticText = "This turn, each creature you control enters the battlefield with an additional +1/+1 counter on it"; } - public EntersBattlefieldEffect(EntersBattlefieldEffect effect) { + public ZameckGuildmageEntersBattlefieldEffect(ZameckGuildmageEntersBattlefieldEffect effect) { super(effect); - this.baseEffects = effect.baseEffects.copy(); - this.text = effect.text; - } - - public void addEffect(Effect effect) { - baseEffects.add(effect); } @Override @@ -117,11 +99,8 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) { - return true; - } - return false; + Permanent permanent = game.getPermanentEntering(event.getTargetId()); + return permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE); } @Override @@ -131,23 +110,15 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - for (Effect effect: baseEffects) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null) { - effect.setTargetPointer(new FixedTarget(target.getId())); - effect.apply(game, source); - } + Permanent target = game.getPermanentEntering(event.getTargetId()); + if (target != null) { + target.addCounters(CounterType.P1P1.createInstance(), game); } return false; } @Override - public String getText(Mode mode) { - return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text; - } - - @Override - public EntersBattlefieldEffect copy() { - return new EntersBattlefieldEffect(this); + public ZameckGuildmageEntersBattlefieldEffect copy() { + return new ZameckGuildmageEntersBattlefieldEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java index 4a1345a52c9..71d69e1ebc2 100644 --- a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java +++ b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java @@ -27,39 +27,29 @@ */ package mage.sets.innistrad; - -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.Effect; -import mage.abilities.effects.Effects; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; -import mage.game.stack.Spell; -import mage.target.targetpointer.FixedTarget; - -import java.util.UUID; import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; /** * @author nantuko */ public class DearlyDeparted extends CardImpl { - private static final String ruleText = "As long as {this} is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it"; - public DearlyDeparted(UUID ownerId) { super(ownerId, 9, "Dearly Departed", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{W}{W}"); this.expansionSetCode = "ISD"; @@ -71,8 +61,7 @@ public class DearlyDeparted extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // As long as Dearly Departed is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it. - this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, - new EntersBattlefieldEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), ruleText))); + this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD, new DearlyDepartedEntersBattlefieldEffect())); } public DearlyDeparted(final DearlyDeparted card) { @@ -85,43 +74,26 @@ public class DearlyDeparted extends CardImpl { } } -class EntersBattlefieldEffect extends ReplacementEffectImpl { +class DearlyDepartedEntersBattlefieldEffect extends ReplacementEffectImpl { - protected Effects baseEffects = new Effects(); - protected String text; - - public static final String SOURCE_CAST_SPELL_ABILITY = "sourceCastSpellAbility"; - - public EntersBattlefieldEffect(Effect baseEffect) { - this(baseEffect, ""); + public DearlyDepartedEntersBattlefieldEffect() { + super(Duration.OneUse, Outcome.BoostCreature); + staticText = "As long as {this} is in your graveyard, each Human creature you control enters the battlefield with an additional +1/+1 counter on it"; } - public EntersBattlefieldEffect(Effect baseEffect, String text) { - super(Duration.OneUse, baseEffect.getOutcome()); - this.baseEffects.add(baseEffect); - this.text = text; - } - - public EntersBattlefieldEffect(EntersBattlefieldEffect effect) { + public DearlyDepartedEntersBattlefieldEffect(DearlyDepartedEntersBattlefieldEffect effect) { super(effect); - this.baseEffects = effect.baseEffects.copy(); - this.text = effect.text; } - public void addEffect(Effect effect) { - baseEffects.add(effect); - } - @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) && permanent.hasSubtype("Human")) { - setValue("target", permanent); return true; } return false; @@ -129,33 +101,16 @@ class EntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Spell spell = game.getStack().getSpell(event.getSourceId()); - for (Effect effect: baseEffects) { - Object target = getValue("target"); - if (target != null && target instanceof Permanent) { - effect.setTargetPointer(new FixedTarget(((Permanent)target).getId())); - if (effect instanceof ContinuousEffect) { - game.addEffect((ContinuousEffect) effect, source); - } - else { - if (spell != null) { - effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); - } - effect.apply(game, source); - } - } + Permanent target = game.getPermanentEntering(event.getTargetId()); + if (target != null) { + target.addCounters(CounterType.P1P1.createInstance(), game); } return false; } @Override - public String getText(Mode mode) { - return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text; - } - - @Override - public EntersBattlefieldEffect copy() { - return new EntersBattlefieldEffect(this); + public DearlyDepartedEntersBattlefieldEffect copy() { + return new DearlyDepartedEntersBattlefieldEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java b/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java index 657f77a94c3..1e5aebd4ea2 100644 --- a/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java +++ b/Mage.Sets/src/mage/sets/innistrad/EssenceOfTheWild.java @@ -28,19 +28,17 @@ package mage.sets.innistrad; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.CopyEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -89,21 +87,18 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent perm = game.getPermanent(event.getTargetId()); + Permanent perm = game.getPermanentEntering(event.getTargetId()); return perm != null && perm.getCardType().contains(CardType.CREATURE) && perm.getControllerId().equals(source.getControllerId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent perm = game.getPermanent(source.getSourceId()); - if (perm != null) { - perm = perm.copy(); - perm.reset(game); - perm.assignNewId(); - game.addEffect(new EssenceOfTheWildCopyEffect(perm, event.getTargetId()), source); + Permanent sourceObject = game.getPermanent(source.getSourceId()); + if (sourceObject != null) { + game.addEffect(new CopyEffect(Duration.Custom, sourceObject, event.getTargetId()), source); } return false; } @@ -114,59 +109,3 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl { } } - -class EssenceOfTheWildCopyEffect extends ContinuousEffectImpl { - - private final Permanent essence; - private final UUID targetId; - - public EssenceOfTheWildCopyEffect(Permanent essence, UUID targetId) { - super(Duration.EndOfGame, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); - this.essence = essence; - this.targetId = targetId; - } - - public EssenceOfTheWildCopyEffect(final EssenceOfTheWildCopyEffect effect) { - super(effect); - this.essence = effect.essence.copy(); - this.targetId = effect.targetId; - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(targetId); - if (permanent != null) { - permanent.setName(essence.getName()); - permanent.getColor(game).setColor(essence.getColor(game)); - permanent.getManaCost().clear(); - permanent.getManaCost().add(essence.getManaCost()); - permanent.getCardType().clear(); - for (CardType type: essence.getCardType()) { - permanent.getCardType().add(type); - } - permanent.getSubtype().clear(); - for (String type: essence.getSubtype()) { - permanent.getSubtype().add(type); - } - permanent.getSupertype().clear(); - for (String type: essence.getSupertype()) { - permanent.getSupertype().add(type); - } - permanent.getAbilities().clear(); - for (Ability ability: essence.getAbilities()) { - permanent.addAbility(ability, game); - } - permanent.getPower().setValue(essence.getPower().getValue()); - permanent.getToughness().setValue(essence.getToughness().getValue()); - - return true; - } - return false; - } - - @Override - public EssenceOfTheWildCopyEffect copy() { - return new EssenceOfTheWildCopyEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java b/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java index 3cf16f8fbe3..62ec36b5d7e 100644 --- a/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java +++ b/Mage.Sets/src/mage/sets/innistrad/EvilTwin.java @@ -31,11 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; @@ -65,11 +65,10 @@ public class EvilTwin extends CardImpl { this.toughness = new MageInt(0); // You may have Evil Twin enter the battlefield as a copy of any creature on the battlefield except it gains "{U}{B}, {T}: Destroy target creature with the same name as this creature." - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new EvilTwinApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains \"{U}{B}, {T}: Destroy target creature with the same name as this creature\"", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new EvilTwinApplyToPermanent()); + effect.setText("a copy of any creature on the battlefield except it gains \"{U}{B}, {T}: Destroy target creature with the same name as this creature.\""); + this.addAbility(new EntersBattlefieldAbility(effect, true)); + } public EvilTwin(final EvilTwin card) { diff --git a/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java b/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java index 3d3e258a14b..1f43014bc50 100644 --- a/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java +++ b/Mage.Sets/src/mage/sets/innistrad/GarrukRelentless.java @@ -31,11 +31,10 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.TransformSourceEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -60,11 +59,10 @@ public class GarrukRelentless extends CardImpl { this.expansionSetCode = "ISD"; this.subtype.add("Garruk"); - this.canTransform = true; this.secondSideCard = new GarrukTheVeilCursed(ownerId); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // When Garruk Relentless has two or fewer loyalty counters on him, transform him. this.addAbility(new TransformAbility()); @@ -160,4 +158,4 @@ class GarrukRelentlessDamageEffect extends OneShotEffect { return new GarrukRelentlessDamageEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java index d20fc714ff0..0fea92be5d7 100644 --- a/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java +++ b/Mage.Sets/src/mage/sets/innistrad/LilianaOfTheVeil.java @@ -27,18 +27,19 @@ */ package mage.sets.innistrad; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; -import mage.abilities.effects.common.SacrificeEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; @@ -47,10 +48,6 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - /** * * @author North @@ -62,17 +59,16 @@ public class LilianaOfTheVeil extends CardImpl { this.expansionSetCode = "ISD"; this.subtype.add("Liliana"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Each player discards a card. this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(), 1)); - + // -2: Target player sacrifices a creature. LoyaltyAbility ability = new LoyaltyAbility(new SacrificeEffect(new FilterCreaturePermanent(), 1, "Target player"), -2); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - + // -6: Separate all permanents target player controls into two piles. That player sacrifices all permanents in the pile of his or her choice. ability = new LoyaltyAbility(new LilianaOfTheVeilEffect(), -6); ability.addTarget(new TargetPlayer()); @@ -124,7 +120,7 @@ class LilianaOfTheVeilEffect extends OneShotEffect { } } List pile2 = new ArrayList<>(); - for (Permanent p: game.getBattlefield().getAllActivePermanents(targetPlayer.getId())) { + for (Permanent p : game.getBattlefield().getAllActivePermanents(targetPlayer.getId())) { if (!pile1.contains(p)) { pile2.add(p); } diff --git a/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java index 92799396ef5..db8e522dc02 100644 --- a/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java +++ b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java @@ -53,7 +53,7 @@ public class AlloyGolem extends CardImpl { // As Alloy Golem enters the battlefield, choose a color. // Alloy Golem is the chosen color. this.addAbility(new EntersBattlefieldAbility(new BecomesColorSourceEffect(Duration.WhileOnBattlefield), - null, true, "As {this} enters the battlefield, choose a color.\n{this} is the chosen color.", "")); + null, "As {this} enters the battlefield, choose a color.\n{this} is the chosen color.", "")); } public AlloyGolem(final AlloyGolem card) { diff --git a/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java index 8fb23c7cc30..eee53175131 100644 --- a/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java +++ b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java @@ -60,7 +60,7 @@ public class ArdentSoldier extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // If Ardent Soldier was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); } public ArdentSoldier(final ArdentSoldier card) { diff --git a/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java b/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java index 7fc7d46ab01..cb7bb39c3d8 100644 --- a/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java +++ b/Mage.Sets/src/mage/sets/invasion/BenalishLancer.java @@ -61,7 +61,7 @@ public class BenalishLancer extends CardImpl { // If Benalish Lancer was kicked, it enters the battlefield with two +1/+1 counters on it and with first strike. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with first strike.", ""); ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/Duskwalker.java b/Mage.Sets/src/mage/sets/invasion/Duskwalker.java index fecf398f9ba..23923ab9284 100644 --- a/Mage.Sets/src/mage/sets/invasion/Duskwalker.java +++ b/Mage.Sets/src/mage/sets/invasion/Duskwalker.java @@ -61,7 +61,7 @@ public class Duskwalker extends CardImpl { // If Duskwalker was kicked, it enters the battlefield with two +1/+1 counters on it and with fear. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with fear.", ""); ability.addEffect(new GainAbilitySourceEffect(FearAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java index d463f15af2e..4d36fabfd90 100644 --- a/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java +++ b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java @@ -61,7 +61,7 @@ public class FaerieSquadron extends CardImpl { this.addAbility(new KickerAbility("{3}{U}")); // If Faerie Squadron was kicked, it enters the battlefield with two +1/+1 counters on it and with flying. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with flying.", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with flying.", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java index b0ce21efa99..9b0aaa5aac9 100644 --- a/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java +++ b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java @@ -59,7 +59,7 @@ public class KavuAggressor extends CardImpl { this.addAbility(new CantBlockAbility()); // If Kavu Aggressor was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); } public KavuAggressor(final KavuAggressor card) { diff --git a/Mage.Sets/src/mage/sets/invasion/KavuTitan.java b/Mage.Sets/src/mage/sets/invasion/KavuTitan.java index 84a39593671..ed1da4b825d 100644 --- a/Mage.Sets/src/mage/sets/invasion/KavuTitan.java +++ b/Mage.Sets/src/mage/sets/invasion/KavuTitan.java @@ -60,7 +60,7 @@ public class KavuTitan extends CardImpl { this.addAbility(new KickerAbility("{2}{G}")); // If Kavu Titan was kicked, it enters the battlefield with three +1/+1 counters on it and with trample. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), - KickedCondition.getInstance(), true, + KickedCondition.getInstance(), "If Kavu Titan was kicked, it enters the battlefield with three +1/+1 counters on it and with trample.", ""); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java b/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java index 966430d562d..3793017ef35 100644 --- a/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java +++ b/Mage.Sets/src/mage/sets/invasion/PouncingKavu.java @@ -64,7 +64,7 @@ public class PouncingKavu extends CardImpl { this.addAbility(FirstStrikeAbility.getInstance()); // If Pouncing Kavu was kicked, it enters the battlefield with two +1/+1 counters on it and with haste. Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with haste.", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with haste.", ""); ability.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java index e28139b407a..a50a302bef4 100644 --- a/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java +++ b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java @@ -64,7 +64,7 @@ public class PrisonBarricade extends CardImpl { this.addAbility(new KickerAbility("{1}{W}")); // If Prison Barricade was kicked, it enters the battlefield with a +1/+1 counter on it and with "Prison Barricade can attack as though it didn't have defender." Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); ability.addEffect(new CanAttackAsThoughItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java b/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java index 6a5a08663fd..a729cf2c00c 100644 --- a/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java +++ b/Mage.Sets/src/mage/sets/invasion/UrborgSkeleton.java @@ -68,7 +68,7 @@ public class UrborgSkeleton extends CardImpl { // If Urborg Skeleton was kicked, it enters the battlefield with a +1/+1 counter on it. Ability ability = new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), - KickedCondition.getInstance(),false, staticText,""); + KickedCondition.getInstance(), staticText,""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java b/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java index 02703289141..44d4bd6a633 100644 --- a/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java +++ b/Mage.Sets/src/mage/sets/invasion/VodalianSerpent.java @@ -62,7 +62,7 @@ public class VodalianSerpent extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackUnlessDefenderControllsPermanent(new FilterLandPermanent("Island", "an Island")))); // If Vodalian Serpent was kicked, it enters the battlefield with four +1/+1 counters on it. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)), - KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); + KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with four +1/+1 counters on it.", "")); } public VodalianSerpent(final VodalianSerpent card) { diff --git a/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java b/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java index ef7d31f7976..de36fde3e17 100644 --- a/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java +++ b/Mage.Sets/src/mage/sets/jacevsvraska/BodyDouble.java @@ -30,8 +30,7 @@ package mage.sets.jacevsvraska; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; import mage.cards.Card; @@ -40,10 +39,8 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreatureCard; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInGraveyard; @@ -63,11 +60,7 @@ public class BodyDouble extends CardImpl { this.toughness = new MageInt(0); // You may have Body Double enter the battlefield as a copy of any creature card in a graveyard. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new BodyDoubleCopyEffect(), - "You may have {this} enter the battlefield as a copy of any creature card in a graveyard", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new BodyDoubleCopyEffect(), true)); } @@ -85,7 +78,7 @@ class BodyDoubleCopyEffect extends OneShotEffect { public BodyDoubleCopyEffect() { super(Outcome.Copy); - this.staticText = "You may have {this} enter the battlefield as a copy of any creature card in a graveyard"; + this.staticText = "as a copy of any creature card in a graveyard"; } public BodyDoubleCopyEffect(final BodyDoubleCopyEffect effect) { @@ -95,8 +88,7 @@ class BodyDoubleCopyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (player != null && sourcePermanent != null) { + if (player != null) { Target target = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); target.setNotTarget(true); if (target.canChoose(source.getControllerId(), game)) { diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java index 82266793698..2fce108dbb9 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java @@ -30,11 +30,10 @@ package mage.sets.journeyintonyx; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -62,7 +61,7 @@ public class AjaniMentorOfHeroes extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control"); private static final FilterCard filterCard = new FilterCard("an Aura, creature, or planeswalker card"); - + static { filter.add(new ControllerPredicate(TargetController.YOU)); filterCard.add(Predicates.or( @@ -70,23 +69,22 @@ public class AjaniMentorOfHeroes extends CardImpl { new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.PLANESWALKER))); } - + public AjaniMentorOfHeroes(UUID ownerId) { super(ownerId, 145, "Ajani, Mentor of Heroes", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{G}{W}"); this.expansionSetCode = "JOU"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Distribute three +1/+1 counters among one, two, or three target creatures you control Ability ability = new LoyaltyAbility(new AjaniMentorOfHeroesAddCountersEffect(), 1); ability.addTarget(new TargetCreaturePermanentAmount(3, filter)); this.addAbility(ability); - + // +1: Look at the top four cards of your library. You may reveal an Aura, creature, or planeswalker card from among them and put that card into your hand. Put the rest on the bottom of your library in any order. - this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4,1, filterCard,true, false, Zone.HAND, true), 1)); - + this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(4, 1, filterCard, true, false, Zone.HAND, true), 1)); + // -8: You gain 100 life. this.addAbility(new LoyaltyAbility(new GainLifeEffect(100), -8)); } @@ -122,7 +120,7 @@ class AjaniMentorOfHeroesAddCountersEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && source.getTargets().size() > 0) { Target multiTarget = source.getTargets().get(0); - for (UUID target: multiTarget.getTargets()) { + for (UUID target : multiTarget.getTargets()) { Permanent permanent = game.getPermanent(target); if (permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java b/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java index c5b745b5894..31e52d06b4a 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/BloodcrazedHoplite.java @@ -89,7 +89,7 @@ public class BloodcrazedHoplite extends CardImpl { class BloodcrazedHopliteTriggeredAbility extends TriggeredAbilityImpl { public BloodcrazedHopliteTriggeredAbility() { - super(Zone.BATTLEFIELD, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); + super(Zone.ALL, new RemoveCounterTargetEffect(CounterType.P1P1.createInstance()), true); } public BloodcrazedHopliteTriggeredAbility(BloodcrazedHopliteTriggeredAbility ability) { diff --git a/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java b/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java index f832cbe3df9..c95149465dd 100644 --- a/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java +++ b/Mage.Sets/src/mage/sets/judgment/BalthorTheDefiled.java @@ -37,8 +37,9 @@ import mage.abilities.costs.common.ExileSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; @@ -51,7 +52,6 @@ import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.players.Player; - /** * * @author LevelX2 @@ -75,7 +75,7 @@ public class BalthorTheDefiled extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BalthorTheDefiledEffect(), new ManaCostsImpl("{B}{B}{B}")); ability.addCost(new ExileSourceCost()); this.addAbility(ability); - + } public BalthorTheDefiled(final BalthorTheDefiled card) { @@ -98,32 +98,32 @@ class BalthorTheDefiledEffect extends OneShotEffect { new ColorPredicate(ObjectColor.RED))); } - public BalthorTheDefiledEffect() { + public BalthorTheDefiledEffect() { super(Outcome.Detriment); this.staticText = "Each player returns all black and all red creature cards from his or her graveyard to the battlefield"; } - public BalthorTheDefiledEffect(final BalthorTheDefiledEffect effect) { + public BalthorTheDefiledEffect(final BalthorTheDefiledEffect effect) { super(effect); } @Override - public BalthorTheDefiledEffect copy() { - return new BalthorTheDefiledEffect(this); + public BalthorTheDefiledEffect copy() { + return new BalthorTheDefiledEffect(this); } @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + Cards cardsToReturn = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId()); - } + cardsToReturn.addAll(player.getGraveyard().getCards(filter, source.getSourceId(), source.getControllerId(), game)); } } + controller.moveCards(cardsToReturn.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java b/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java index 87503dfe207..2a058c4e4bf 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/CleverImpersonator.java @@ -29,13 +29,11 @@ package mage.sets.khansoftarkir; import java.util.UUID; import mage.MageInt; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterNonlandPermanent; /** @@ -53,10 +51,7 @@ public class CleverImpersonator extends CardImpl { this.toughness = new MageInt(0); // You may have Clever Impersonator enter the battlefield as a copy of any nonland permanent on the battlefield. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new FilterNonlandPermanent()), - "You may have {this} enter the battlefield as a copy of any nonland permanent on the battlefield", - true))); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(new FilterNonlandPermanent()), true)); } public CleverImpersonator(final CleverImpersonator card) { diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java b/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java index cb84a4e3e85..c6d95ccf67b 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SarkhanTheDragonspeaker.java @@ -34,13 +34,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfDrawTriggeredAbility; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.HasteAbility; @@ -54,7 +53,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; @@ -71,16 +69,16 @@ public class SarkhanTheDragonspeaker extends CardImpl { this.expansionSetCode = "KTK"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, Sarkhan, the Dragonspeaker becomes a legendary 4/4 red Dragon creature with flying, indestructible, and haste. this.addAbility(new LoyaltyAbility(new SarkhanTheDragonspeakerEffect(), 1)); - + // -3: Sarkhan, the Dragonspeaker deals 4 damage to target creature. LoyaltyAbility ability = new LoyaltyAbility(new DamageTargetEffect(4), -3); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // -6: You get an emblem with "At the beginning of your draw step, draw two additional cards" and "At the beginning of your end step, discard your hand." Effect effect = new GetEmblemEffect(new SarkhanTheDragonspeakerEmblem()); effect.setText("You get an emblem with \"At the beginning of your draw step, draw two additional cards\" and \"At the beginning of your end step, discard your hand.\""); @@ -98,7 +96,7 @@ public class SarkhanTheDragonspeaker extends CardImpl { } class SarkhanTheDragonspeakerEffect extends ContinuousEffectImpl { - + SarkhanTheDragonspeakerEffect() { super(Duration.EndOfTurn, Outcome.BecomeCreature); staticText = "Until end of turn, {this} becomes a legendary 4/4 red Dragon creature with flying, indestructible, and haste."; @@ -112,7 +110,7 @@ class SarkhanTheDragonspeakerEffect extends ContinuousEffectImpl { public SarkhanTheDragonspeakerEffect copy() { return new SarkhanTheDragonspeakerEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java b/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java index 835039e8420..c12ea7c75ef 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SorinSolemnVisitor.java @@ -32,14 +32,13 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.SacrificeEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; @@ -48,12 +47,10 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.command.Emblem; import mage.game.permanent.token.Token; - /** * * @author LevelX2 @@ -65,8 +62,7 @@ public class SorinSolemnVisitor extends CardImpl { this.expansionSetCode = "KTK"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until your next turn, creatures you control get +1/+0 and gain lifelink. Effect effect = new BoostControlledEffect(1, 0, Duration.UntilYourNextTurn, new FilterCreaturePermanent()); @@ -94,18 +90,22 @@ public class SorinSolemnVisitor extends CardImpl { return new SorinSolemnVisitor(this); } } + /** - * Emblem: "At the beginning of each opponent's upkeep, that player sacrifices a creature." + * Emblem: "At the beginning of each opponent's upkeep, that player sacrifices a + * creature." */ class SorinEmblem extends Emblem { + public SorinEmblem() { this.setName("EMBLEM: Sorin, Solemn Visitor"); - Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, new SacrificeEffect(new FilterCreaturePermanent(),1 ,"that player"), TargetController.OPPONENT, false, true); + Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, new SacrificeEffect(new FilterCreaturePermanent(), 1, "that player"), TargetController.OPPONENT, false, true); this.getAbilities().add(ability); } } class SorinSolemnVisitorVampireToken extends Token { + SorinSolemnVisitorVampireToken() { super("Vampire", "a 2/2 black Vampire creature token with flying"); setOriginalExpansionSetCode("KTK"); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java b/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java index d319410e590..cc33f764fd9 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/WarNameAspirant.java @@ -68,7 +68,6 @@ public class WarNameAspirant extends CardImpl { // Raid - War-Name Aspirant enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), RaidCondition.getInstance(), - true, "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", "{this} enters the battlefield with a +1/+1 counter"), new PlayerAttackedWatcher()); diff --git a/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java b/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java index 3ab1fcca736..2852b95626f 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/AnimateDead.java @@ -70,15 +70,14 @@ public class AnimateDead extends CardImpl { this.expansionSetCode = "LEA"; this.subtype.add("Aura"); - // Enchant creature card in a graveyard TargetCardInGraveyard auraTarget = new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AnimateDeadAttachEffect(Outcome.PutCreatureInPlay)); Ability enchantAbility = new EnchantAbility(auraTarget.getTargetName()); - this.addAbility(enchantAbility); - // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" - // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield + this.addAbility(enchantAbility); + // When Animate Dead enters the battlefield, if it's on the battlefield, it loses "enchant creature card in a graveyard" + // and gains "enchant creature put onto the battlefield with Animate Dead." Return enchanted creature card to the battlefield // under your control and attach Animate Dead to it. When Animate Dead leaves the battlefield, that creature's controller sacrifices it. Ability ability = new ConditionalTriggeredAbility( new EntersBattlefieldTriggeredAbility(new AnimateDeadReAttachEffect(), false), @@ -86,11 +85,11 @@ public class AnimateDead extends CardImpl { "When {this} enters the battlefield, if it's on the battlefield, it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with {this}.\" Return enchanted creature card to the battlefield under your control and attach {this} to it."); ability.addEffect(new AnimateDeadChangeAbilityEffect()); this.addAbility(ability); - this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false)); - + this.addAbility(new LeavesBattlefieldTriggeredAbility(new AnimateDeadLeavesBattlefieldTriggeredEffect(), false)); + // Enchanted creature gets -1/-0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(-1, 0, Duration.WhileOnBattlefield))); - + } public AnimateDead(final AnimateDead card) { @@ -104,36 +103,36 @@ public class AnimateDead extends CardImpl { } class AnimateDeadReAttachEffect extends OneShotEffect { - + public AnimateDeadReAttachEffect() { super(Outcome.Benefit); this.staticText = "Return enchanted creature card to the battlefield under your control and attach {this} to it"; } - + public AnimateDeadReAttachEffect(final AnimateDeadReAttachEffect effect) { super(effect); } - + @Override public AnimateDeadReAttachEffect copy() { return new AnimateDeadReAttachEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Permanent enchantment = game.getPermanent(source.getSourceId()); - + if (controller != null && enchantment != null) { Card cardInGraveyard = game.getCard(enchantment.getAttachedTo()); if (cardInGraveyard == null) { return true; } - + // put card into play - controller.putOntoBattlefieldWithInfo(cardInGraveyard, game, Zone.GRAVEYARD, source.getSourceId()); + controller.moveCards(cardInGraveyard, Zone.BATTLEFIELD, source, game); Permanent enchantedCreature = game.getPermanent(cardInGraveyard.getId()); - + FilterCreaturePermanent filter = new FilterCreaturePermanent("enchant creature put onto the battlefield with Animate Dead"); filter.add(new PermanentIdPredicate(cardInGraveyard.getId())); Target target = new TargetCreaturePermanent(filter); @@ -146,27 +145,27 @@ class AnimateDeadReAttachEffect extends OneShotEffect { } return true; } - + return false; } } - + class AnimateDeadLeavesBattlefieldTriggeredEffect extends OneShotEffect { - + public AnimateDeadLeavesBattlefieldTriggeredEffect() { super(Outcome.Benefit); this.staticText = "enchanted creature's controller sacrifices it"; } - + public AnimateDeadLeavesBattlefieldTriggeredEffect(final AnimateDeadLeavesBattlefieldTriggeredEffect effect) { super(effect); } - + @Override public AnimateDeadLeavesBattlefieldTriggeredEffect copy() { return new AnimateDeadLeavesBattlefieldTriggeredEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); @@ -223,17 +222,16 @@ class AnimateDeadAttachEffect extends OneShotEffect { class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements SourceEffect { private final static Ability newAbility = new EnchantAbility("creature put onto the battlefield with Animate Dead"); - + static { newAbility.setRuleAtTheTop(true); } - + public AnimateDeadChangeAbilityEffect() { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); staticText = "it loses \"enchant creature card in a graveyard\" and gains \"enchant creature put onto the battlefield with Animate Dead\""; } - public AnimateDeadChangeAbilityEffect(final AnimateDeadChangeAbilityEffect effect) { super(effect); } @@ -242,7 +240,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou public AnimateDeadChangeAbilityEffect copy() { return new AnimateDeadChangeAbilityEffect(this); } - + @Override public void init(Ability source, Game game) { super.init(source, game); @@ -254,7 +252,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou Permanent permanent = affectedObjectList.get(0).getPermanent(game); if (permanent != null) { Ability abilityToRemove = null; - for (Ability ability: permanent.getAbilities()) { + for (Ability ability : permanent.getAbilities()) { if (ability instanceof EnchantAbility) { abilityToRemove = ability; } @@ -264,7 +262,7 @@ class AnimateDeadChangeAbilityEffect extends ContinuousEffectImpl implements Sou } permanent.addAbility(newAbility, source.getSourceId(), game); return true; - } + } return false; } } diff --git a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java index b1a99b0e249..d783513396a 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/CopyArtifact.java @@ -28,24 +28,14 @@ package mage.sets.limitedalpha; import java.util.UUID; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.filter.FilterPermanent; -import mage.filter.predicate.mageobject.CardTypePredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; -import mage.util.functions.ApplyToPermanent; +import mage.filter.common.FilterArtifactPermanent; +import mage.util.functions.CardTypeApplier; /** * @@ -59,11 +49,9 @@ public class CopyArtifact extends CardImpl { this.expansionSetCode = "LEA"; // You may have Copy Artifact enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyArtifactEffect(), - "You may have {this} enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types", - true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterArtifactPermanent(), new CardTypeApplier(CardType.ENCHANTMENT)); + effect.setText("as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public CopyArtifact(final CopyArtifact card) { @@ -75,64 +63,3 @@ public class CopyArtifact extends CardImpl { return new CopyArtifact(this); } } - -class CopyArtifactEffect extends OneShotEffect { - - ApplyToPermanent applier = new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) { - permanent.getCardType().add(CardType.ENCHANTMENT); - } - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getCardType().contains(CardType.ENCHANTMENT)) { - mageObject.getCardType().add(CardType.ENCHANTMENT); - } - return true; - } - - }; - - private static final FilterPermanent filter = new FilterPermanent("artifact"); - - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - - public CopyArtifactEffect() { - super(Outcome.Copy); - } - - public CopyArtifactEffect(final CopyArtifactEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(filter); - target.setNotTarget(true); - if (target.canChoose(source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, applier); - return true; - } - } - } - return false; - } - - @Override - public CopyArtifactEffect copy() { - return new CopyArtifactEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java b/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java index f53660bf0f0..f123146b6a8 100644 --- a/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java +++ b/Mage.Sets/src/mage/sets/magic2010/AjaniGoldmane.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,15 +20,26 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2010; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.Effects; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,19 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effects; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.keyword.VigilanceAbility; -import mage.cards.CardImpl; import mage.counters.CounterType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; @@ -68,7 +66,7 @@ public class AjaniGoldmane extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Ajani"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: You gain 2 life. this.addAbility(new LoyaltyAbility(new GainLifeEffect(2), 1)); @@ -136,4 +134,4 @@ class AvatarTokenEffect extends ContinuousEffectImpl { return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java b/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java index e795ef55dc2..b1ced672549 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java +++ b/Mage.Sets/src/mage/sets/magic2010/ChandraNalaar.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,17 +20,17 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2010; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.dynamicvalue.DynamicValue; @@ -38,18 +38,14 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DamageAllControlledTargetEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.target.TargetPlayer; import mage.target.common.TargetCreaturePermanent; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com, nantuko @@ -61,8 +57,7 @@ public class ChandraNalaar extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); ability1.addTarget(new TargetPlayer()); @@ -98,7 +93,7 @@ class ChandraNalaarXValue implements DynamicValue { public int calculate(Game game, Ability sourceAbility, Effect effect) { for (Cost cost : sourceAbility.getCosts()) { if (cost instanceof PayVariableLoyaltyCost) { - return ((PayVariableLoyaltyCost)cost).getAmount(); + return ((PayVariableLoyaltyCost) cost).getAmount(); } } return 0; @@ -123,4 +118,3 @@ class ChandraNalaarXValue implements DynamicValue { return defaultValue; } } - diff --git a/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java b/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java index 7c35ee12a38..9a3ddef6c26 100644 --- a/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java +++ b/Mage.Sets/src/mage/sets/magic2010/GarrukWildspeaker.java @@ -1,49 +1,46 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.sets.magic2010; import java.util.UUID; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.BeastToken; import mage.target.common.TargetLandPermanent; @@ -61,8 +58,7 @@ public class GarrukWildspeaker extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Garruk"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Untap two target lands. LoyaltyAbility ability1 = new LoyaltyAbility(new UntapTargetEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java b/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java index fcd4938b0e1..b5566671786 100644 --- a/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java +++ b/Mage.Sets/src/mage/sets/magic2010/JaceBeleren.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,25 +20,22 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2010; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.target.TargetPlayer; /** @@ -52,9 +49,9 @@ public class JaceBeleren extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - // +2: Each player draws a card. + // +2: Each player draws a card. this.addAbility(new LoyaltyAbility(new DrawCardAllEffect(1), 2)); // -1: Target player draws a card. diff --git a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java index 5f955caa787..7ab2a913ae9 100644 --- a/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java +++ b/Mage.Sets/src/mage/sets/magic2010/LilianaVess.java @@ -32,9 +32,8 @@ import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; import mage.cards.Card; @@ -43,7 +42,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; @@ -60,7 +58,7 @@ public class LilianaVess extends CardImpl { this.expansionSetCode = "M10"; this.subtype.add("Liliana"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Target player discards a card. LoyaltyAbility ability1 = new LoyaltyAbility(new DiscardTargetEffect(1), 1); ability1.addTarget(new TargetPlayer()); diff --git a/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java b/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java index 484242f65d6..8e61bb1817f 100644 --- a/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java +++ b/Mage.Sets/src/mage/sets/magic2011/InfernoTitan.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2011; import java.util.UUID; @@ -100,10 +99,7 @@ class InfernoTitanAbility extends TriggeredAbilityImpl { if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) { return true; } - if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - return true; - } - return false; + return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/sets/magic2011/SunTitan.java b/Mage.Sets/src/mage/sets/magic2011/SunTitan.java index 03f7d21a769..0b5c5660dc7 100644 --- a/Mage.Sets/src/mage/sets/magic2011/SunTitan.java +++ b/Mage.Sets/src/mage/sets/magic2011/SunTitan.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2011; import java.util.UUID; @@ -117,10 +116,7 @@ class SunTitanAbility extends TriggeredAbilityImpl { if (event.getType() == EventType.ATTACKER_DECLARED && event.getSourceId().equals(this.getSourceId())) { return true; } - if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - return true; - } - return false; + return event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()); } @Override diff --git a/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java b/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java index 3677a7b9cc7..1fd2d3f98a1 100644 --- a/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java +++ b/Mage.Sets/src/mage/sets/magic2012/ChandraTheFirebrand.java @@ -25,23 +25,20 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2012; import java.util.UUID; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyTargetSpellEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -55,22 +52,21 @@ import mage.target.targetpointer.FixedTarget; */ public class ChandraTheFirebrand extends CardImpl { - public ChandraTheFirebrand (UUID ownerId) { + public ChandraTheFirebrand(UUID ownerId) { super(ownerId, 124, "Chandra, the Firebrand", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{R}"); this.expansionSetCode = "M12"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Chandra, the Firebrand deals 1 damage to target creature or player. - LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); ability1.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability1); // -2: When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy. - Effect effect = new CreateDelayedTriggeredAbilityEffect(new ChandraTheFirebrandAbility()); - effect .setText("When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy"); + Effect effect = new CreateDelayedTriggeredAbilityEffect(new ChandraTheFirebrandAbility()); + effect.setText("When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy"); this.addAbility(new LoyaltyAbility(effect, -2)); // -6: Chandra, the Firebrand deals 6 damage to each of up to six target creatures and/or players @@ -79,7 +75,7 @@ public class ChandraTheFirebrand extends CardImpl { this.addAbility(ability2); } - public ChandraTheFirebrand (final ChandraTheFirebrand card) { + public ChandraTheFirebrand(final ChandraTheFirebrand card) { super(card); } @@ -91,6 +87,7 @@ public class ChandraTheFirebrand extends CardImpl { } class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { + ChandraTheFirebrandAbility() { super(new CopyTargetSpellEffect(), Duration.EndOfTurn); } @@ -111,11 +108,11 @@ class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { - if (event.getPlayerId().equals(this.getControllerId())) { + if (event.getPlayerId().equals(this.getControllerId())) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); + effect.setTargetPointer(new FixedTarget(event.getTargetId())); } return true; } @@ -127,4 +124,4 @@ class ChandraTheFirebrandAbility extends DelayedTriggeredAbility { public String getRule() { return "When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java b/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java index 17c8316eca0..935f24def0f 100644 --- a/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java +++ b/Mage.Sets/src/mage/sets/magic2012/GarrukPrimalHunter.java @@ -25,23 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2012; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; @@ -56,20 +52,19 @@ import mage.players.Player; * @author Loki */ public class GarrukPrimalHunter extends CardImpl { - + private static final FilterControlledPermanent filter = new FilterControlledLandPermanent(); - public GarrukPrimalHunter (UUID ownerId) { + public GarrukPrimalHunter(UUID ownerId) { super(ownerId, 174, "Garruk, Primal Hunter", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{G}{G}"); this.expansionSetCode = "M12"; this.subtype.add("Garruk"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Put a 3/3 green Beast creature token onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new BeastToken()), 1)); - + // -3: Draw cards equal to the greatest power among creatures you control. this.addAbility(new LoyaltyAbility(new GarrukPrimalHunterEffect(), -3)); @@ -77,7 +72,7 @@ public class GarrukPrimalHunter extends CardImpl { this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new WurmToken(), new PermanentsOnBattlefieldCount(filter)), -6)); } - public GarrukPrimalHunter (final GarrukPrimalHunter card) { + public GarrukPrimalHunter(final GarrukPrimalHunter card) { super(card); } @@ -89,6 +84,7 @@ public class GarrukPrimalHunter extends CardImpl { } class GarrukPrimalHunterEffect extends OneShotEffect { + GarrukPrimalHunterEffect() { super(Outcome.DrawCard); staticText = "Draw cards equal to the greatest power among creatures you control"; diff --git a/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java b/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java index 58b5b0f98c3..2e687f4f8cb 100644 --- a/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java +++ b/Mage.Sets/src/mage/sets/magic2012/JaceMemoryAdept.java @@ -27,24 +27,21 @@ */ package mage.sets.magic2012; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.Mode; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; -import java.util.UUID; - /** * @author nantuko */ @@ -55,8 +52,7 @@ public class JaceMemoryAdept extends CardImpl { this.expansionSetCode = "M12"; this.subtype.add("Jace"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Draw a card. Target player puts the top card of his or her library into his or her graveyard. LoyaltyAbility ability1 = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1); @@ -116,5 +112,3 @@ class JaceMemoryAdeptEffect extends DrawCardTargetEffect { return new JaceMemoryAdeptEffect(this); } } - - diff --git a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java index 82de7d6d4e8..23ede410e11 100644 --- a/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java +++ b/Mage.Sets/src/mage/sets/magic2012/PhantasmalImage.java @@ -30,23 +30,17 @@ package mage.sets.magic2012; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.common.BecomesTargetTriggeredAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; /** @@ -55,7 +49,31 @@ import mage.util.functions.ApplyToPermanent; */ public class PhantasmalImage extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it gains \"When this creature becomes the target of a spell or ability, sacrifice it.\""; + private static final String effectText = "a copy of any creature on the battlefield, except it's an Illusion in addition to its other types and it gains \"When this creature becomes the target of a spell or ability, sacrifice it.\""; + + ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() { + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSubtype().contains("Illusion")) { + permanent.getSubtype().add("Illusion"); + } + // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities + permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); + //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSubtype().contains("Illusion")) { + mageObject.getSubtype().add("Illusion"); + } + // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities + mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); + //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); + return true; + } + }; public PhantasmalImage(UUID ownerId) { super(ownerId, 72, "Phantasmal Image", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}"); @@ -69,9 +87,9 @@ public class PhantasmalImage extends CardImpl { // You may have Phantasmal Image enter the battlefield as a copy of any creature // on the battlefield, except it's an Illusion in addition to its other types and // it gains "When this creature becomes the target of a spell or ability, sacrifice it." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new PhantasmalImageCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), phantasmalImageApplier); + effect.setText(effectText); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public PhantasmalImage(final PhantasmalImage card) { @@ -83,62 +101,3 @@ public class PhantasmalImage extends CardImpl { return new PhantasmalImage(this); } } - -class PhantasmalImageCopyEffect extends OneShotEffect { - - public PhantasmalImageCopyEffect() { - super(Outcome.Copy); - } - - public PhantasmalImageCopyEffect(final PhantasmalImageCopyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)")); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSubtype().contains("Illusion")) { - permanent.getSubtype().add("Illusion"); - } - // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities - permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); - //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSubtype().contains("Illusion")) { - mageObject.getSubtype().add("Illusion"); - } - // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities - mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); - //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); - return true; - } - - }); - - return true; - } - } - } - return false; - } - - @Override - public PhantasmalImageCopyEffect copy() { - return new PhantasmalImageCopyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java b/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java index 44cc9264d27..6f651062b5e 100644 --- a/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java +++ b/Mage.Sets/src/mage/sets/magic2012/SuturedGhoul.java @@ -34,7 +34,6 @@ import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.TrampleAbility; @@ -104,7 +103,7 @@ class SuturedGhoulEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent == null) { return false; } diff --git a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java index 2575cf4bc83..43b20bce5ec 100644 --- a/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java +++ b/Mage.Sets/src/mage/sets/magic2013/AjaniCallerOfThePride.java @@ -28,16 +28,14 @@ package mage.sets.magic2013; import java.util.UUID; -import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.ControllerLifeCount; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; @@ -64,12 +62,12 @@ public class AjaniCallerOfThePride extends CardImpl { @Override public void build() { - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a +1/+1 counter on up to one target creature. Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); effect.setText("Put a +1/+1 counter on up to one target creature"); Ability ability = new LoyaltyAbility(effect, 1); - ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.addTarget(new TargetCreaturePermanent(0, 1)); this.addAbility(ability); // -3: Target creature gains flying and double strike until end of turn. Effects effects = new Effects(); diff --git a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java index b706cc764c0..2ae1156c849 100644 --- a/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java +++ b/Mage.Sets/src/mage/sets/magic2013/LilianaOfTheDarkRealms.java @@ -28,6 +28,18 @@ package mage.sets.magic2013; import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -36,20 +48,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.Mana; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.abilities.mana.SimpleManaAbility; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.common.FilterLandCard; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -78,8 +76,7 @@ public class LilianaOfTheDarkRealms extends CardImpl { this.expansionSetCode = "M13"; this.subtype.add("Liliana"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Search your library for a Swamp card, reveal it, and put it into your hand. Then shuffle your library. this.addAbility(new LoyaltyAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), 1)); diff --git a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java index 8c3d87f6aad..25de8f9d80e 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/sets/magic2014/ChandraPyromaster.java @@ -33,12 +33,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.combat.CantBlockTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -49,7 +48,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -74,7 +72,7 @@ public class ChandraPyromaster extends CardImpl { this.expansionSetCode = "M14"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Chandra, Pyromaster deals 1 damage to target player and 1 damage to up to one target creature that player controls. That creature can't block this turn. LoyaltyAbility ability1 = new LoyaltyAbility(new ChandraPyromasterEffect1(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java index 6cf8ee79c45..4784c9168fa 100644 --- a/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java +++ b/Mage.Sets/src/mage/sets/magic2014/GarrukCallerOfBeasts.java @@ -31,20 +31,18 @@ import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PutPermanentOnBattlefieldEffect; import mage.abilities.effects.common.RevealLibraryPutIntoHandEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -69,11 +67,10 @@ public class GarrukCallerOfBeasts extends CardImpl { this.expansionSetCode = "M14"; this.subtype.add("Garruk"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Reveal the top 5 cards of your library. Put all creature cards revealed this way into your hand and the rest on the bottom of your library in any order. - this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("all creature cards"),true), 1)); + this.addAbility(new LoyaltyAbility(new RevealLibraryPutIntoHandEffect(5, new FilterCreatureCard("all creature cards"), true), 1)); // -3: You may put a green creature card from your hand onto the battlefield. this.addAbility(new LoyaltyAbility(new PutPermanentOnBattlefieldEffect(filterGreenCreature), -3)); @@ -94,18 +91,20 @@ public class GarrukCallerOfBeasts extends CardImpl { } /** - * Emblem: "Whenever you cast a creature spell, you may search your library for a creature card, put it onto the battlefield, then shuffle your library." + * Emblem: "Whenever you cast a creature spell, you may search your library for + * a creature card, put it onto the battlefield, then shuffle your library." */ class GarrukCallerOfBeastsEmblem extends Emblem { private static final FilterSpell filter = new FilterSpell("a creature spell"); + static { filter.add(new CardTypePredicate(CardType.CREATURE)); } public GarrukCallerOfBeastsEmblem() { this.setName("EMBLEM: Garruk, Caller of Beasts"); - Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterCreatureCard("creature card")),false, true, Outcome.PutCreatureInPlay); + Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterCreatureCard("creature card")), false, true, Outcome.PutCreatureInPlay); Ability ability = new SpellCastControllerTriggeredAbility(Zone.COMMAND, effect, filter, true, false); this.getAbilities().add(ability); } diff --git a/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java b/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java index 0a7c07a1299..4a7ae5c389f 100644 --- a/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java +++ b/Mage.Sets/src/mage/sets/magic2014/ImposingSovereign.java @@ -58,7 +58,7 @@ public class ImposingSovereign extends CardImpl { // Creatures your opponents control enter the battlefield tapped. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ImposingSovereignEffect())); - + } public ImposingSovereign(final ImposingSovereign card) { @@ -72,7 +72,7 @@ public class ImposingSovereign extends CardImpl { } class ImposingSovereignEffect extends ReplacementEffectImpl { - + ImposingSovereignEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Creatures your opponents control enter the battlefield tapped"; @@ -84,7 +84,7 @@ class ImposingSovereignEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.tap(game); } @@ -95,11 +95,11 @@ class ImposingSovereignEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java index fc7db630f25..0736339d5af 100644 --- a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java +++ b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java @@ -314,7 +314,7 @@ class SavageSummoningEntersBattlefieldEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } diff --git a/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java b/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java index b9283d50ea6..aee04861911 100644 --- a/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java +++ b/Mage.Sets/src/mage/sets/magic2015/AjaniSteadfast.java @@ -30,7 +30,7 @@ package mage.sets.magic2015; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.PreventionEffectImpl; @@ -38,7 +38,6 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.counter.AddCountersAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.VigilanceAbility; @@ -66,22 +65,21 @@ import mage.target.common.TargetCreaturePermanent; public class AjaniSteadfast extends CardImpl { private static final FilterPlaneswalkerPermanent filter = new FilterPlaneswalkerPermanent("other planeswalker you control"); - + static { filter.add(new AnotherPredicate()); filter.add(new ControllerPredicate(TargetController.YOU)); } - + public AjaniSteadfast(UUID ownerId) { super(ownerId, 1, "Ajani Steadfast", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{W}"); this.expansionSetCode = "M15"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until end of turn, up to one target creature gets +1/+1 and gains first strike, vigilance, and lifelink. - Effect effect = new BoostTargetEffect(1,1, Duration.EndOfTurn); + Effect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn); effect.setText("Until end of turn, up to one target creature gets +1/+1"); LoyaltyAbility ability = new LoyaltyAbility(effect, 1); effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); @@ -93,16 +91,16 @@ public class AjaniSteadfast extends CardImpl { effect = new GainAbilityTargetEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); effect.setText(", and lifelink"); ability.addEffect(effect); - ability.addTarget(new TargetCreaturePermanent(0,1)); + ability.addTarget(new TargetCreaturePermanent(0, 1)); this.addAbility(ability); - + // -2: Put a +1/+1 counter on each creature you control and a loyalty counter on each other planeswalker you control. ability = new LoyaltyAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()), -2); effect = new AddCountersAllEffect(CounterType.LOYALTY.createInstance(), filter); effect.setText("and a loyalty counter on each other planeswalker you control"); ability.addEffect(effect); this.addAbility(ability); - + // -7: You get an emblem with "If a source would deal damage to you or a planeswalker you control, prevent all but 1 of that damage." this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new AjaniSteadfastEmblem()), -7)); } @@ -121,7 +119,7 @@ class AjaniSteadfastEmblem extends Emblem { public AjaniSteadfastEmblem() { setName("EMBLEM: Ajani Steadfast"); - this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new AjaniSteadfastPreventEffect())); + this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new AjaniSteadfastPreventEffect())); this.setExpansionSetCodeForImage("M15"); } } @@ -143,7 +141,7 @@ class AjaniSteadfastPreventEffect extends PreventionEffectImpl { int damage = event.getAmount(); if (damage > 1) { amountToPrevent = damage - 1; - preventDamageAction(event, source, game); + preventDamageAction(event, source, game); } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java index 955c9019f01..dd839d19569 100644 --- a/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java +++ b/Mage.Sets/src/mage/sets/magic2015/GarrukApexPredator.java @@ -32,7 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.AttackedByCreatureTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.GetEmblemTargetPlayerEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; @@ -50,7 +49,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SetTargetPointer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; @@ -81,7 +79,7 @@ public class GarrukApexPredator extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Garruk"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Destroy another target planeswalker. LoyaltyAbility ability = new LoyaltyAbility(new DestroyTargetEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java b/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java index 703a9f5a0cf..03eda36b2ff 100644 --- a/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java +++ b/Mage.Sets/src/mage/sets/magic2015/GenesisHydra.java @@ -131,7 +131,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } target1.clearChosen(); } else { @@ -140,11 +140,7 @@ class GenesisHydraPutOntoBattlefieldEffect extends OneShotEffect { } else { game.informPlayers("No nonland permanent card with converted mana cost " + count + " or less to choose."); } - while (cards.size() > 0) { - Card card = cards.get(cards.iterator().next(), game); - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + controller.moveCards(cards, Zone.LIBRARY, source, game); controller.shuffleLibrary(game); return true; } diff --git a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java index c644c080918..a05440e99db 100644 --- a/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java +++ b/Mage.Sets/src/mage/sets/magic2015/HushwingGryff.java @@ -108,7 +108,7 @@ class HushwingGryffEffect extends ContinuousRuleModifyingEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { Ability ability = (Ability) getValue("targetAbility"); if (ability != null && AbilityType.TRIGGERED.equals(ability.getAbilityType())) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java b/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java index 964c2310133..7d4c32fbbaa 100644 --- a/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java +++ b/Mage.Sets/src/mage/sets/magic2015/JaceTheLivingGuildpact.java @@ -30,20 +30,18 @@ package mage.sets.magic2015; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; @@ -69,8 +67,7 @@ public class JaceTheLivingGuildpact extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Jace"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Look at the top two cards of your library. Put one of them into your graveyard. Effect effect = new LookLibraryAndPickControllerEffect( @@ -78,7 +75,7 @@ public class JaceTheLivingGuildpact extends CardImpl { effect.setText("Look at the top two cards of your library. Put one of them into your graveyard"); this.addAbility(new LoyaltyAbility(effect, 1)); - // -3: Return another target nonland permanent to its owner's hand. + // -3: Return another target nonland permanent to its owner's hand. LoyaltyAbility ability = new LoyaltyAbility(new ReturnToHandTargetEffect(), -3); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); @@ -113,15 +110,15 @@ class JaceTheLivingGuildpactEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - for (UUID playerId: controller.getInRange()) { + for (UUID playerId : controller.getInRange()) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card card: player.getHand().getCards(game)) { + for (Card card : player.getHand().getCards(game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - for (Card card: player.getGraveyard().getCards(game)) { + } + for (Card card : player.getGraveyard().getCards(game)) { card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + } player.shuffleLibrary(game); } } diff --git a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java index 1aa0cb0c7c6..fcfabc49c0f 100644 --- a/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java +++ b/Mage.Sets/src/mage/sets/magic2015/MercurialPretender.java @@ -29,25 +29,17 @@ package mage.sets.magic2015; import java.util.UUID; import mage.MageInt; -import mage.MageObject; -import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.util.functions.AbilityApplier; /** @@ -56,7 +48,7 @@ import mage.util.functions.AbilityApplier; */ public class MercurialPretender extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature you control except it gains \"{2}{U}{U}: Return this creature to its owner's hand.\""; + private static final String effectText = "as a copy of any creature you control except it gains \"{2}{U}{U}: Return this creature to its owner's hand.\""; public MercurialPretender(UUID ownerId) { super(ownerId, 68, "Mercurial Pretender", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{U}"); @@ -69,9 +61,10 @@ public class MercurialPretender extends CardImpl { // You may have Mercurial Pretender enter the battlefield as a copy of any creature you control // except it gains "{2}{U}{U}: Return this creature to its owner's hand." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new MercurialPretenderCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), + new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}")))); + effect.setText(effectText); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public MercurialPretender(final MercurialPretender card) { @@ -83,41 +76,3 @@ public class MercurialPretender extends CardImpl { return new MercurialPretender(this); } } - -class MercurialPretenderCopyEffect extends OneShotEffect { - - public MercurialPretenderCopyEffect() { - super(Outcome.Copy); - } - - public MercurialPretenderCopyEffect(final MercurialPretenderCopyEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterControlledCreaturePermanent()); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, - // {2}{U}{U}: Return this creature to its owner's hand. - new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}"))) - ); - return true; - } - } - } - return false; - } - - @Override - public MercurialPretenderCopyEffect copy() { - return new MercurialPretenderCopyEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java b/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java index 3c5177de393..00f8de29bc3 100644 --- a/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java +++ b/Mage.Sets/src/mage/sets/magic2015/NissaWorldwaker.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -46,7 +45,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.common.FilterBasicLandCard; import mage.filter.common.FilterLandPermanent; @@ -79,9 +77,8 @@ public class NissaWorldwaker extends CardImpl { this.expansionSetCode = "M15"; this.subtype.add("Nissa"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Target land you control becomes a 4/4 Elemental creature with trample. It's still a land. LoyaltyAbility ability = new LoyaltyAbility(new BecomesCreatureTargetEffect(new NissaWorldwakerToken(), false, true, Duration.Custom), 1); ability.addTarget(new TargetLandPermanent(filter)); @@ -89,11 +86,11 @@ public class NissaWorldwaker extends CardImpl { // +1: Untap up to four target Forests. ability = new LoyaltyAbility(new UntapTargetEffect(), 1); - ability.addTarget(new TargetPermanent(0,4,filterForest, false)); + ability.addTarget(new TargetPermanent(0, 4, filterForest, false)); this.addAbility(ability); // -7: Search your library for any number of basic land cards, put them onto the battlefield, then shuffle your library. Those lands become 4/4 Elemental creatures with trample. They're still lands. - this.addAbility(new LoyaltyAbility(new NissaWorldwakerSearchEffect(), -7)); + this.addAbility(new LoyaltyAbility(new NissaWorldwakerSearchEffect(), -7)); } public NissaWorldwaker(final NissaWorldwaker card) { @@ -128,17 +125,17 @@ class NissaWorldwakerSearchEffect extends OneShotEffect { if (player == null) { return false; } - TargetCardInLibrary target = new TargetCardInLibrary(0,Integer.MAX_VALUE, new FilterBasicLandCard()); + TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, new FilterBasicLandCard()); if (player.searchLibrary(target, game)) { if (target.getTargets().size() > 0) { - for (UUID cardId: target.getTargets()) { + for (UUID cardId : target.getTargets()) { Card card = player.getLibrary().getCard(cardId, game); if (card != null) { if (player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId())) { ContinuousEffect effect = new BecomesCreatureTargetEffect(new NissaWorldwakerToken(), false, true, Duration.Custom); effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); - } + game.addEffect(effect, source); + } } } } @@ -159,4 +156,4 @@ class NissaWorldwakerToken extends Token { this.toughness = new MageInt(4); this.addAbility(TrampleAbility.getInstance()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java index 45882a2ddcf..fe48e846fa9 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java +++ b/Mage.Sets/src/mage/sets/magicorigins/ChandraRoaringFlame.java @@ -33,18 +33,16 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.command.Emblem; import mage.players.Player; @@ -62,25 +60,24 @@ public class ChandraRoaringFlame extends CardImpl { this.expansionSetCode = "ORI"; this.subtype.add("Chandra"); this.color.setRed(true); - + this.nightCard = true; this.canTransform = true; - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); - + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); + // +1: Chandra, Roaring Flame deals 2 damage to target player. LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), 1); loyaltyAbility.addTarget(new TargetPlayer()); - this.addAbility(loyaltyAbility); - + this.addAbility(loyaltyAbility); + //-2: Chandra, Roaring Flame deals 2 damage to target creature. loyaltyAbility = new LoyaltyAbility(new DamageTargetEffect(2), -2); loyaltyAbility.addTarget(new TargetCreaturePermanent()); - this.addAbility(loyaltyAbility); - + this.addAbility(loyaltyAbility); + //-7: Chandra, Roaring Flame deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." this.addAbility(new LoyaltyAbility(new ChandraRoaringFlameEmblemEffect(), -7)); - } @@ -95,27 +92,27 @@ public class ChandraRoaringFlame extends CardImpl { } class ChandraRoaringFlameEmblemEffect extends OneShotEffect { - + public ChandraRoaringFlameEmblemEffect() { super(Outcome.Damage); this.staticText = "{this} deals 6 damage to each opponent. Each player dealt damage this way gets an emblem with \"At the beginning of your upkeep, this emblem deals 3 damage to you.\""; } - + public ChandraRoaringFlameEmblemEffect(final ChandraRoaringFlameEmblemEffect effect) { super(effect); } - + @Override public ChandraRoaringFlameEmblemEffect copy() { return new ChandraRoaringFlameEmblemEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { List opponentsEmblem = new ArrayList<>(); - for(UUID playerId: game.getOpponents(controller.getId())) { + for (UUID playerId : game.getOpponents(controller.getId())) { Player opponent = game.getPlayer(playerId); if (opponent != null) { if (opponent.damage(6, source.getSourceId(), game, false, true) > 0) { @@ -132,7 +129,8 @@ class ChandraRoaringFlameEmblemEffect extends OneShotEffect { } /** - * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to you." + * Emblem with "At the beginning of your upkeep, this emblem deals 3 damage to + * you." */ class ChandraRoaringFlameEmblem extends Emblem { @@ -142,4 +140,4 @@ class ChandraRoaringFlameEmblem extends Emblem { effect.setText("this emblem deals 3 damage to you"); this.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(Zone.COMMAND, effect, TargetController.YOU, false, true)); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java index 926b6fab831..70692bfa083 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java +++ b/Mage.Sets/src/mage/sets/magicorigins/GideonBattleForged.java @@ -32,14 +32,13 @@ import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.TurnPhase; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; @@ -77,7 +75,7 @@ public class GideonBattleForged extends CardImpl { this.nightCard = true; this.canTransform = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able. LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new GideonBattleForgedAttacksIfAbleTargetEffect(Duration.Custom), 2); diff --git a/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java index 069802820e9..c4cb42fc138 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java +++ b/Mage.Sets/src/mage/sets/magicorigins/HallowedMoonlight.java @@ -36,6 +36,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; @@ -90,8 +91,7 @@ class HallowedMoonlightEffect extends ReplacementEffectImpl { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { EntersTheBattlefieldEvent entersTheBattlefieldEvent = (EntersTheBattlefieldEvent) event; - controller.moveCardToExileWithInfo(entersTheBattlefieldEvent.getTarget(), null, "", - source.getSourceId(), game, entersTheBattlefieldEvent.getFromZone(), true); + controller.moveCards(entersTheBattlefieldEvent.getTarget(), Zone.EXILED, source, game, false, false, false, null); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java b/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java index 7fabc195698..7e87bf53d0c 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java +++ b/Mage.Sets/src/mage/sets/magicorigins/JaceTelepathUnbound.java @@ -30,7 +30,7 @@ package mage.sets.magicorigins; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.AsThoughEffectType; @@ -49,7 +48,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterSpell; import mage.filter.common.FilterInstantOrSorceryCard; import mage.game.Game; @@ -77,7 +75,7 @@ public class JaceTelepathUnbound extends CardImpl { this.nightCard = true; this.canTransform = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Up to one target creature gets -2/-0 until your next turn. Effect effect = new BoostTargetEffect(-2, 0, Duration.UntilYourNextTurn); diff --git a/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java b/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java index c3abacd4394..67cdc1e5242 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java +++ b/Mage.Sets/src/mage/sets/magicorigins/LilianaDefiantNecromancer.java @@ -32,7 +32,7 @@ import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.common.DiesCreatureTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; @@ -40,7 +40,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -49,7 +48,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; @@ -84,7 +82,7 @@ public class LilianaDefiantNecromancer extends CardImpl { this.nightCard = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Each player discards a card. this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(1, false), 2)); diff --git a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java index d3a209c463a..c1e5a65d797 100644 --- a/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java +++ b/Mage.Sets/src/mage/sets/magicorigins/NissaSageAnimist.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -69,7 +67,7 @@ public class NissaSageAnimist extends CardImpl { this.nightCard = true; - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Reveal the top card of your library. If it's a land card, put it onto the battlefield. Otherwise, put it into your hand. this.addAbility(new LoyaltyAbility(new NissaSageAnimistPlusOneEffect(), 1)); diff --git a/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java b/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java index 7cfbf933b62..eaf8987852c 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java +++ b/Mage.Sets/src/mage/sets/mirrodin/ProteusStaff.java @@ -76,21 +76,21 @@ public class ProteusStaff extends CardImpl { } class ProteusStaffEffect extends OneShotEffect { - + ProteusStaffEffect() { super(Outcome.PutCreatureInPlay); this.staticText = "Put target creature on the bottom of its owner's library. That creature's controller reveals cards from the top of his or her library until he or she reveals a creature card. The player puts that card onto the battlefield and the rest on the bottom of his or her library in any order."; } - + ProteusStaffEffect(final ProteusStaffEffect effect) { super(effect); } - + @java.lang.Override public ProteusStaffEffect copy() { return new ProteusStaffEffect(this); } - + @java.lang.Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); @@ -100,7 +100,7 @@ class ProteusStaffEffect extends OneShotEffect { if (owner != null && controller != null) { // Put target creature on the bottom of its owner's library. owner.moveCardToLibraryWithInfo(permanent, source.getSourceId(), game, Zone.BATTLEFIELD, false, true); - + // That creature's controller reveals cards from the top of his or her library until he or she reveals a creature card. Cards cards = new CardsImpl(); while (controller.getLibrary().size() > 0) { @@ -108,16 +108,15 @@ class ProteusStaffEffect extends OneShotEffect { if (card != null) { if (card.getCardType().contains(CardType.CREATURE)) { // The player puts that card onto the battlefield - controller.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; - } - else { + } else { cards.add(card); } } } controller.revealCards("Proteus Staff", cards, game); - + // and the rest on the bottom of his or her library in any order. while (cards.size() > 0 && controller.canRespond()) { if (cards.size() == 1) { @@ -125,9 +124,8 @@ class ProteusStaffEffect extends OneShotEffect { if (card != null) { controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); cards.remove(card); - } - } - else { + } + } else { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on bottom of your library (last chosen will be on bottom)")); controller.choose(Outcome.Neutral, cards, target, game); Card card = cards.get(target.getFirstTarget(), game); diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java index df35e2d49d7..90520e0a75a 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/TezzeretAgentOfBolas.java @@ -1,16 +1,16 @@ /* * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,16 +20,17 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ package mage.sets.mirrodinbesieged; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.Effect; @@ -37,13 +38,11 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -52,8 +51,6 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetArtifactPermanent; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -61,6 +58,7 @@ import java.util.UUID; public class TezzeretAgentOfBolas extends CardImpl { private static final FilterCard filter = new FilterCard("an artifact card"); + static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); } @@ -70,8 +68,7 @@ public class TezzeretAgentOfBolas extends CardImpl { this.expansionSetCode = "MBS"; this.subtype.add("Tezzeret"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Look at the top five cards of your library. You may reveal an artifact card from among them and put it into your hand. Put the rest on the bottom of your library in any order. this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(5, 1, filter, true), 1)); @@ -80,7 +77,7 @@ public class TezzeretAgentOfBolas extends CardImpl { Effect effect = new AddCardTypeTargetEffect(CardType.CREATURE, Duration.EndOfGame); effect.setText("Target artifact becomes an artifact creature"); LoyaltyAbility ability1 = new LoyaltyAbility(effect, -1); - effect = new SetPowerToughnessTargetEffect(5,5, Duration.EndOfGame); + effect = new SetPowerToughnessTargetEffect(5, 5, Duration.EndOfGame); effect.setText("with base power and toughness 5/5"); ability1.addEffect(effect); ability1.addTarget(new TargetArtifactPermanent()); diff --git a/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java b/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java index 61a7cc1e97e..6f652e82b4e 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java +++ b/Mage.Sets/src/mage/sets/modernmasters/Epochrasite.java @@ -67,7 +67,7 @@ public class Epochrasite extends CardImpl { // Epochrasite enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), - new InvertCondition(new CastFromHandCondition()), true, + new InvertCondition(new CastFromHandCondition()), "{this} enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand",""), new CastFromHandWatcher()); diff --git a/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java b/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java index 31277520f32..d790518da10 100644 --- a/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java +++ b/Mage.Sets/src/mage/sets/modernmasters2015/WorldheartPhoenix.java @@ -139,7 +139,7 @@ public class WorldheartPhoenix extends CardImpl { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { // TODO: No perfect solution because there could be other effects that allow to cast the card for this mana cost if (spellAbility.getManaCosts().getText().equals("{W}{U}{B}{R}{G}")) { permanent.addCounters(CounterType.P1P1.createInstance(2), game); diff --git a/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java b/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java index 51657bef406..039cbc3f889 100644 --- a/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java +++ b/Mage.Sets/src/mage/sets/morningtide/BramblewoodParagon.java @@ -52,8 +52,9 @@ import mage.game.permanent.Permanent; * @author emerald000 */ public class BramblewoodParagon extends CardImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Each creature you control with a +1/+1 counter on it"); + static { filter.add(new CounterPredicate(CounterType.P1P1)); } @@ -68,15 +69,15 @@ public class BramblewoodParagon extends CardImpl { // Each other Warrior creature you control enters the battlefield with an additional +1/+1 counter on it. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BramblewoodParagonReplacementEffect())); - + // Each creature you control with a +1/+1 counter on it has trample. this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, + Zone.BATTLEFIELD, new GainAbilityAllEffect( - TrampleAbility.getInstance(), - Duration.WhileOnBattlefield, + TrampleAbility.getInstance(), + Duration.WhileOnBattlefield, filter))); - + } public BramblewoodParagon(final BramblewoodParagon card) { @@ -99,16 +100,16 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { BramblewoodParagonReplacementEffect(BramblewoodParagonReplacementEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = game.getPermanentEntering(event.getTargetId()); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.hasSubtype("Warrior") && !event.getTargetId().equals(source.getSourceId()); @@ -116,14 +117,13 @@ class BramblewoodParagonReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } return false; } - @Override public BramblewoodParagonReplacementEffect copy() { return new BramblewoodParagonReplacementEffect(this); diff --git a/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java b/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java index 624ac5cf2dc..2199b73e735 100644 --- a/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java +++ b/Mage.Sets/src/mage/sets/morningtide/OonasBlackguard.java @@ -102,7 +102,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.hasSubtype("Rogue") @@ -119,7 +119,7 @@ class OonasBlackguardReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } diff --git a/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java b/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java index a1fdaf96195..e4841e300df 100644 --- a/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java +++ b/Mage.Sets/src/mage/sets/morningtide/RecrossThePaths.java @@ -54,9 +54,9 @@ public class RecrossThePaths extends CardImpl { super(ownerId, 133, "Recross the Paths", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{G}"); this.expansionSetCode = "MOR"; - // Reveal cards from the top of your library until you reveal a land card. Put that card onto the battlefield and the rest on the bottom of your library in any order. + // Reveal cards from the top of your library until you reveal a land card. Put that card onto the battlefield and the rest on the bottom of your library in any order. this.getSpellAbility().addEffect(new RecrossThePathsEffect()); - + // Clash with an opponent. If you win, return Recross the Paths to its owner's hand. this.getSpellAbility().addEffect(ClashWinReturnToHandSpellEffect.getInstance()); } @@ -96,23 +96,23 @@ class RecrossThePathsEffect extends OneShotEffect { if (controller == null || sourceObject == null) { return false; } - + Cards cards = new CardsImpl(); Card cardFound = null; while (controller.getLibrary().size() > 0) { Card card = controller.getLibrary().removeFromTop(game); if (card != null) { - cards.add(card); - if (filter.match(card, game)){ + cards.add(card); + if (filter.match(card, game)) { cardFound = card; break; } - } + } } if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getName(), cards, game); + controller.revealCards(sourceObject.getIdName(), cards, game); if (cardFound != null) { - controller.putOntoBattlefieldWithInfo(cardFound, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(cardFound, Zone.BATTLEFIELD, source, game); cards.remove(cardFound); } controller.putCardsOnBottomOfLibrary(cards, game, source, true); diff --git a/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java b/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java index c7a423909b4..a634409057b 100644 --- a/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java +++ b/Mage.Sets/src/mage/sets/morningtide/SageOfFables.java @@ -64,7 +64,7 @@ public class SageOfFables extends CardImpl { // Each other Wizard creature you control enters the battlefield with an additional +1/+1 counter on it. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SageOfFablesReplacementEffect())); - + // {2}, Remove a +1/+1 counter from a creature you control: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); @@ -91,16 +91,16 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { SageOfFablesReplacementEffect(SageOfFablesReplacementEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); - return creature != null && creature.getControllerId().equals(source.getControllerId()) + Permanent creature = game.getPermanentEntering(event.getTargetId()); + return creature != null && creature.getControllerId().equals(source.getControllerId()) && creature.getCardType().contains(CardType.CREATURE) && creature.getSubtype().contains("Wizard") && !event.getTargetId().equals(source.getSourceId()); @@ -113,14 +113,13 @@ class SageOfFablesReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); if (creature != null) { creature.addCounters(CounterType.P1P1.createInstance(), game); } return false; } - @Override public SageOfFablesReplacementEffect copy() { return new SageOfFablesReplacementEffect(this); diff --git a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java index 6b1311d8f0e..f2c46b36031 100644 --- a/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java +++ b/Mage.Sets/src/mage/sets/nemesis/ParallaxWave.java @@ -36,7 +36,6 @@ import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.keyword.FadingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; @@ -60,10 +59,9 @@ public class ParallaxWave extends CardImpl { super(ownerId, 17, "Parallax Wave", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}"); this.expansionSetCode = "NMS"; - // Fading 5 this.addAbility(new FadingAbility(5, this)); - + // Remove a fade counter from Parallax Wave: Exile target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new RemoveCountersSourceCost(CounterType.FADE.createInstance())); ability.addTarget(new TargetCreaturePermanent()); @@ -103,21 +101,16 @@ class ParallaxWaveEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null) { - int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() -1; + Player controller = game.getPlayer(source.getControllerId()); + if (sourceObject != null && controller != null) { + int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1; UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter); if (exileZoneId != null) { ExileZone exileZone = game.getExile().getExileZone(exileZoneId); if (exileZone != null) { - for (Card card: exileZone.getCards(game)) { - Player player = game.getPlayer(card.getOwnerId()); - if (player != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - } - exileZone.clear(); + return controller.moveCards(exileZone.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null); } - return true; + return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java b/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java index 2fef2672aa1..d7cdb54f046 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/DueRespect.java @@ -28,14 +28,14 @@ package mage.sets.newphyrexia; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -50,7 +50,6 @@ public class DueRespect extends CardImpl { super(ownerId, 8, "Due Respect", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{W}"); this.expansionSetCode = "NPH"; - // Permanents enter the battlefield tapped this turn. this.getSpellAbility().addEffect(new DueRespectEffect()); // Draw a card. @@ -85,18 +84,18 @@ class DueRespectEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); if (permanent != null) { permanent.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { return true; diff --git a/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java b/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java index 5b5a30d8035..e51d4c7d16e 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/KarnLiberated.java @@ -34,11 +34,10 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileFromZoneTargetEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -47,7 +46,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.game.ExileZone; import mage.game.Game; @@ -72,7 +70,7 @@ public class KarnLiberated extends CardImpl { super(ownerId, 1, "Karn Liberated", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{7}"); this.expansionSetCode = "NPH"; this.subtype.add("Karn"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); // +4: Target player exiles a card from his or her hand. LoyaltyAbility ability1 = new LoyaltyAbility(new ExileFromZoneTargetEffect(Zone.HAND, exileId, this.getIdName(), new FilterCard()), 4); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java b/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java index 5f88e32d91f..6f7bf4cf1a4 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/OmenMachine.java @@ -28,11 +28,6 @@ package mage.sets.newphyrexia; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.BeginningOfDrawTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -40,7 +35,12 @@ import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.TargetController; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -125,9 +125,8 @@ class OmenMachineEffect2 extends OneShotEffect { if (card != null) { player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); if (card.getCardType().contains(CardType.LAND)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); - } - else { + player.moveCards(card, Zone.BATTLEFIELD, source, game); + } else { if (card.getSpellAbility().canChooseTarget(game)) { player.cast(card.getSpellAbility(), game, true); } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java b/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java index 59519623423..eb91ef9938c 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/TorporOrb.java @@ -40,6 +40,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -77,23 +78,24 @@ class TorporOrbEffect extends ContinuousRuleModifyingEffectImpl { TorporOrbEffect(final TorporOrbEffect effect) { super(effect); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { Ability ability = (Ability) getValue("targetAbility"); if (ability != null && AbilityType.TRIGGERED.equals(ability.getAbilityType())) { - Permanent p = game.getPermanent(event.getTargetId()); - if (p != null && p.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } return false; } + @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(event.getSourceId()); @@ -103,7 +105,7 @@ class TorporOrbEffect extends ContinuousRuleModifyingEffectImpl { } return null; } - + @Override public TorporOrbEffect copy() { return new TorporOrbEffect(this); diff --git a/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java b/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java index 45d79931645..6dd467f88fb 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/UrabraskTheHidden.java @@ -28,16 +28,18 @@ package mage.sets.newphyrexia; import java.util.UUID; - -import mage.constants.*; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.HasteAbility; -import mage.cards.Card; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -74,6 +76,7 @@ public class UrabraskTheHidden extends CardImpl { } class UrabraskTheHiddenEffect extends ReplacementEffectImpl { + UrabraskTheHiddenEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Creatures your opponents control enter the battlefield tapped"; @@ -85,7 +88,7 @@ class UrabraskTheHiddenEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } @@ -96,21 +99,20 @@ class UrabraskTheHiddenEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Card card = game.getCard(event.getTargetId()); - if (card != null && card.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = game.getPermanentEntering(event.getTargetId()); + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } return false; } - @Override public UrabraskTheHiddenEffect copy() { return new UrabraskTheHiddenEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java b/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java index 39c827a0a17..e06118df4fa 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java +++ b/Mage.Sets/src/mage/sets/planarchaos/FrozenAEther.java @@ -67,6 +67,7 @@ public class FrozenAEther extends CardImpl { } class FrozenAEtherTapEffect extends ReplacementEffectImpl { + FrozenAEtherTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts, creatures, and lands your opponents control enter the battlefield tapped"; @@ -78,7 +79,7 @@ class FrozenAEtherTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } @@ -89,15 +90,15 @@ class FrozenAEtherTapEffect extends ReplacementEffectImpl { public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && - (permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND) || - permanent.getCardType().contains(CardType.ARTIFACT))) { + Permanent permanent = game.getPermanentEntering(event.getTargetId()); + if (permanent != null + && (permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND) + || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java index 4505e346779..92ebfdb6731 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java +++ b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java @@ -34,7 +34,6 @@ import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.NameACardEffect; import mage.abilities.keyword.FlyingAbility; @@ -102,7 +101,7 @@ class VoidstoneGargoyleChooseCardEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && permanent != null) { Choice cardChoice = new ChoiceImpl(); cardChoice.setChoices(CardRepository.instance.getNonLandNames()); diff --git a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java index 4d91881eea1..78d965850c7 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java +++ b/Mage.Sets/src/mage/sets/planechase2012/PrimalPlasma.java @@ -66,7 +66,7 @@ public class PrimalPlasma extends CardImpl { this.toughness = new MageInt(0); // As Primal Plasma enters the battlefield, it becomes your choice of a 3/3 creature, a 2/2 creature with flying, or a 1/6 creature with defender. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PrimalPlasmaReplacementEffect())); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new PrimalPlasmaReplacementEffect())); } public PrimalPlasma(final PrimalPlasma card) { @@ -102,7 +102,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -117,7 +117,7 @@ class PrimalPlasmaReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what " + permanent.getIdName() + " becomes to"); diff --git a/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java b/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java index e16d11cbd58..2797a6b8908 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java +++ b/Mage.Sets/src/mage/sets/planechase2012/SakashimasStudent.java @@ -29,19 +29,16 @@ package mage.sets.planechase2012; import java.util.UUID; import mage.MageInt; -import mage.MageObject; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.keyword.NinjutsuAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.util.functions.ApplyToPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.util.functions.AddSubtypeApplier; /** * @@ -60,11 +57,11 @@ public class SakashimasStudent extends CardImpl { // Ninjutsu {1}{U} this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{1}{U}"))); + // You may have Sakashima's Student enter the battlefield as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(new SakashimasStudentApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new AddSubtypeApplier("Ninja")); + effect.setText("as a copy of any creature on the battlefield, except it's still a Ninja in addition to its other creature types"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } @@ -77,23 +74,3 @@ public class SakashimasStudent extends CardImpl { return new SakashimasStudent(this); } } - -class SakashimasStudentApplyToPermanent extends ApplyToPermanent { - - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSubtype().contains("Ninja")) { - permanent.getSubtype().add("Ninja"); - } - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSubtype().contains("Ninja")) { - mageObject.getSubtype().add("Ninja"); - } - return true; - } - -} diff --git a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java index 0125728af80..0bdfbb25581 100644 --- a/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java +++ b/Mage.Sets/src/mage/sets/planeshift/ArcticMerfolk.java @@ -61,8 +61,7 @@ public class ArcticMerfolk extends CardImpl { // If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it. this.addAbility(new EntersBattlefieldAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - KickedCondition.getInstance(), - true,"If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.","")); + KickedCondition.getInstance(),"If Arctic Merfolk was kicked, it enters the battlefield with a +1/+1 counter on it.","")); } public ArcticMerfolk(final ArcticMerfolk card) { diff --git a/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java b/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java index 5a94ca0d4ee..bf5b2311558 100644 --- a/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java +++ b/Mage.Sets/src/mage/sets/planeshift/DralnusPet.java @@ -75,7 +75,7 @@ public class DralnusPet extends CardImpl { kickerCosts.add(new DiscardCardCost(new FilterCreatureCard())); this.addAbility(new KickerAbility(kickerCosts)); // If Dralnu's Pet was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost. - Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.getInstance(), true, + Ability ability = new EntersBattlefieldAbility(new DralnusPetEffect(), KickedCondition.getInstance(), "If {this} was kicked, it enters the battlefield with flying and with X +1/+1 counters on it, where X is the discarded card's converted mana cost", ""); ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); this.addAbility(ability); @@ -115,7 +115,7 @@ class DralnusPetEffect extends OneShotEffect { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { int cmc = 0; for (Cost cost : spellAbility.getCosts()) { if (cost instanceof DiscardCardCost && ((DiscardCardCost) cost).getCards().size() > 0) { diff --git a/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java b/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java index 5a43de13839..8dae36a679d 100644 --- a/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java +++ b/Mage.Sets/src/mage/sets/planeshift/PhyrexianScuta.java @@ -56,8 +56,7 @@ public class PhyrexianScuta extends CardImpl { // Kicker-Pay 3 life. this.addAbility(new KickerAbility(new PayLifeCost(3))); // If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it. - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), - true, "If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it.", "")); + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), "If Phyrexian Scuta was kicked, it enters the battlefield with two +1/+1 counters on it.", "")); } public PhyrexianScuta(final PhyrexianScuta card) { diff --git a/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java b/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java index f8c469ed658..e1a02355e1b 100644 --- a/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java +++ b/Mage.Sets/src/mage/sets/ravnica/CopyEnchantment.java @@ -30,16 +30,14 @@ package mage.sets.ravnica; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.SpellAbility; -import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterEnchantmentPermanent; import mage.game.Game; @@ -58,13 +56,8 @@ public class CopyEnchantment extends CardImpl { super(ownerId, 42, "Copy Enchantment", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); this.expansionSetCode = "RAV"; - // You may have Copy Enchantment enter the battlefield as a copy of any enchantment on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyEnchantmentEffect(new FilterEnchantmentPermanent()), - "You may have {this} enter the battlefield as a copy of any enchantment on the battlefield", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyEnchantmentEffect(new FilterEnchantmentPermanent("any enchantment")), true)); } public CopyEnchantment(final CopyEnchantment card) { @@ -82,15 +75,15 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { public CopyEnchantmentEffect(FilterPermanent filter) { super(filter, new EmptyApplyToPermanent()); } - + public CopyEnchantmentEffect(final CopyEnchantmentEffect effect) { super(effect); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && sourcePermanent != null) { if (super.apply(game, source)) { Permanent permanentToCopy = getBluePrintPermanent(); @@ -98,9 +91,10 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { if (permanentToCopy.getSubtype().contains("Aura")) { Target target = getBluePrintPermanent().getSpellAbility().getTargets().get(0); Outcome auraOutcome = Outcome.BoostCreature; - Ability: for (Ability ability: getBluePrintPermanent().getAbilities()) { + Ability: + for (Ability ability : getBluePrintPermanent().getAbilities()) { if (ability instanceof SpellAbility) { - for (Effect effect: ability.getEffects()) { + for (Effect effect : ability.getEffects()) { if (effect instanceof AttachEffect) { auraOutcome = effect.getOutcome(); break Ability; @@ -108,6 +102,7 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { } } } + target.setNotTarget(true); if (controller.choose(auraOutcome, target, source.getSourceId(), game)) { UUID targetId = target.getFirstTarget(); Permanent targetPermanent = game.getPermanent(targetId); @@ -127,10 +122,10 @@ class CopyEnchantmentEffect extends CopyPermanentEffect { } return false; } - + @Override public CopyEnchantmentEffect copy() { return new CopyEnchantmentEffect(this); } - + } diff --git a/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java b/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java index 5b4297fba72..fd8a62fde94 100644 --- a/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java +++ b/Mage.Sets/src/mage/sets/ravnica/LoxodonGatekeeper.java @@ -30,20 +30,19 @@ package mage.sets.ravnica; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.cards.CardImpl; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; - /** * * @author fireshoes @@ -75,6 +74,7 @@ public class LoxodonGatekeeper extends CardImpl { } class LoxodonGatekeeperTapEffect extends ReplacementEffectImpl { + LoxodonGatekeeperTapEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts, creatures, and lands your opponents control enter the battlefield tapped"; @@ -86,26 +86,26 @@ class LoxodonGatekeeperTapEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && - (permanent.getCardType().contains(CardType.CREATURE) || - permanent.getCardType().contains(CardType.LAND) || - permanent.getCardType().contains(CardType.ARTIFACT))) { + Permanent permanent = game.getPermanentEntering(event.getTargetId()); + if (permanent != null + && (permanent.getCardType().contains(CardType.CREATURE) + || permanent.getCardType().contains(CardType.LAND) + || permanent.getCardType().contains(CardType.ARTIFACT))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java b/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java index 91dd5a1a86c..10bf030e45a 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/CorpsejackMenace.java @@ -28,30 +28,30 @@ package mage.sets.returntoravnica; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; /** - * http://www.wizards.com/magic/magazine/article.aspx?x=mtg/faq/rtr + * http://www.wizards.com/magic/magazine/article.aspx?x=mtg/faq/rtr * - * If a creature you control would enter the battlefield with a number of +1/+1 - * counters on it, it enters with twice that many instead. + * If a creature you control would enter the battlefield with a number of +1/+1 + * counters on it, it enters with twice that many instead. * - * If you control two Corpsejack Menaces, the number of +1/+1 counters placed - * is four times the original number. Three Corpsejack Menaces multiplies the - * original number by eight, and so on. + * If you control two Corpsejack Menaces, the number of +1/+1 counters placed is + * four times the original number. Three Corpsejack Menaces multiplies the + * original number by eight, and so on. * * @author LevelX2 */ @@ -80,8 +80,8 @@ public class CorpsejackMenace extends CardImpl { } } - class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl { + CorpsejackMenaceReplacementEffect() { super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false); staticText = "If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead"; @@ -93,24 +93,30 @@ class CorpsejackMenaceReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent p = game.getPermanent(event.getTargetId()); - if (p != null) { - p.addCounters(CounterType.P1P1.createInstance(event.getAmount()*2), game, event.getAppliedEffects()); + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(event.getAmount() * 2), game, event.getAppliedEffects()); } return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ADD_COUNTERS; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getData().equals(CounterType.P1P1.getName())) { - Permanent target = game.getPermanent(event.getTargetId()); - if (target != null && target.getControllerId().equals(source.getControllerId()) - && target.getCardType().contains(CardType.CREATURE)) { + Permanent permanent = game.getPermanent(event.getTargetId()); + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getControllerId().equals(source.getControllerId()) + && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java index 93753306a08..cdce3f264d5 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/JaceArchitectOfThought.java @@ -34,11 +34,10 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; import mage.game.ExileZone; @@ -76,7 +74,7 @@ public class JaceArchitectOfThought extends CardImpl { this.expansionSetCode = "RTR"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Until your next turn, whenever a creature an opponent controls attacks, it gets -1/-0 until end of turn. this.addAbility(new LoyaltyAbility(new JaceArchitectOfThoughtStartEffect1(), 1)); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java b/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java index c13d4cf6131..5d838ca5ddd 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/TabletOfTheGuilds.java @@ -32,7 +32,6 @@ import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.choices.ChoiceColor; @@ -86,7 +85,7 @@ class TabletOfTheGuildsEntersBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (player != null && permanent != null) { String colors; ChoiceColor colorChoice = new ChoiceColor(); diff --git a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java index 3c890808dd2..776fd85498b 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java @@ -33,13 +33,12 @@ import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseGameTargetPlayerEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.game.Game; import mage.game.events.DamagedPlaneswalkerEvent; import mage.game.events.GameEvent; @@ -76,7 +74,7 @@ public class VraskaTheUnseen extends CardImpl { this.expansionSetCode = "RTR"; this.subtype.add("Vraska"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Until your next turn, whenever a creature deals combat damage to Vraska the Unseen, destroy that creature. this.addAbility(new LoyaltyAbility(new VraskaTheUnseenGainAbilityEffect(new VraskaTheUnseenTriggeredAbility()), 1)); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java index 45fdec326b5..52140b5319a 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/GideonJura.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.riseoftheeldrazi; import java.util.UUID; @@ -33,19 +32,17 @@ import mage.MageInt; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.RequirementEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.PreventAllDamageToSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.TurnPhase; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; @@ -71,9 +68,8 @@ public class GideonJura extends CardImpl { this.expansionSetCode = "ROE"; this.subtype.add("Gideon"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(6)), false)); - // +2: During target opponent's next turn, creatures that player controls attack Gideon Jura if able. LoyaltyAbility ability1 = new LoyaltyAbility(new GideonJuraEffect(), 2); ability1.addTarget(new TargetOpponent()); @@ -148,9 +144,9 @@ class GideonJuraEffect extends RequirementEffect { @Override public boolean isInactive(Ability source, Game game) { - return (startingTurn != game.getTurnNum() && - (game.getPhase().getType() == TurnPhase.END && - game.getActivePlayerId().equals(source.getFirstTarget()))) + return (startingTurn != game.getTurnNum() + && (game.getPhase().getType() == TurnPhase.END + && game.getActivePlayerId().equals(source.getFirstTarget()))) || // 6/15/2010: If a creature controlled by the affected player can't attack Gideon Jura (because he's no longer on the battlefield, for example), that player may have it attack you, another one of your planeswalkers, or nothing at all. creatingPermanent.getPermanent(game) == null; } @@ -169,4 +165,4 @@ class GideonJuraEffect extends RequirementEffect { public boolean mustBlock(Game game) { return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java index 8cdd3585f79..8252432060e 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/SarkhanTheMad.java @@ -33,9 +33,8 @@ import mage.MageInt; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardsImpl; @@ -43,7 +42,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -65,7 +63,7 @@ public class SarkhanTheMad extends CardImpl { super(ownerId, 214, "Sarkhan the Mad", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{B}{R}"); this.expansionSetCode = "ROE"; this.subtype.add("Sarkhan"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(7)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(7)); this.addAbility(new LoyaltyAbility(new SarkhanTheMadRevealAndDrawEffect(), 0)); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java index 2b68b4fc8c4..67375b8e9c8 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/WallOfOmens.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,22 +20,21 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.riseoftheeldrazi; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -51,7 +50,10 @@ public class WallOfOmens extends CardImpl { this.power = new MageInt(0); this.toughness = new MageInt(4); + // Defender this.addAbility(DefenderAbility.getInstance()); + + // When Wall of Omens enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); } diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java index 3a4232607be..f468e0e748b 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/SakashimaTheImpostor.java @@ -30,26 +30,21 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.EntersBattlefieldEffect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; import mage.util.functions.ApplyToPermanent; /** @@ -58,8 +53,6 @@ import mage.util.functions.ApplyToPermanent; */ public class SakashimaTheImpostor extends CardImpl { - private static final String abilityText = "You may have {this} enter the battlefield as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains \"{2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step.\""; - public SakashimaTheImpostor(UUID ownerId) { super(ownerId, 53, "Sakashima the Impostor", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); this.expansionSetCode = "SOK"; @@ -70,9 +63,9 @@ public class SakashimaTheImpostor extends CardImpl { this.toughness = new MageInt(1); // You may have Sakashima the Impostor enter the battlefield as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains "{2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step." - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new SakashimaTheImpostorCopyEffect(), abilityText, true)); - this.addAbility(ability); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new SakashimaTheImpostorApplier()); + effect.setText("as a copy of any creature on the battlefield, except its name is still Sakashima the Impostor, it's legendary in addition to its other types, and it gains \"{2}{U}{U}: Return {this} to its owner's hand at the beginning of the next end step.\""); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public SakashimaTheImpostor(final SakashimaTheImpostor card) { @@ -85,67 +78,34 @@ public class SakashimaTheImpostor extends CardImpl { } } -class SakashimaTheImpostorCopyEffect extends OneShotEffect { - - public SakashimaTheImpostorCopyEffect() { - super(Outcome.Copy); - } - - public SakashimaTheImpostorCopyEffect(final SakashimaTheImpostorCopyEffect effect) { - super(effect); - } +class SakashimaTheImpostorApplier extends ApplyToPermanent { @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - Target target = new TargetPermanent(new FilterCreaturePermanent()); - target.setNotTarget(true); - if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) { - player.choose(Outcome.Copy, target, source.getSourceId(), game); - Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget()); - if (copyFromPermanent != null) { - game.copyPermanent(copyFromPermanent, sourceObject.getId(), source, new ApplyToPermanent() { - @Override - public Boolean apply(Game game, Permanent permanent) { - if (!permanent.getSupertype().contains("Legendary")) { - permanent.getSubtype().add("Legendary"); - } - permanent.setName("Sakashima the Impostor"); - // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step - permanent.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), - new ManaCostsImpl("{2}{U}{U}") - ), game); - return true; - } - - @Override - public Boolean apply(Game game, MageObject mageObject) { - if (!mageObject.getSupertype().contains("Legendary")) { - mageObject.getSubtype().add("Legendary"); - } - mageObject.setName("Sakashima the Impostor"); - // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step - mageObject.getAbilities().add(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), - new ManaCostsImpl("{2}{U}{U}") - )); - return true; - } - - }); - - return true; - } - } + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSupertype().contains("Legendary")) { + permanent.getSubtype().add("Legendary"); } - return false; + permanent.setName("Sakashima the Impostor"); + // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step + permanent.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), + new ManaCostsImpl("{2}{U}{U}") + ), game); + return true; } @Override - public SakashimaTheImpostorCopyEffect copy() { - return new SakashimaTheImpostorCopyEffect(this); + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSupertype().contains("Legendary")) { + mageObject.getSubtype().add("Legendary"); + } + mageObject.setName("Sakashima the Impostor"); + // {2}{U}{U}: Return Sakashima the Impostor to its owner's hand at the beginning of the next end step + mageObject.getAbilities().add(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ReturnToHandSourceEffect(true)), false), + new ManaCostsImpl("{2}{U}{U}") + )); + return true; } + } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java index 9de094b78e4..893edc2be14 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/ElspethTirel.java @@ -25,20 +25,18 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.scarsofmirrodin; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -46,28 +44,25 @@ import mage.game.permanent.PermanentToken; import mage.game.permanent.token.SoldierToken; import mage.players.Player; -import java.util.UUID; - /** * * @author Loki */ public class ElspethTirel extends CardImpl { - public ElspethTirel (UUID ownerId) { + public ElspethTirel(UUID ownerId) { super(ownerId, 6, "Elspeth Tirel", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{W}"); this.expansionSetCode = "SOM"; this.subtype.add("Elspeth"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); this.addAbility(new LoyaltyAbility(new ElspethTirelFirstEffect(), 2)); this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken(), 3), -2)); this.addAbility(new LoyaltyAbility(new ElspethTirelThirdEffect(), -5)); } - public ElspethTirel (final ElspethTirel card) { + public ElspethTirel(final ElspethTirel card) { super(card); } @@ -78,6 +73,7 @@ public class ElspethTirel extends CardImpl { } class ElspethTirelFirstEffect extends OneShotEffect { + public ElspethTirelFirstEffect() { super(Outcome.GainLife); staticText = "You gain 1 life for each creature you control"; @@ -105,6 +101,7 @@ class ElspethTirelFirstEffect extends OneShotEffect { } class ElspethTirelThirdEffect extends OneShotEffect { + public ElspethTirelThirdEffect() { super(Outcome.DestroyPermanent); staticText = "Destroy all other permanents except for lands and tokens"; @@ -116,9 +113,10 @@ class ElspethTirelThirdEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Permanent perm: game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { - if (!perm.getId().equals(source.getSourceId()) && !(perm instanceof PermanentToken) && ! (perm.getCardType().contains(CardType.LAND))) + for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { + if (!perm.getId().equals(source.getSourceId()) && !(perm instanceof PermanentToken) && !(perm.getCardType().contains(CardType.LAND))) { perm.destroy(source.getSourceId(), game, false); + } } return true; } @@ -128,4 +126,4 @@ class ElspethTirelThirdEffect extends OneShotEffect { return new ElspethTirelThirdEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java index c9c727992b0..1af105c5b8e 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/KothOfTheHammer.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.scarsofmirrodin; import java.util.UUID; @@ -33,7 +32,7 @@ import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.TapSourceCost; @@ -44,7 +43,6 @@ import mage.abilities.effects.common.DynamicManaEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.continuous.BecomesCreatureTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -54,7 +52,6 @@ import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; @@ -70,6 +67,7 @@ import mage.target.common.TargetLandPermanent; * @author Loki, North */ public class KothOfTheHammer extends CardImpl { + static final FilterLandPermanent filter = new FilterLandPermanent("Mountain"); private static final FilterLandPermanent filterCount = new FilterLandPermanent("Mountain you control"); @@ -80,15 +78,13 @@ public class KothOfTheHammer extends CardImpl { filterCount.add(new ControllerPredicate(TargetController.YOU)); } - public KothOfTheHammer (UUID ownerId) { + public KothOfTheHammer(UUID ownerId) { super(ownerId, 94, "Koth of the Hammer", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{R}"); this.expansionSetCode = "SOM"; this.subtype.add("Koth"); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - // +1: Untap target Mountain. It becomes a 4/4 red Elemental creature until end of turn. It's still a land. Ability ability = new LoyaltyAbility(new UntapTargetEffect(), 1); ability.addEffect(new BecomesCreatureTargetEffect(new KothOfTheHammerToken(), false, true, Duration.EndOfTurn)); @@ -102,7 +98,7 @@ public class KothOfTheHammer extends CardImpl { this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new KothOfTheHammerEmblem()), -5)); } - public KothOfTheHammer (final KothOfTheHammer card) { + public KothOfTheHammer(final KothOfTheHammer card) { super(card); } @@ -111,6 +107,7 @@ public class KothOfTheHammer extends CardImpl { return new KothOfTheHammer(this); } } + class KothOfTheHammerToken extends Token { public KothOfTheHammerToken() { @@ -125,7 +122,9 @@ class KothOfTheHammerToken extends Token { } class KothOfTheHammerEmblem extends Emblem { + // "Mountains you control have '{T}: This land deals 1 damage to target creature or player.'" + public KothOfTheHammerEmblem() { this.setName("EMBLEM: Koth of the Hammer"); this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new KothOfTheHammerThirdEffect())); @@ -133,6 +132,7 @@ class KothOfTheHammerEmblem extends Emblem { } class KothOfTheHammerThirdEffect extends ContinuousEffectImpl { + public KothOfTheHammerThirdEffect() { super(Duration.EndOfGame, Outcome.AddAbility); staticText = "You get an emblem with \"Mountains you control have '{T}: This land deals 1 damage to target creature or player.'\""; diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java index 2f4def3ecfd..b3d27b48775 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/VenserTheSojourner.java @@ -32,7 +32,7 @@ import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -40,7 +40,6 @@ import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.ReturnFromExileEffect; import mage.abilities.effects.common.combat.CantBeBlockedAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterPermanent; import mage.filter.FilterSpell; import mage.filter.common.FilterCreaturePermanent; @@ -80,7 +78,7 @@ public class VenserTheSojourner extends CardImpl { this.expansionSetCode = "SOM"; this.subtype.add("Venser"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Exile target permanent you own. Return it to the battlefield under your control at the beginning of the next end step. LoyaltyAbility ability1 = new LoyaltyAbility(new VenserTheSojournerEffect(), 2); diff --git a/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java b/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java index 43423eb386c..9e94853f483 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/FlourishingDefenses.java @@ -51,7 +51,6 @@ public class FlourishingDefenses extends CardImpl { super(ownerId, 114, "Flourishing Defenses", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}"); this.expansionSetCode = "SHM"; - // Whenever a -1/-1 counter is placed on a creature, you may put a 1/1 green Elf Warrior creature token onto the battlefield. this.addAbility(new FlourishingDefensesTriggeredAbility()); @@ -91,7 +90,10 @@ class FlourishingDefensesTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getData().equals(CounterType.M1M1.getName())) { Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId()); - if (permanent.getCardType().contains(CardType.CREATURE)) { + if (permanent == null) { + permanent = game.getPermanentEntering(event.getTargetId()); + } + if (permanent != null && permanent.getCardType().contains(CardType.CREATURE)) { return true; } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java b/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java index e94e6b2e98e..1f031527630 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/GlamerSpinners.java @@ -126,7 +126,8 @@ class GlamerSpinnersEffect extends OneShotEffect { LinkedList auras = new LinkedList<>(); auras.addAll(targetPermanent.getAttachments()); - if (controller.choose(Outcome.Neutral, chosenPermanentToAttachAuras, source.getSourceId(), game)) { + if (chosenPermanentToAttachAuras.canChoose(source.getSourceId(), source.getControllerId(), game) + && controller.choose(Outcome.Neutral, chosenPermanentToAttachAuras, source.getSourceId(), game)) { Permanent permanentToAttachAuras = game.getPermanent(chosenPermanentToAttachAuras.getFirstTarget()); if (permanentToAttachAuras != null) { for (UUID auraId : auras) { @@ -163,7 +164,7 @@ class GlamerSpinnersEffect extends OneShotEffect { } return true; } - + return false; } } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java index ee4ee7cc2ca..a21eeaa672c 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java @@ -1,46 +1,43 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effects; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DestroyAllControlledTargetEffect; -import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.target.TargetPermanent; @@ -52,7 +49,7 @@ import mage.target.common.TargetCreatureOrPlayer; * @author BetaSteward_at_googlemail.com */ public class AjaniVengeant extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("lands"); static { @@ -64,8 +61,7 @@ public class AjaniVengeant extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Ajani"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Target permanent doesn't untap during its controller's next untap step. LoyaltyAbility ability1 = new LoyaltyAbility(new DontUntapInControllersNextUntapStepTargetEffect(), 1); @@ -85,7 +81,6 @@ public class AjaniVengeant extends CardImpl { ability3.addTarget(new TargetPlayer()); this.addAbility(ability3); - } public AjaniVengeant(final AjaniVengeant card) { diff --git a/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java b/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java index b37b88c0d95..6cd0c9bdef5 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/ElspethKnightErrant.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,21 +20,16 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; @@ -43,11 +38,13 @@ import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.CardImpl; -import mage.counters.CounterType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -67,8 +64,7 @@ public class ElspethKnightErrant extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Elspeth"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put a 1/1 white Soldier creature token onto the battlefield. Token token = new SoldierToken(); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java b/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java index 4377e3fb628..43196e13e7b 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/SarkhanVol.java @@ -1,50 +1,47 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.sets.shardsofalara; -import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; -import mage.abilities.effects.common.continuous.BoostControlledEffect; import java.util.UUID; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.Effects; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.Effects; -import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.keyword.HasteAbility; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.DragonToken; import mage.target.common.TargetCreaturePermanent; @@ -62,8 +59,7 @@ public class SarkhanVol extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Sarkhan"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Creatures you control get +1/+1 and gain haste until end of turn. Effects effects1 = new Effects(); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java b/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java index 9cae9ec46d7..af865ed4cee 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/TezzeretTheSeeker.java @@ -31,13 +31,12 @@ import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.UntapTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; @@ -47,7 +46,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter.ComparisonType; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterArtifactPermanent; @@ -69,7 +67,7 @@ public class TezzeretTheSeeker extends CardImpl { this.expansionSetCode = "ALA"; this.subtype.add("Tezzeret"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Untap up to two target artifacts. LoyaltyAbility ability = new LoyaltyAbility(new UntapTargetEffect(), 1); diff --git a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java index 803b119ff50..3d57c2229d3 100644 --- a/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java +++ b/Mage.Sets/src/mage/sets/speedvscunning/AquamorphEntity.java @@ -65,11 +65,10 @@ public class AquamorphEntity extends CardImpl { this.toughness = new MageInt(0); // As Aquamorph Entity enters the battlefield or is turned face up, it becomes your choice of 5/1 or 1/5. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new AquamorphEntityReplacementEffect()); + Ability ability = new SimpleStaticAbility(Zone.ALL, new AquamorphEntityReplacementEffect()); ability.setWorksFaceDown(true); this.addAbility(ability); - // Morph {2}{U} this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{U}"))); } @@ -84,7 +83,6 @@ public class AquamorphEntity extends CardImpl { } } - class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { private final String choice51 = "a 5/1 creature"; @@ -101,7 +99,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { @Override public boolean checksEventType(GameEvent event, Game game) { - switch(event.getType()) { + switch (event.getType()) { case ENTERS_THE_BATTLEFIELD: case TURNFACEUP: return true; @@ -114,7 +112,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (sourcePermanent != null && !sourcePermanent.isFaceDown(game)) { return true; } @@ -135,7 +133,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { Choice choice = new ChoiceImpl(true); choice.setMessage("Choose what the creature becomes to"); @@ -143,7 +141,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { choice.getChoices().add(choice15); Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - while(!choice.isChosen()) { + while (!choice.isChosen()) { controller.choose(Outcome.Neutral, choice, game); if (!controller.canRespond()) { return false; @@ -168,7 +166,7 @@ class AquamorphEntityReplacementEffect extends ReplacementEffectImpl { } } return false; - + } @Override diff --git a/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java b/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java index a53c41a32c6..33b9e60a024 100644 --- a/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java +++ b/Mage.Sets/src/mage/sets/tempest/Dracoplasm.java @@ -69,10 +69,10 @@ public class Dracoplasm extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // As Dracoplasm enters the battlefield, sacrifice any number of creatures. Dracoplasm's power becomes the total power of those creatures and its toughness becomes their total toughness. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DracoplasmEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.ALL, new DracoplasmEffect())); + // {R}: Dracoplasm gets +1/+0 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.R))); } @@ -88,41 +88,41 @@ public class Dracoplasm extends CardImpl { } class DracoplasmEffect extends ReplacementEffectImpl { - + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); - + static { filter.add(new AnotherPredicate()); } - + public DracoplasmEffect() { - super(Duration.WhileOnBattlefield, Outcome.BoostCreature); + super(Duration.EndOfGame, Outcome.BoostCreature); this.staticText = "As {this} enters the battlefield, sacrifice any number of creatures. {this}'s power becomes the total power of those creatures and its toughness becomes their total toughness"; } - + public DracoplasmEffect(final DracoplasmEffect effect) { super(effect); } - + @Override public DracoplasmEffect copy() { return new DracoplasmEffect(this); } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - return event.getTargetId().equals(source.getSourceId()); + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true); @@ -133,7 +133,7 @@ class DracoplasmEffect extends ReplacementEffectImpl { if (target.getTargets().size() > 0) { int power = 0; int toughness = 0; - for (UUID targetId: target.getTargets()) { + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature != null && targetCreature.sacrifice(source.getSourceId(), game)) { power += targetCreature.getPower().getValue(); @@ -146,5 +146,5 @@ class DracoplasmEffect extends ReplacementEffectImpl { } return false; } - + } diff --git a/Mage.Sets/src/mage/sets/tempest/RootMaze.java b/Mage.Sets/src/mage/sets/tempest/RootMaze.java index 36109448c25..26835f74da4 100644 --- a/Mage.Sets/src/mage/sets/tempest/RootMaze.java +++ b/Mage.Sets/src/mage/sets/tempest/RootMaze.java @@ -67,6 +67,7 @@ public class RootMaze extends CardImpl { } class RootMazeEffect extends ReplacementEffectImpl { + RootMazeEffect() { super(Duration.WhileOnBattlefield, Outcome.Tap); staticText = "Artifacts and lands enter the battlefield tapped"; @@ -78,21 +79,21 @@ class RootMazeEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent target = game.getPermanent(event.getTargetId()); + Permanent target = game.getPermanentEntering(event.getTargetId()); if (target != null) { target.setTapped(true); } return false; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.ENTERS_THE_BATTLEFIELD; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getTargetId()); + Permanent permanent = game.getPermanentEntering(event.getTargetId()); return permanent != null && (permanent.getCardType().contains(CardType.LAND) || permanent.getCardType().contains(CardType.ARTIFACT)); } diff --git a/Mage.Sets/src/mage/sets/tenthedition/Clone.java b/Mage.Sets/src/mage/sets/tenthedition/Clone.java index 2412dacd079..6869479699a 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/Clone.java +++ b/Mage.Sets/src/mage/sets/tenthedition/Clone.java @@ -25,19 +25,15 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.tenthedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -54,11 +50,12 @@ public class Clone extends CardImpl { this.toughness = new MageInt(0); // You may have Clone enter the battlefield as a copy of any creature on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield", - true)); - this.addAbility(ability); +// ; +// Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( +// new CopyPermanentEffect(), +// "You may have {this} enter the battlefield as a copy of any creature on the battlefield", +// true)); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(), true)); } public Clone(final Clone card) { diff --git a/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java b/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java index eb3d8d91876..7edca1e49b4 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java +++ b/Mage.Sets/src/mage/sets/tenthedition/SculptingSteel.java @@ -28,14 +28,11 @@ package mage.sets.tenthedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -44,9 +41,9 @@ import mage.filter.predicate.mageobject.CardTypePredicate; * @author jeffwadsworth */ public class SculptingSteel extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("artifact"); - + static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); } @@ -56,11 +53,7 @@ public class SculptingSteel extends CardImpl { this.expansionSetCode = "10E"; // You may have Sculpting Steel enter the battlefield as a copy of any artifact on the battlefield. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect( - new CopyPermanentEffect(filter), - "You may have {this} enter the battlefield as a copy of any artifact on the battlefield", - true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public SculptingSteel(final SculptingSteel card) { diff --git a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java index 25c3342c95b..18d2eaee092 100644 --- a/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java +++ b/Mage.Sets/src/mage/sets/theros/AshiokNightmareWeaver.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.common.PayVariableLoyaltyCost; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -48,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.SubLayer; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; @@ -73,7 +71,7 @@ public class AshiokNightmareWeaver extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Ashiok"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Exile the top three cards of target opponent's library. LoyaltyAbility ability = new LoyaltyAbility(new AshiokNightmareWeaverExileEffect(), 2); diff --git a/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java b/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java index ec4d805c92a..1710de8c1c3 100644 --- a/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java +++ b/Mage.Sets/src/mage/sets/theros/ElspethSunsChampion.java @@ -30,21 +30,19 @@ package mage.sets.theros; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; @@ -58,6 +56,7 @@ import mage.game.permanent.token.SoldierToken; public class ElspethSunsChampion extends CardImpl { private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures with power 4 or greater"); + static { filter.add(new PowerPredicate(Filter.ComparisonType.GreaterThan, 3)); } @@ -67,8 +66,7 @@ public class ElspethSunsChampion extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Elspeth"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Put three 1/1 white Soldier creature tokens onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken(), 3), 1)); @@ -95,7 +93,7 @@ class ElspethSunsChampionEmblem extends Emblem { public ElspethSunsChampionEmblem() { this.setName("EMBLEM: Elspeth, Sun's Champion"); - Ability ability = new SimpleStaticAbility(Zone.COMMAND, new BoostControlledEffect(2,2, Duration.WhileOnBattlefield, filter, false)); + Ability ability = new SimpleStaticAbility(Zone.COMMAND, new BoostControlledEffect(2, 2, Duration.WhileOnBattlefield, filter, false)); ability.addEffect(new GainAbilityControlledEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield, filter)); this.getAbilities().add(ability); diff --git a/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java b/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java index 0166753702c..b71a4b0cc07 100644 --- a/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java +++ b/Mage.Sets/src/mage/sets/theros/XenagosTheReveler.java @@ -34,10 +34,9 @@ import mage.MageInt; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -49,7 +48,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.Predicates; @@ -70,20 +68,17 @@ public class XenagosTheReveler extends CardImpl { this.expansionSetCode = "THS"; this.subtype.add("Xenagos"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Add X mana in any combination of {R} and/or {G} to your mana pool, where X is the number of creatures you control. this.addAbility(new LoyaltyAbility(new XenagosManaEffect(), +1)); - + // 0: Put a 2/2 red and green Satyr creature token with haste onto the battlefield. this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new XenagosSatyrToken()), 0)); // -6: Exile the top seven cards of your library. You may put any number of creature and/or land cards from among them onto the battlefield. this.addAbility(new LoyaltyAbility(new XenagosExileEffect(), -6)); - - } public XenagosTheReveler(final XenagosTheReveler card) { @@ -115,7 +110,7 @@ class XenagosManaEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null){ + if (player != null) { int x = game.getBattlefield().count(new FilterControlledCreaturePermanent(), source.getSourceId(), source.getControllerId(), game); Choice manaChoice = new ChoiceImpl(); Set choices = new LinkedHashSet<>(); @@ -124,7 +119,7 @@ class XenagosManaEffect extends OneShotEffect { manaChoice.setChoices(choices); manaChoice.setMessage("Select color of mana to add"); - for (int i = 0; i < x; i++){ + for (int i = 0; i < x; i++) { Mana mana = new Mana(); while (!player.choose(Outcome.Benefit, manaChoice, game)) { if (!player.canRespond()) { @@ -150,7 +145,6 @@ class XenagosManaEffect extends OneShotEffect { } } - class XenagosSatyrToken extends Token { public XenagosSatyrToken() { @@ -167,7 +161,6 @@ class XenagosSatyrToken extends Token { } - class XenagosExileEffect extends OneShotEffect { public XenagosExileEffect() { @@ -197,12 +190,12 @@ class XenagosExileEffect extends OneShotEffect { } FilterCard filter = new FilterCard("creature and/or land cards to put onto the battlefield"); filter.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), - new CardTypePredicate(CardType.LAND))); + new CardTypePredicate(CardType.LAND))); TargetCard target1 = new TargetCard(0, Integer.MAX_VALUE, Zone.EXILED, filter); if (cards.size() > 0 && target1.canChoose(source.getSourceId(), source.getControllerId(), game) && player.choose(Outcome.PutCardInPlay, cards, target1, game)) { - for (UUID targetId: target1.getTargets()) { + for (UUID targetId : target1.getTargets()) { Card card = cards.get(targetId, game); if (card != null) { player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java index de7538b305a..d2b840b0cb1 100644 --- a/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java +++ b/Mage.Sets/src/mage/sets/timespiral/Hypergenesis.java @@ -60,7 +60,7 @@ public class Hypergenesis extends CardImpl { // Suspend 3-{1}{G}{G} this.addAbility(new SuspendAbility(3, new ManaCostsImpl("{1}{G}{G}"), this)); - + // Starting with you, each player may put an artifact, creature, enchantment, or land card from his or her hand onto the battlefield. Repeat this process until no one puts a card onto the battlefield. this.getSpellAbility().addEffect(new HypergenesisEffect()); } @@ -77,8 +77,9 @@ public class Hypergenesis extends CardImpl { @SuppressWarnings("unchecked") class HypergenesisEffect extends OneShotEffect { - + private static final FilterCard filter = new FilterCard("an artifact, creature, enchantment, or land card"); + static { filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ENCHANTMENT), new CardTypePredicate(CardType.LAND))); } @@ -109,7 +110,7 @@ class HypergenesisEffect extends OneShotEffect { UUID firstInactivePlayer = null; Target target = new TargetCardInHand(filter); - while (controller.canRespond()) { + while (controller.canRespond()) { if (currentPlayer != null && currentPlayer.canRespond() && controller.getInRange().contains(currentPlayer.getId())) { if (firstInactivePlayer == null) { firstInactivePlayer = currentPlayer.getId(); @@ -120,7 +121,7 @@ class HypergenesisEffect extends OneShotEffect { if (target.chooseTarget(outcome, currentPlayer.getId(), source, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - currentPlayer.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); + currentPlayer.moveCards(card, Zone.BATTLEFIELD, source, game); firstInactivePlayer = null; } } diff --git a/Mage.Sets/src/mage/sets/timespiral/Vesuva.java b/Mage.Sets/src/mage/sets/timespiral/Vesuva.java index 197107be0c8..99f6571e913 100644 --- a/Mage.Sets/src/mage/sets/timespiral/Vesuva.java +++ b/Mage.Sets/src/mage/sets/timespiral/Vesuva.java @@ -28,14 +28,14 @@ package mage.sets.timespiral; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.effects.common.TapSourceEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -56,12 +56,13 @@ public class Vesuva extends CardImpl { this.expansionSetCode = "TSP"; // You may have Vesuva enter the battlefield tapped as a copy of any land on the battlefield. - EntersBattlefieldEffect effect = new EntersBattlefieldEffect( - new TapSourceEffect(true), - "You may have {this} enter the battlefield tapped as a copy of any land on the battlefield", - true); - effect.addEffect(new CopyPermanentEffect(filter)); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + Effect effect = new TapSourceEffect(true); + effect.setText("tapped"); + Ability ability = new EntersBattlefieldAbility(effect, true); + effect = new CopyPermanentEffect(filter); + effect.setText("as a copy of any land on the battlefield"); + ability.addEffect(effect); + this.addAbility(ability); } public Vesuva(final Vesuva card) { diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java b/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java index 393033b9be8..502842da895 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/AcademyRector.java @@ -106,7 +106,7 @@ class AcademyRectorEffect extends OneShotEffect { controller.searchLibrary(target, game); Card targetCard = game.getCard(target.getFirstTarget()); if (targetCard != null) { - controller.putOntoBattlefieldWithInfo(targetCard, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(targetCard, Zone.BATTLEFIELD, source, game); } controller.shuffleLibrary(game); return true; diff --git a/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java b/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java index 467c548ca54..476ad0d3747 100644 --- a/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java +++ b/Mage.Sets/src/mage/sets/vintagemasters/DacksDuplicate.java @@ -30,15 +30,15 @@ package mage.sets.vintagemasters; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.abilities.keyword.DethroneAbility; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.functions.ApplyToPermanent; @@ -58,11 +58,9 @@ public class DacksDuplicate extends CardImpl { this.toughness = new MageInt(0); // You may have Dack's Duplicate enter the battlefield as a copy of any creature on the battlefield except it gains haste and dethrone. - this.addAbility(new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(new DacksDuplicateApplyToPermanent()), - "You may have {this} enter the battlefield as a copy of any creature on the battlefield except it gains haste and dethrone", - true))); + Effect effect = new CopyPermanentEffect(new FilterCreaturePermanent(), new DacksDuplicateApplyToPermanent()); + effect.setText("as a copy of any creature on the battlefield except it gains haste and dethrone"); + this.addAbility(new EntersBattlefieldAbility(effect, true)); } public DacksDuplicate(final DacksDuplicate card) { diff --git a/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java b/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java index bc0509a505a..5dbc70aa620 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java +++ b/Mage.Sets/src/mage/sets/weatherlight/CallOfTheWild.java @@ -28,11 +28,7 @@ package mage.sets.weatherlight; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -41,6 +37,10 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -68,7 +68,6 @@ public class CallOfTheWild extends CardImpl { } } - class CallOfTheWildEffect extends OneShotEffect { public CallOfTheWildEffect() { @@ -87,22 +86,21 @@ class CallOfTheWildEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller == null || sourceObject == null) { return false; } - if (player.getLibrary().size() > 0) { - Card card = player.getLibrary().getFromTop(game); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Call of the Wild", cards, game); - + if (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { + Cards cards = new CardsImpl(card); + controller.revealCards(sourceObject.getIdName(), cards, game); if (card.getCardType().contains(CardType.CREATURE)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } else { - player.moveCards(card, Zone.LIBRARY, Zone.GRAVEYARD, source, game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } } } diff --git a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java index 77ae649901b..d68cd5c7eda 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java +++ b/Mage.Sets/src/mage/sets/worldwake/JaceTheMindSculptor.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,21 +20,19 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.worldwake; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; @@ -43,8 +41,6 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.counters.CounterType; -import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; @@ -56,13 +52,12 @@ import mage.target.common.TargetCreaturePermanent; */ public class JaceTheMindSculptor extends CardImpl { - public JaceTheMindSculptor(UUID ownerId) { super(ownerId, 31, "Jace, the Mind Sculptor", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{U}"); this.expansionSetCode = "WWK"; this.subtype.add("Jace"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +2: Look at the top card of target player's library. You may put that card on the bottom of that player's library. LoyaltyAbility ability1 = new LoyaltyAbility(new JaceTheMindSculptorEffect1(), 2); @@ -77,7 +72,7 @@ public class JaceTheMindSculptor extends CardImpl { LoyaltyAbility ability3 = new LoyaltyAbility(new ReturnToHandTargetEffect(), -1); ability3.addTarget(new TargetCreaturePermanent()); this.addAbility(ability3); - + // −12: Exile all cards from target player's library, then that player shuffles his or her hand into his or her library. LoyaltyAbility ability4 = new LoyaltyAbility(new JaceTheMindSculptorEffect3(), -12); ability4.addTarget(new TargetPlayer()); @@ -123,7 +118,7 @@ class JaceTheMindSculptorEffect1 extends OneShotEffect { cards.add(card); controller.lookAtCards("Jace, the Mind Sculptor", cards, game); if (controller.chooseUse(outcome, "Do you wish to put card on the bottom of player's library?", source, game)) { - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); + controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, false, false); } else { game.informPlayers(controller.getLogName() + " puts the card back on top of the library."); } diff --git a/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java b/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java index c436a967e92..75eaeeef964 100644 --- a/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java +++ b/Mage.Sets/src/mage/sets/worldwake/JwariShapeshifter.java @@ -28,15 +28,12 @@ package mage.sets.worldwake; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; @@ -47,9 +44,9 @@ import mage.filter.predicate.permanent.AnotherPredicate; * @author jeffwadsworth */ public class JwariShapeshifter extends CardImpl { - + private static final FilterPermanent filter = new FilterPermanent("Ally creature"); - + static { filter.add(new SubtypePredicate("Ally")); filter.add(new CardTypePredicate(CardType.CREATURE)); @@ -66,11 +63,7 @@ public class JwariShapeshifter extends CardImpl { this.toughness = new MageInt(0); // You may have Jwari Shapeshifter enter the battlefield as a copy of any Ally creature on the battlefield. - Ability ability = new SimpleStaticAbility( - Zone.BATTLEFIELD, - new EntersBattlefieldEffect(new CopyPermanentEffect(filter), null, - "You may have {this} enter the battlefield as a copy of any Ally creature on the battlefield", true, true)); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(filter), true)); } public JwariShapeshifter(final JwariShapeshifter card) { diff --git a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java index da7a28bd75e..d5b4caaa4a7 100644 --- a/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java +++ b/Mage.Sets/src/mage/sets/zendikar/AetherFigment.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,36 +20,31 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.zendikar; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.KickedCondition; -import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.CantBeBlockedSourceAbility; +import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; - /** * @author nantuko, BetaSteward_at_googlemail.com */ public class AetherFigment extends CardImpl { - private static final String staticText = "with two +1/+1 counters on it, if it was kicked"; - public AetherFigment(UUID ownerId) { super(ownerId, 40, "AEther Figment", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.expansionSetCode = "ZEN"; @@ -65,7 +60,11 @@ public class AetherFigment extends CardImpl { this.addAbility(new KickerAbility("{3}")); // If AEther Figment was kicked, it enters the battlefield with two +1/+1 counters on it - Ability ability = new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), KickedCondition.getInstance(), ""), staticText); + Ability ability = new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + KickedCondition.getInstance(), + "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it", + ""); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java index a64697b5814..7caa34f04f9 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java +++ b/Mage.Sets/src/mage/sets/zendikar/ChandraAblaze.java @@ -32,18 +32,16 @@ import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.discard.DiscardHandAllEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -66,7 +64,7 @@ public class ChandraAblaze extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Chandra"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(5)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); // +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to target creature or player. LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1); diff --git a/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java b/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java index 1a24adaacdf..2306fb65d75 100644 --- a/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java +++ b/Mage.Sets/src/mage/sets/zendikar/NissaRevane.java @@ -28,17 +28,15 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; -import mage.cards.CardImpl; -import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.predicate.mageobject.NamePredicate; @@ -62,11 +60,10 @@ public class NissaRevane extends CardImpl { } public NissaRevane(UUID ownerId) { - super(ownerId, 170, "Nissa Revane", Rarity.MYTHIC, new CardType[]{ CardType.PLANESWALKER }, "{2}{G}{G}"); + super(ownerId, 170, "Nissa Revane", Rarity.MYTHIC, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{G}"); this.expansionSetCode = "ZEN"; this.subtype.add("Nissa"); - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(2)), false)); - + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(2)); LoyaltyAbility ability1 = new LoyaltyAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(1, nissasChosenFilter)), 1); this.addAbility(ability1); diff --git a/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java b/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java index 5ecb9fe0b4c..309684109aa 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java +++ b/Mage.Sets/src/mage/sets/zendikar/SorinMarkov.java @@ -27,27 +27,24 @@ */ package mage.sets.zendikar; -import mage.constants.CardType; -import mage.constants.Rarity; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.turn.ControlTargetPlayerNextTurnEffect; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; -import mage.counters.CounterType; +import mage.constants.Rarity; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetOpponent; -import java.util.UUID; - /** * * @author nantuko @@ -59,8 +56,7 @@ public class SorinMarkov extends CardImpl { this.expansionSetCode = "ZEN"; this.subtype.add("Sorin"); - - this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(4)), false)); + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +2: Sorin Markov deals 2 damage to target creature or player and you gain 2 life. LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(2), 2); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java index ebea5c555aa..41fdc97851c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/MasterBiomancerTest.java @@ -9,23 +9,19 @@ import org.mage.test.serverside.base.CardTestPlayerBase; * * @author LevelX2 */ - - public class MasterBiomancerTest extends CardTestPlayerBase { /* Master Biomancer {2}{G}{U} * Creature - Elf Wizard * 2/4 - * Each other creature you control enters the battlefield with a number of additional +1/+1 counters + * Each other creature you control enters the battlefield with a number of additional +1/+1 counters * on it equal to Master Biomancer's power and as a Mutant in addition to its other types. * */ - @Test public void testCreatureGetsCounters() { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer - addCard(Zone.BATTLEFIELD, playerA, "Island", 5); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); addCard(Zone.HAND, playerA, "Mindeye Drake"); @@ -52,12 +48,12 @@ public class MasterBiomancerTest extends CardTestPlayerBase { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer // doubled by Corpsejack Menace (when he ist cast, his own ability will not apply) // http://blogs.magicjudges.org/rulestips/2013/03/corpsejack-menace-and-master-biomancer/ - addCard(Zone.BATTLEFIELD, playerA, "Island", 2); addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); + // If one or more +1/+1 counters would be placed on a creature you control, twice that many +1/+1 counters are placed on it instead. addCard(Zone.HAND, playerA, "Corpsejack Menace"); addCard(Zone.HAND, playerA, "Mindeye Drake"); @@ -83,30 +79,28 @@ public class MasterBiomancerTest extends CardTestPlayerBase { assertPowerToughness(playerA, "Mindeye Drake", 6, 9); } - /** - * Progenitor Mimic - * Creature - Shapeshifter - * 0/0 - * You may have Progenitor Mimic enter the battlefield as a copy of any creature on - * the battlefield except it gains "At the beginning of your upkeep, if this creature - * isn't a token, put a token onto the battlefield that's a copy of this creature." + * Progenitor Mimic Creature - Shapeshifter 0/0 You may have Progenitor + * Mimic enter the battlefield as a copy of any creature on the battlefield + * except it gains "At the beginning of your upkeep, if this creature isn't + * a token, put a token onto the battlefield that's a copy of this + * creature." * - * If Progenitor Mimic comes into play, it gets two +1/+1 counters from - * the Master Biomancer already in play. It copies the Master Biomancer and - * is therfore a 4/6 creature. - * The Token generated next round from Progenitor Mimic has to get 2 + 4 counters - * and is therefore a 8/10 creature. + * If Progenitor Mimic comes into play, it gets two +1/+1 counters from the + * Master Biomancer already in play. It copies the Master Biomancer and is + * therfore a 4/6 creature. The Token generated next round from Progenitor + * Mimic has to get 2 + 4 counters and is therefore a 8/10 creature. */ - @Test public void testWithProgenitorMimic() { // a creature enters the battlefield and gets a counter for each point of power of Master Biomancer - addCard(Zone.BATTLEFIELD, playerA, "Island", 3); addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); + // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield + // except it gains "At the beginning of your upkeep, if this creature isn't a token, + // put a token onto the battlefield that's a copy of this creature." addCard(Zone.HAND, playerA, "Progenitor Mimic"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Progenitor Mimic"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java index 98e3294b084..9ed98cca08f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SuspendTest.java @@ -49,6 +49,8 @@ public class SuspendTest extends CardTestPlayerBase { public void testEpochrasite() { addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // Epochrasite enters the battlefield with three +1/+1 counters on it if you didn't cast it from your hand. + // When Epochrasite dies, exile it with three time counters on it and it gains suspend. addCard(Zone.HAND, playerA, "Epochrasite", 1); addCard(Zone.HAND, playerB, "Lightning Bolt", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java index ff78a4dcf31..6567fa4edd3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/KikiJikiMirrorBreakerTest.java @@ -157,7 +157,7 @@ public class KikiJikiMirrorBreakerTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Island", 5); addCard(Zone.BATTLEFIELD, playerB, "Kiki-Jiki, Mirror Breaker", 1); - // {T}: Draw two cards. Target opponent gains control of Humble Defector. Activate this ability only during your turn. + // You may have Body Double enter the battlefield as a copy of any creature card in a graveyard. addCard(Zone.HAND, playerB, "Body Double", 1); // {4}{U} castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Body Double"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java index 48fc3962b1f..fe600b1e415 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/copy/VesuvaTest.java @@ -92,7 +92,6 @@ public class VesuvaTest extends CardTestPlayerBase { execute(); assertPermanentCount(playerB, "Dark Depths", 1); - assertPermanentCount(playerA, "Vesuva", 0); assertPermanentCount(playerA, "Dark Depths", 1); Permanent darkDepth = getPermanent("Dark Depths", playerA); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java index 6c1e294d57c..082e3440095 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/PillarOfFlameTest.java @@ -6,22 +6,30 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * Pillar of Flame: - * Pillar of Flame deals 2 damage to target creature or player. If a creature dealt damage this way would die this turn, exile it instead. + * Pillar of Flame: Pillar of Flame deals 2 damage to target creature or player. + * If a creature dealt damage this way would die this turn, exile it instead. * * @author LevelX2 */ public class PillarOfFlameTest extends CardTestPlayerBase { /** - * Tests when cast Pillar of Flame targeting opponent there is no influence on dying creature of opponent + * Tests when cast Pillar of Flame targeting opponent there is no influence + * on dying creature of opponent */ @Test public void testNotTriggeringExileItInstead() { - addCard(Zone.BATTLEFIELD, playerA, "Lightning Mauler"); - addCard(Zone.BATTLEFIELD, playerA, "Rakdos Cackler"); + // Soulbond + // As long as Lightning Mauler is paired with another creature, both creatures have haste. + addCard(Zone.BATTLEFIELD, playerA, "Lightning Mauler"); // 2/1 + // Unleash (You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it.) + addCard(Zone.BATTLEFIELD, playerA, "Rakdos Cackler"); // 1/1 + // Pillar of Flame deals 2 damage to target creature or player. + // If a creature dealt damage this way would die this turn, exile it instead. addCard(Zone.HAND, playerA, "Pillar of Flame"); + // Soulbond + // As long as Stonewright is paired with another creature, each of those creatures has "{R}: This creature gets +1/+0 until end of turn." addCard(Zone.HAND, playerA, "Stonewright"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); @@ -49,7 +57,8 @@ public class PillarOfFlameTest extends CardTestPlayerBase { } /** - * Tests when cast Pillar of Flame targeting creature it goes to exile if dying later + * Tests when cast Pillar of Flame targeting creature it goes to exile if + * dying later */ @Test public void testTriggeringExileItInstead() { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java index 441d68754b9..c8694f3540b 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/TorporOrbTest.java @@ -6,8 +6,8 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * Torpor Orb: - * Creatures entering the battlefield don't cause abilities to trigger. + * Torpor Orb: Creatures entering the battlefield don't cause abilities to + * trigger. * * @author noxx */ @@ -15,7 +15,10 @@ public class TorporOrbTest extends CardTestPlayerBase { @Test public void testWallOfOmens() { + // Creatures entering the battlefield don't cause abilities to trigger. addCard(Zone.BATTLEFIELD, playerA, "Torpor Orb"); + // Defender + // When Wall of Omens enters the battlefield, draw a card. addCard(Zone.HAND, playerA, "Wall of Omens"); addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); @@ -33,7 +36,8 @@ public class TorporOrbTest extends CardTestPlayerBase { } /** - * Treacherous Pit-Dweller doesnt function properly with Torpor Orb and Hushwing Gryff + * Treacherous Pit-Dweller doesnt function properly with Torpor Orb and + * Hushwing Gryff */ @Test public void testPitTweller() { @@ -42,8 +46,8 @@ public class TorporOrbTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); - - attack(2, playerB, "Treacherous Pit-Dweller"); + + attack(2, playerB, "Treacherous Pit-Dweller"); castSpell(2, PhaseStep.DECLARE_ATTACKERS, playerA, "Lightning Bolt", "Treacherous Pit-Dweller"); setStopAt(2, PhaseStep.POSTCOMBAT_MAIN); @@ -53,9 +57,9 @@ public class TorporOrbTest extends CardTestPlayerBase { assertLife(playerB, 20); assertGraveyardCount(playerA, "Lightning Bolt", 1); - + assertPermanentCount(playerB, "Treacherous Pit-Dweller", 1); - assertPowerToughness(playerB, "Treacherous Pit-Dweller", 5,4); + assertPowerToughness(playerB, "Treacherous Pit-Dweller", 5, 4); } - + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java index 5d8f468f12c..fe610fe9b3c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/FathomMageTest.java @@ -13,14 +13,16 @@ public class FathomMageTest extends CardTestPlayerBase { /** * Fathom Mage - Creature — Human Wizard 1/1, 2UG * - * Evolve (Whenever a creature enters the battlefield under your control, if that creature has greater power or toughness than this creature, put a +1/+1 counter on this creature.) - * Whenever a +1/+1 counter is placed on Fathom Mage, you may draw a card. + * Evolve (Whenever a creature enters the battlefield under your control, if + * that creature has greater power or toughness than this creature, put a + * +1/+1 counter on this creature.) Whenever a +1/+1 counter is placed on + * Fathom Mage, you may draw a card. + * * - */ @Test public void testDrawCardsAddedCounters() { - // card draw triggered ability will trigger once for each of those counters from Blessings of Nature. + // card draw triggered ability will trigger once for each of those counters from Blessings of Nature. addCard(Zone.HAND, playerA, "Blessings of Nature"); addCard(Zone.BATTLEFIELD, playerA, "Fathom Mage", 1); @@ -38,14 +40,14 @@ public class FathomMageTest extends CardTestPlayerBase { @Test public void testDrawCardsEntersTheBattlefield() { - // card draw triggered ability will trigger once for each of those counters from Master Biomancer. + // card draw triggered ability will trigger once for each of those counters from Master Biomancer. addCard(Zone.HAND, playerA, "Fathom Mage"); addCard(Zone.BATTLEFIELD, playerA, "Master Biomancer", 1); - addCard(Zone.BATTLEFIELD, playerA, "Forest", 4); - addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + addCard(Zone.BATTLEFIELD, playerA, "Island", 2); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fathom Mage"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fathom Mage"); // {2}{G}{U} setStopAt(1, PhaseStep.END_TURN); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 5d0df67f11a..702e99ba355 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1970,11 +1970,26 @@ public class TestPlayer implements Player { return computerPlayer.scry(value, source, game); } + @Override + public boolean moveCards(Card card, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(card, toZone, source, game); + } + @Override public boolean moveCards(Card card, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } + @Override + public boolean moveCards(Cards cards, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(cards, toZone, source, game); + } + + @Override + public boolean moveCards(Set cards, Zone toZone, Ability source, Game game) { + return computerPlayer.moveCards(cards, toZone, source, game); + } + @Override public boolean moveCards(Set cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 77d726faea7..8611baa943c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -533,10 +533,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement if (flag) { Assert.assertTrue("No such ability=" + ability.toString() + ", player=" + player.getName() - + ", cardName" + cardName, found.getAbilities().containsRule(ability)); + + ", cardName" + cardName, found.getAbilities(currentGame).containsRule(ability)); } else { Assert.assertFalse("Card shouldn't have such ability=" + ability.toString() + ", player=" + player.getName() - + ", cardName" + cardName, found.getAbilities().containsRule(ability)); + + ", cardName" + cardName, found.getAbilities(currentGame).containsRule(ability)); } } @@ -574,7 +574,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement } } } - Assert.assertEquals("(Battlefield) Card counts for " + player.getName() + " are not equal (" + cardName + ")", count, actualCount); + Assert.assertEquals("(Battlefield) Permanents counts for " + player.getName() + " are not equal (" + cardName + ")", count, actualCount); } @Override diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 821abd34d61..619a400685d 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -958,6 +958,10 @@ public abstract class AbilityImpl implements Ability { if (object instanceof Permanent) { return false; } else { + Permanent permanent = game.getPermanentEntering(getSourceId()); + if (permanent != null && permanent.getAbilities().contains(this)) { + return true; + } // check if it's an ability that is temporary gained to a card Abilities otherAbilities = game.getState().getAllOtherAbilities(this.getSourceId()); if (otherAbilities == null || !otherAbilities.contains(this)) { diff --git a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java index aac46fbe9d8..0efbd80e31e 100644 --- a/Mage/src/mage/abilities/common/DiesTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/DiesTriggeredAbility.java @@ -71,7 +71,7 @@ public class DiesTriggeredAbility extends ZoneChangeTriggeredAbility { if (super.checkEventType(event, game)) { return ((ZoneChangeEvent) event).getFromZone().equals(Zone.BATTLEFIELD) && ((ZoneChangeEvent) event).getToZone().equals(Zone.GRAVEYARD); } - return event.getType() == GameEvent.EventType.ZONE_CHANGE; + return false; } @Override diff --git a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java index 64bd2c40fe5..40231800591 100644 --- a/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/mage/abilities/common/EntersBattlefieldAbility.java @@ -40,44 +40,50 @@ import mage.constants.Zone; public class EntersBattlefieldAbility extends StaticAbility { protected String abilityRule; + protected boolean optional; public EntersBattlefieldAbility(Effect effect) { - this(effect, true); + this(effect, false); } /** * * @param effect effect that happens when the permanent enters the - * battlefield - * @param showRule show the rule for this ability + * battlefiely + * @param optional */ - public EntersBattlefieldAbility(Effect effect, Boolean showRule) { - this(effect, null, showRule, null, null); + public EntersBattlefieldAbility(Effect effect, boolean optional) { + this(effect, optional, null, null, null); } public EntersBattlefieldAbility(Effect effect, String effectText) { - this(effect, null, true, null, effectText); + this(effect, null, null, effectText); + } + + public EntersBattlefieldAbility(Effect effect, Condition condition, String abilityRule, String effectText) { + this(effect, false, condition, abilityRule, effectText); } /** * * @param effect effect that happens when the permanent enters the * battlefield + * @param optional * @param condition only if this condition is true, the effect will happen - * @param ruleVisible show the rule for this ability * @param abilityRule rule for this ability (no text from effects will be * added) * @param effectText this text will be used for the EnterBattlefieldEffect */ - public EntersBattlefieldAbility(Effect effect, Condition condition, Boolean ruleVisible, String abilityRule, String effectText) { - super(Zone.ALL, new EntersBattlefieldEffect(effect, condition, effectText)); - this.setRuleVisible(ruleVisible); + public EntersBattlefieldAbility(Effect effect, boolean optional, Condition condition, String abilityRule, String effectText) { + super(Zone.ALL, new EntersBattlefieldEffect(effect, condition, effectText, true, optional)); this.abilityRule = abilityRule; + this.optional = optional; } public EntersBattlefieldAbility(final EntersBattlefieldAbility ability) { super(ability); this.abilityRule = ability.abilityRule; + this.optional = ability.optional; } @Override @@ -99,12 +105,9 @@ public class EntersBattlefieldAbility extends StaticAbility { @Override public String getRule() { - if (!ruleVisible) { - return ""; - } if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return "{this} enters the battlefield " + super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield " + super.getRule(); } } diff --git a/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java b/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java new file mode 100644 index 00000000000..aad230eaf2d --- /dev/null +++ b/Mage/src/mage/abilities/common/PlanswalkerEntersWithLoyalityCountersAbility.java @@ -0,0 +1,30 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.counters.CounterType; + +/** + * + * @author LevelX2 + */ +public class PlanswalkerEntersWithLoyalityCountersAbility extends EntersBattlefieldAbility { + + public PlanswalkerEntersWithLoyalityCountersAbility(int loyality) { + super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyality))); + setRuleVisible(false); + } + + public PlanswalkerEntersWithLoyalityCountersAbility(final PlanswalkerEntersWithLoyalityCountersAbility ability) { + super(ability); + } + + @Override + public EntersBattlefieldAbility copy() { + return new PlanswalkerEntersWithLoyalityCountersAbility(this); + } +} diff --git a/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java index 27811130bdc..1abc7306f5f 100644 --- a/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java +++ b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java @@ -12,10 +12,14 @@ import mage.watchers.Watcher; * @author Loki */ public class CastFromHandCondition implements Condition { + @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + permanent = game.getPermanentEntering(source.getSourceId()); + } + if (permanent != null) { Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId()); if (watcher != null && watcher.conditionMet()) { return true; @@ -29,5 +33,4 @@ public class CastFromHandCondition implements Condition { return "you cast it from your hand"; } - } diff --git a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java index 03a0be13f47..b69b73b278c 100644 --- a/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java +++ b/Mage/src/mage/abilities/costs/AlternativeCost2Impl.java @@ -125,8 +125,6 @@ public class AlternativeCost2Impl> extends Cos activated = true; } - ; - /** * Reset the activate and count information * diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index c5b4661816b..2f35dbd4901 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -879,7 +879,7 @@ public class ContinuousEffects implements Serializable { // For example: Vesuva copying a Dark Depth (VesuvaTest:testDarkDepth) // This call should be removed if possible as replacement effects of EntersTheBattlefield events // do no longer work correctly because the entering permanents are not yet on the battlefield (before they were). - game.applyEffects(); + // game.applyEffects(); } while (true); return caught; } diff --git a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java index ef6bb795d16..052d4ee5d4b 100644 --- a/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/EntersBattlefieldEffect.java @@ -34,7 +34,6 @@ import mage.abilities.condition.Condition; import mage.constants.Duration; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; @@ -52,7 +51,6 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { protected Condition condition; protected boolean optional; - public static final String ENTERING_PERMANENT = "enteringPermanent"; public static final String SOURCE_CAST_SPELL_ABILITY = "sourceCastSpellAbility"; public EntersBattlefieldEffect(Effect baseEffect) { @@ -67,10 +65,6 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { this(baseEffect, null, text, true, optional); } - public EntersBattlefieldEffect(Effect baseEffect, Condition condition, String text) { - this(baseEffect, condition, text, true, false); - } - public EntersBattlefieldEffect(Effect baseEffect, Condition condition, String text, boolean selfScope, boolean optional) { super(Duration.WhileOnBattlefield, baseEffect.getOutcome(), selfScope); this.baseEffects.add(baseEffect); @@ -126,18 +120,16 @@ public class EntersBattlefieldEffect extends ReplacementEffectImpl { } } for (Effect effect : baseEffects) { - if (source.activate(game, false)) { - if (effect instanceof ContinuousEffect) { - game.addEffect((ContinuousEffect) effect, source); - } else { - if (spell != null) { - effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); - } - // Because the permanent is not on the battlefield yet, it has to be taken from the event - effect.setValue(ENTERING_PERMANENT, ((EntersTheBattlefieldEvent) event).getTarget()); - effect.apply(game, source); + // if (source.activate(game, false)) { // Why is this needed???? + if (effect instanceof ContinuousEffect) { + game.addEffect((ContinuousEffect) effect, source); + } else { + if (spell != null) { + effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility()); } + effect.apply(game, source); } + // } } return false; } diff --git a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java index 4a87a976677..722fc0468d9 100644 --- a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java +++ b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common; import java.util.ArrayList; @@ -62,17 +61,17 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { this.amount = amount; this.staticText = setText(); } - + public AddManaInAnyCombinationEffect(int amount, String text) { this(amount); this.staticText = text; } - + public AddManaInAnyCombinationEffect(int amount, String text, ColoredManaSymbol... coloredManaSymbols) { this(amount, coloredManaSymbols); this.staticText = text; } - + public AddManaInAnyCombinationEffect(DynamicValue amount, String text, ColoredManaSymbol... coloredManaSymbols) { this(amount, coloredManaSymbols); this.staticText = text; @@ -92,13 +91,13 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null){ + if (player != null) { Mana mana = new Mana(); int amountOfManaLeft = amount.calculate(game, source, this); while (amountOfManaLeft > 0 && player.canRespond()) { - for (ColoredManaSymbol coloredManaSymbol: manaSymbols) { - int number = player.getAmount(0, amountOfManaLeft, new StringBuilder("How many ").append(coloredManaSymbol.name()).append(" mana?").toString(), game); + for (ColoredManaSymbol coloredManaSymbol : manaSymbols) { + int number = player.getAmount(0, amountOfManaLeft, "How many " + coloredManaSymbol.getColorName() + " mana?", game); if (number > 0) { for (int i = 0; i < number; i++) { mana.add(new Mana(coloredManaSymbol)); @@ -111,7 +110,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { } } checkToFirePossibleEvents(mana, game, source); - player.getManaPool().addMana(mana, game, source); + player.getManaPool().addMana(mana, game, source); return true; } return false; @@ -130,7 +129,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { sb.append("colors"); } else { int i = 0; - for (ColoredManaSymbol coloredManaSymbol: manaSymbols) { + for (ColoredManaSymbol coloredManaSymbol : manaSymbols) { i++; if (i > 1) { sb.append(" and/or "); diff --git a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java index a06e008ad7a..dcae2105843 100644 --- a/Mage/src/mage/abilities/effects/common/AmplifyEffect.java +++ b/Mage/src/mage/abilities/effects/common/AmplifyEffect.java @@ -19,6 +19,7 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -27,15 +28,13 @@ import mage.target.common.TargetCardInHand; /** * Effect for the AmplifyAbility * - * 702.37. Amplify - * 702.37a Amplify is a static ability. “Amplify N” means “As - * this object enters the battlefield, reveal any number of cards from your hand - * that share a creature type with it. This permanent enters the battlefield - * with N +1/+1 counters on it for each card revealed this way. You can’t reveal - * this card or any other cards that are entering the battlefield at the same - * time as this card.” - * 702.37b If a creature has multiple instances of amplify, - * each one works separately. + * 702.37. Amplify 702.37a Amplify is a static ability. “Amplify N” means “As + * this object enters the battlefield, reveal any number of cards from your hand + * that share a creature type with it. This permanent enters the battlefield + * with N +1/+1 counters on it for each card revealed this way. You can’t reveal + * this card or any other cards that are entering the battlefield at the same + * time as this card.” 702.37b If a creature has multiple instances of amplify, + * each one works separately. * * * @author FenrisulfrX @@ -45,6 +44,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { private final AmplifyFactor amplifyFactor; public enum AmplifyFactor { + Amplify1("Amplify 1", "put one +1/+1 counters on it", 1), Amplify2("Amplify 2", "put two +1/+1 counters on it", 2), Amplify3("Amplify 3", "put three +1/+1 counters on it", 3); @@ -95,7 +95,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent sourceCreature = game.getPermanent(event.getTargetId()); + Permanent sourceCreature = ((EntersTheBattlefieldEvent) event).getTarget(); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && sourceCreature != null) { FilterCreatureCard filter = new FilterCreatureCard("creatures cards to reveal"); @@ -108,7 +108,7 @@ public class AmplifyEffect extends ReplacementEffectImpl { } else if (filterSubtypes.size() == 1) { filter.add(filterSubtypes.get(0)); } - if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0){ + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { if (controller.chooseUse(outcome, "Reveal cards to Amplify?", source, game)) { TargetCardInHand target = new TargetCardInHand(0, Integer.MAX_VALUE, filter); if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { @@ -128,11 +128,11 @@ public class AmplifyEffect extends ReplacementEffectImpl { public String getText(Mode mode) { StringBuilder sb = new StringBuilder(amplifyFactor.toString()); sb.append("(As this enter the battlefield, "); - sb.append(amplifyFactor.getRuleText()).append(" for each card" + - " you reveal that shares a type with it in your hand.)"); + sb.append(amplifyFactor.getRuleText()).append(" for each card" + + " you reveal that shares a type with it in your hand.)"); return sb.toString(); } - + @Override public AmplifyEffect copy() { return new AmplifyEffect(this); diff --git a/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java index 07c1e706e9b..5d73e8dd40e 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseBasicLandTypeEffect.java @@ -7,7 +7,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.choices.ChoiceImpl; import mage.constants.Outcome; @@ -41,7 +40,7 @@ public class ChooseBasicLandTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java index 2fe01116753..161dec6767e 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseColorEffect.java @@ -29,7 +29,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.choices.ChoiceColor; import mage.constants.Outcome; @@ -56,7 +55,7 @@ public class ChooseColorEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java index 06178b02843..b1d4b0e6f62 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseCreatureTypeEffect.java @@ -29,7 +29,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.repository.CardRepository; import mage.choices.Choice; @@ -58,7 +57,7 @@ public class ChooseCreatureTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java b/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java index 52259dbac52..bd59c25c334 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseLandTypeEffect.java @@ -7,7 +7,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.repository.CardRepository; import mage.choices.Choice; @@ -36,7 +35,7 @@ public class ChooseLandTypeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java b/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java index 9ac1910128e..bdb32a34a13 100644 --- a/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChooseOpponentEffect.java @@ -7,7 +7,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.game.Game; @@ -41,7 +40,7 @@ public class ChooseOpponentEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java b/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java index 7e5c6402c1b..7f8ce4c72cc 100644 --- a/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java +++ b/Mage/src/mage/abilities/effects/common/ChoosePlayerEffect.java @@ -7,7 +7,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.game.Game; @@ -39,7 +38,7 @@ public class ChoosePlayerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject mageObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject mageObject = game.getPermanentEntering(source.getSourceId()); if (mageObject == null) { mageObject = game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/CopyEffect.java b/Mage/src/mage/abilities/effects/common/CopyEffect.java index 86bc3f060fb..9b6becb7198 100644 --- a/Mage/src/mage/abilities/effects/common/CopyEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyEffect.java @@ -33,6 +33,7 @@ import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.Card; +import mage.constants.AbilityType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Layer; @@ -54,10 +55,10 @@ public class CopyEffect extends ContinuousEffectImpl { /** * Object we copy from */ - private MageObject copyFromObject; + protected MageObject copyFromObject; - private UUID copyToObjectId; - private ApplyToPermanent applier; + protected UUID copyToObjectId; + protected ApplyToPermanent applier; public CopyEffect(MageObject copyFromObject, UUID copyToObjectId) { this(Duration.Custom, copyFromObject, copyToObjectId); @@ -82,14 +83,23 @@ public class CopyEffect extends ContinuousEffectImpl { if (!(copyFromObject instanceof Permanent) && (copyFromObject instanceof Card)) { this.copyFromObject = new PermanentCard((Card) copyFromObject, source.getControllerId(), game); } - + Permanent permanent = game.getPermanent(copyToObjectId); + if (permanent != null) { + affectedObjectList.add(new MageObjectReference(permanent, game)); + } else if (source.getAbilityType().equals(AbilityType.STATIC)) { + // for replacement effects that let a permanent enter the battlefield as a copy of another permanent we need to apply that copy + // before the permanent is added to the battlefield + permanent = game.getPermanentEntering(copyToObjectId); + if (permanent != null) { + copyToPermanent(permanent, game, source); + // set reference to the permanent later on the battlefield so we have to add already one to the zone change counter + affectedObjectList.add(new MageObjectReference(permanent.getId(), game.getState().getZoneChangeCounter(copyToObjectId) + 1, game)); + } + } } @Override public boolean apply(Game game, Ability source) { - if (affectedObjectList.isEmpty()) { - affectedObjectList.add(new MageObjectReference(getSourceId(), game)); - } Permanent permanent = affectedObjectList.get(0).getPermanent(game); if (permanent == null) { permanent = (Permanent) game.getLastKnownInformation(getSourceId(), Zone.BATTLEFIELD, source.getSourceObjectZoneChangeCounter()); @@ -99,6 +109,10 @@ public class CopyEffect extends ContinuousEffectImpl { return false; } } + return copyToPermanent(permanent, game, source); + } + + protected boolean copyToPermanent(Permanent permanent, Game game, Ability source) { permanent.setCopy(true); permanent.setName(copyFromObject.getName()); permanent.getColor(game).setColor(copyFromObject.getColor(game)); diff --git a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java index f6318632ac6..bf1ef297244 100644 --- a/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java +++ b/Mage/src/mage/abilities/effects/common/CopyPermanentEffect.java @@ -73,7 +73,7 @@ public class CopyPermanentEffect extends OneShotEffect { this.applier = applier; this.filter = filter; this.useTargetOfAbility = useTarget; - this.staticText = "You may have {this} enter the battlefield as a copy of any " + filter.getMessage() + " on the battlefield"; + this.staticText = "as a copy of any " + filter.getMessage() + " on the battlefield"; } public CopyPermanentEffect(final CopyPermanentEffect effect) { @@ -87,7 +87,10 @@ public class CopyPermanentEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); + MageObject sourceObject = game.getPermanentEntering(source.getSourceId()); + if (sourceObject == null) { + sourceObject = game.getObject(source.getSourceId()); + } if (player != null && sourceObject != null) { Permanent copyFromPermanent = null; if (useTargetOfAbility) { diff --git a/Mage/src/mage/abilities/effects/common/DevourEffect.java b/Mage/src/mage/abilities/effects/common/DevourEffect.java index 1d02ab1733d..b2baf9ef7c0 100644 --- a/Mage/src/mage/abilities/effects/common/DevourEffect.java +++ b/Mage/src/mage/abilities/effects/common/DevourEffect.java @@ -47,30 +47,32 @@ import mage.target.common.TargetControlledCreaturePermanent; /** * Effect for the DevourAbility - * - * 702.81. Devour - * 702.81a Devour is a static ability. "Devour N" means "As this object enters the battlefield, - * you may sacrifice any number of creatures. This permanent enters the battlefield with N +1/+1 - * counters on it for each creature sacrificed this way." - * 702.81b Some objects have abilities that refer to the number of creatures the permanent devoured. - * "It devoured" means "sacrificed as a result of its devour ability as it entered the battlefield." * - * + * 702.81. Devour 702.81a Devour is a static ability. "Devour N" means "As this + * object enters the battlefield, you may sacrifice any number of creatures. + * This permanent enters the battlefield with N +1/+1 counters on it for each + * creature sacrificed this way." 702.81b Some objects have abilities that refer + * to the number of creatures the permanent devoured. "It devoured" means + * "sacrificed as a result of its devour ability as it entered the battlefield." + * + * * @author LevelX2 */ public class DevourEffect extends ReplacementEffectImpl { private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures to devour"); + static { filter.add(new AnotherPredicate()); } private final DevourFactor devourFactor; public enum DevourFactor { - Devour1 ("Devour 1", "that many +1/+1 counters on it", 1), - Devour2 ("Devour 2", "twice that many +1/+1 counters on it", 2), - Devour3 ("Devour 3", "three times that many +1/+1 counters on it", 3), - DevourX ("Devour X, where X is the number of creatures devoured this way", "X +1/+1 counters on it for each of those creatures", Integer.MAX_VALUE); + + Devour1("Devour 1", "that many +1/+1 counters on it", 1), + Devour2("Devour 2", "twice that many +1/+1 counters on it", 2), + Devour3("Devour 3", "three times that many +1/+1 counters on it", 3), + DevourX("Devour X, where X is the number of creatures devoured this way", "X +1/+1 counters on it for each of those creatures", Integer.MAX_VALUE); private final String text; private final String ruleText; @@ -114,9 +116,9 @@ public class DevourEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - game.getState().setValue(sourcePermanent.getId().toString() + "devoured", null); - return true; + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); + game.getState().setValue(sourcePermanent.getId().toString() + "devoured", null); + return true; } return false; } @@ -128,7 +130,7 @@ public class DevourEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(event.getTargetId()); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { Target target = new TargetControlledCreaturePermanent(1, Integer.MAX_VALUE, filter, true); @@ -141,9 +143,10 @@ public class DevourEffect extends ReplacementEffectImpl { if (target.getTargets().size() > 0) { List> cardSubtypes = new ArrayList<>(); int devouredCreatures = target.getTargets().size(); - if (!game.isSimulation()) - game.informPlayers(new StringBuilder(creature.getName()).append(" devours ").append(devouredCreatures).append(" creatures").toString()); - for (UUID targetId: target.getTargets()) { + if (!game.isSimulation()) { + game.informPlayers(creature.getLogName() + " devours " + devouredCreatures + " creatures"); + } + for (UUID targetId : target.getTargets()) { Permanent targetCreature = game.getPermanent(targetId); if (targetCreature != null) { cardSubtypes.add((ArrayList) targetCreature.getSubtype()); @@ -172,7 +175,7 @@ public class DevourEffect extends ReplacementEffectImpl { StringBuilder sb = new StringBuilder(devourFactor.toString()); sb.append(" (As this enters the battlefield, you may sacrifice any number of creatures. This creature enters the battlefield with "); sb.append(devourFactor.getRuleText()).append(")"); - return sb.toString(); + return sb.toString(); } public List> getSubtypes(Game game, UUID permanentId) { diff --git a/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java index 137b33c5145..1a82af11cdf 100644 --- a/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/DiscardOntoBattlefieldEffect.java @@ -34,8 +34,8 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; -import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.stack.StackObject; import mage.players.Player; @@ -85,7 +85,7 @@ public class DiscardOntoBattlefieldEffect extends ReplacementEffectImpl { if (card != null) { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { - if (owner.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId())) { + if (owner.moveCards(card, Zone.BATTLEFIELD, source, game)) { return true; } } diff --git a/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java b/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java index 7451cd90dbb..9c704852225 100644 --- a/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java +++ b/Mage/src/mage/abilities/effects/common/EntersBattlefieldWithXCountersEffect.java @@ -31,6 +31,7 @@ import mage.abilities.Ability; import mage.abilities.SpellAbility; import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.counters.Counter; import mage.game.Game; @@ -60,13 +61,15 @@ public class EntersBattlefieldWithXCountersEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); + } } if (permanent != null) { SpellAbility spellAbility = (SpellAbility) getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); if (spellAbility != null && spellAbility.getSourceId().equals(source.getSourceId()) - && permanent.getZoneChangeCounter(game) - 1 == spellAbility.getSourceObjectZoneChangeCounter()) { + && permanent.getZoneChangeCounter(game) == spellAbility.getSourceObjectZoneChangeCounter()) { if (spellAbility.getSourceId().equals(source.getSourceId())) { // put into play by normal cast int amount = spellAbility.getManaCostsToPay().getX(); if (amount > 0) { diff --git a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java index 6e99909a49e..72874fb2fd0 100644 --- a/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java @@ -66,7 +66,7 @@ public class ExileAndReturnTransformedSourceEffect extends OneShotEffect { Player owner = game.getPlayer(card.getOwnerId()); if (owner != null) { game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); - owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId()); + owner.moveCards(card, Zone.BATTLEFIELD, source, game); if (additionalEffect != null) { if (additionalEffect instanceof ContinuousEffect) { game.addEffect((ContinuousEffect) additionalEffect, source); diff --git a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java index 89b065c0306..529760e039b 100644 --- a/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/LookLibraryAndPickControllerEffect.java @@ -29,7 +29,6 @@ */ package mage.abilities.effects.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.dynamicvalue.DynamicValue; @@ -128,28 +127,13 @@ public class LookLibraryAndPickControllerEffect extends LookLibraryControllerEff if (!optional || player.chooseUse(Outcome.DrawCard, getMayText(), source, game)) { FilterCard pickFilter = filter.copy(); pickFilter.setMessage(getPickText()); - TargetCard target = new TargetCard((upTo ? 0 : numberToPick.calculate(game, source, this)), numberToPick.calculate(game, source, this), Zone.PICK, pickFilter); + TargetCard target = new TargetCard((upTo ? 0 : numberToPick.calculate(game, source, this)), numberToPick.calculate(game, source, this), Zone.LIBRARY, pickFilter); if (player.choose(Outcome.DrawCard, cards, target, game)) { - Cards reveal = new CardsImpl(); - for (UUID cardId : target.getTargets()) { - Card card = cards.get(cardId, game); - if (card != null) { - cards.remove(card); - if (targetZoneLookedCards.equals(Zone.BATTLEFIELD)) { - player.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); - } else { - card.moveToZone(targetPickedCards, source.getSourceId(), game, false); - if (!game.isSimulation()) { - game.informPlayers(player.getLogName() + " moves a card to " + targetPickedCards.toString().toLowerCase()); - } - } - if (revealPickedCards) { - reveal.add(card); - } - } - } + Cards pickedCards = new CardsImpl(target.getTargets()); + cards.removeAll(pickedCards); + player.moveCards(pickedCards.getCards(game), targetPickedCards, source, game); if (revealPickedCards) { - player.revealCards(windowName, reveal, game); + player.revealCards(windowName, pickedCards, game); } } diff --git a/Mage/src/mage/abilities/effects/common/NameACardEffect.java b/Mage/src/mage/abilities/effects/common/NameACardEffect.java index b75279a993f..1a642fac0f0 100644 --- a/Mage/src/mage/abilities/effects/common/NameACardEffect.java +++ b/Mage/src/mage/abilities/effects/common/NameACardEffect.java @@ -29,7 +29,6 @@ package mage.abilities.effects.common; import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.repository.CardRepository; import mage.choices.Choice; @@ -72,7 +71,7 @@ public class NameACardEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + MageObject sourceObject = game.getPermanentEntering(source.getSourceId()); if (sourceObject == null) { game.getObject(source.getSourceId()); } diff --git a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java index 12a208ab190..f559340ecce 100644 --- a/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutPermanentOnBattlefieldEffect.java @@ -48,10 +48,9 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player; - if(useTargetController) { + if (useTargetController) { player = game.getPlayer(getTargetPointer().getFirst(game, source)); - } - else { + } else { player = game.getPlayer(source.getControllerId()); } String choiceText = "Put " + filter.getMessage() + " from your hand onto the battlefield?"; @@ -63,23 +62,21 @@ public class PutPermanentOnBattlefieldEffect extends OneShotEffect { if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { - player.putOntoBattlefieldWithInfo(card, game, Zone.HAND, source.getSourceId()); - return true; + return player.moveCards(card, Zone.BATTLEFIELD, source, game); } } - return false; + return true; } @Override public String getText(Mode mode) { - if(this.staticText != null && !this.staticText.isEmpty()) { + if (this.staticText != null && !this.staticText.isEmpty()) { return staticText; } - if(useTargetController) { + if (useTargetController) { return "that player may put " + filter.getMessage() + " from his or her hand onto the battlefield"; - } - else { + } else { return "you may put " + filter.getMessage() + " from your hand onto the battlefield"; } } diff --git a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java index d386e7d944f..650e1c32cbe 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java @@ -88,8 +88,7 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe card = game.getCard(getTargetPointer().getFirst(game, source)); } if (card != null) { - Zone currentZone = game.getState().getZone(card.getId()); - controller.putOntoBattlefieldWithInfo(card, game, currentZone, source.getSourceId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); } return true; } diff --git a/Mage/src/mage/abilities/effects/common/TapSourceEffect.java b/Mage/src/mage/abilities/effects/common/TapSourceEffect.java index aa655d15bfe..e510ae4844c 100644 --- a/Mage/src/mage/abilities/effects/common/TapSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapSourceEffect.java @@ -28,7 +28,6 @@ package mage.abilities.effects.common; import mage.abilities.Ability; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.game.Game; @@ -66,7 +65,7 @@ public class TapSourceEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getSourceId()); if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + permanent = game.getPermanentEntering(source.getSourceId()); } if (permanent != null) { if (withoutTrigger) { diff --git a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java index 0d2e474b159..15fbc93dbff 100644 --- a/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapSourceUnlessPaysEffect.java @@ -29,8 +29,8 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.costs.Cost; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -59,8 +59,8 @@ public class TapSourceUnlessPaysEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); } if (player != null && permanent != null) { if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) diff --git a/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java index 6d37cfc4bad..609ad65d290 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/GainAbilitySourceEffect.java @@ -30,7 +30,6 @@ package mage.abilities.effects.common.continuous; import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.cards.Card; import mage.constants.Duration; import mage.constants.Layer; @@ -94,7 +93,7 @@ public class GainAbilitySourceEffect extends ContinuousEffectImpl implements Sou public void init(Ability source, Game game) { super.init(source, game); if (affectedObjectsSet) { - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { affectedObjectList.add(new MageObjectReference(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()) + 1, game)); } else { diff --git a/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java b/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java index 0633ff60c63..a39c2b7de8b 100644 --- a/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/counter/AddCountersSourceEffect.java @@ -30,9 +30,9 @@ package mage.abilities.effects.common.counter; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.AbilityType; import mage.constants.Outcome; import mage.counters.Counter; import mage.game.Game; @@ -115,8 +115,8 @@ public class AddCountersSourceEffect extends OneShotEffect { } } else { Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent == null) { - permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + if (permanent == null && source.getAbilityType().equals(AbilityType.STATIC)) { + permanent = game.getPermanentEntering(source.getSourceId()); } if (permanent != null) { if (counter != null) { diff --git a/Mage/src/mage/abilities/keyword/AmplifyAbility.java b/Mage/src/mage/abilities/keyword/AmplifyAbility.java index 22a427c8402..a9cc43d60fc 100644 --- a/Mage/src/mage/abilities/keyword/AmplifyAbility.java +++ b/Mage/src/mage/abilities/keyword/AmplifyAbility.java @@ -39,13 +39,13 @@ import mage.constants.Zone; public class AmplifyAbility extends SimpleStaticAbility { public AmplifyAbility(AmplifyFactor amplifyFactor) { - super(Zone.BATTLEFIELD, new AmplifyEffect(amplifyFactor)); + super(Zone.ALL, new AmplifyEffect(amplifyFactor)); } - + public AmplifyAbility(final AmplifyAbility ability) { super(ability); } - + @Override public AmplifyAbility copy() { return new AmplifyAbility(this); diff --git a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java index ea4ddd1a6aa..385703b6691 100644 --- a/Mage/src/mage/abilities/keyword/AuraSwapAbility.java +++ b/Mage/src/mage/abilities/keyword/AuraSwapAbility.java @@ -104,9 +104,9 @@ class AuraSwapEffect extends OneShotEffect { if (controller.choose(Outcome.PutCardInPlay, target, source.getSourceId(), game)) { Card auraInHand = game.getCard(target.getFirstTarget()); if (auraInHand != null) { - controller.putOntoBattlefieldWithInfo(auraInHand, game, Zone.HAND, source.getSourceId()); + controller.moveCards(auraInHand, Zone.BATTLEFIELD, source, game); enchantedPermanent.addAttachment(auraInHand.getId(), game); - controller.moveCards(auraPermanent, null, Zone.HAND, source, game); + controller.moveCards(auraPermanent, Zone.HAND, source, game); return true; } } diff --git a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java index a7ae3282a18..0b8f4d29c61 100644 --- a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java +++ b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java @@ -2,7 +2,6 @@ package mage.abilities.keyword; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.counters.CounterType; @@ -56,7 +55,7 @@ class BloodthirstEffect extends OneShotEffect { BloodthirstEffect(int amount) { super(Outcome.BoostCreature); this.amount = amount; - staticText = new StringBuilder("this permanent comes into play with ").append(this.amount).append(" +1/+1 counters on it").toString(); + staticText = "this permanent comes into play with " + this.amount + " +1/+1 counters on it"; } BloodthirstEffect(final BloodthirstEffect effect) { @@ -70,10 +69,9 @@ class BloodthirstEffect extends OneShotEffect { if (player != null) { BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get("DamagedOpponents", source.getControllerId()); if (watcher != null && watcher.conditionMet()) { - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { permanent.addCounters(CounterType.P1P1.createInstance(amount), game); - } } return true; diff --git a/Mage/src/mage/abilities/keyword/DashAbility.java b/Mage/src/mage/abilities/keyword/DashAbility.java index 4a2d96170f0..b6a876053b0 100644 --- a/Mage/src/mage/abilities/keyword/DashAbility.java +++ b/Mage/src/mage/abilities/keyword/DashAbility.java @@ -76,10 +76,10 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts this.addDashCost(manaString); Ability ability = new EntersBattlefieldAbility( new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false), - DashedCondition.getInstance(), false, "", ""); + DashedCondition.getInstance(), "", ""); ability.addEffect(new DashAddDelayedTriggeredAbilityEffect()); addSubAbility(ability); - + } public DashAbility(final DashAbility ability) { @@ -226,16 +226,18 @@ class DashAddDelayedTriggeredAbilityEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Effect effect = new ReturnToHandTargetEffect(); - effect.setText("return the dashed creature from the battlefield to its owner's hand"); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); - // init target pointer now because the dashed creature will only be returned from current zone - effect.getTargetPointer().init(game, source); - DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - game.addDelayedTriggeredAbility(delayedAbility); + if (game.getPermanentEntering(source.getSourceId()) != null) { + Effect effect = new ReturnToHandTargetEffect(); + effect.setText("return the dashed creature from the battlefield to its owner's hand"); + // init target pointer now because the dashed creature will only be returned from battlefield zone (now in entering state so zone change counter is not raised yet) + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()) + 1)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } return false; } } diff --git a/Mage/src/mage/abilities/keyword/DevourAbility.java b/Mage/src/mage/abilities/keyword/DevourAbility.java index 1d4cdcfa822..ec3148a990a 100644 --- a/Mage/src/mage/abilities/keyword/DevourAbility.java +++ b/Mage/src/mage/abilities/keyword/DevourAbility.java @@ -27,51 +27,51 @@ */ package mage.abilities.keyword; -import mage.constants.Zone; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.DevourEffect; import mage.abilities.effects.common.DevourEffect.DevourFactor; +import mage.constants.Zone; /** * 502.82. Devour * - * 502.82a Devour is a static ability. "Devour N" means "As this object comes into play, - * you may sacrifice any number of creatures. This permanent comes into play with N +1/+1 - * counters on it for each creature sacrificed this way." + * 502.82a Devour is a static ability. "Devour N" means "As this object comes + * into play, you may sacrifice any number of creatures. This permanent comes + * into play with N +1/+1 counters on it for each creature sacrificed this way." * - * 502.82b Some objects have abilities that refer to the number of creatures the permanent - * devoured. "It devoured" means "sacrificed as a result of its devour ability as it came - * into play." + * 502.82b Some objects have abilities that refer to the number of creatures the + * permanent devoured. "It devoured" means "sacrificed as a result of its devour + * ability as it came into play." * * Devour appears only on creature cards. * - * A creature with devour can devour other creatures no matter how it comes into play. + * A creature with devour can devour other creatures no matter how it comes into + * play. * * You may choose to not sacrifice any creatures. * - * If you play a creature with devour as a spell, you choose how many and which creatures - * to devour as part of the resolution of that spell. (It can't be countered at this point.) - * The same is true of a spell or ability that lets you put a creature with devour into play. + * If you play a creature with devour as a spell, you choose how many and which + * creatures to devour as part of the resolution of that spell. (It can't be + * countered at this point.) The same is true of a spell or ability that lets + * you put a creature with devour into play. * - * You may sacrifice only creatures that are already in play. If a creature with devour and - * another creature are coming into play under your control at the same time, the creature - * with devour can't devour that other creature. The creature with devour also can't devour - * itself. + * You may sacrifice only creatures that are already in play. If a creature with + * devour and another creature are coming into play under your control at the + * same time, the creature with devour can't devour that other creature. The + * creature with devour also can't devour itself. * - * If multiple creatures with devour are coming into play under your control at the same time, - * you may use each one's devour ability. A creature you already control can be devoured by - * only one of them, however. (In other words, you can't sacrifice the same creature to satisfy - * multiple devour abilities.) All creatures devoured this way are sacrificed at the same time. + * If multiple creatures with devour are coming into play under your control at + * the same time, you may use each one's devour ability. A creature you already + * control can be devoured by only one of them, however. (In other words, you + * can't sacrifice the same creature to satisfy multiple devour abilities.) All + * creatures devoured this way are sacrificed at the same time. * * @author LevelX2 */ +public class DevourAbility extends SimpleStaticAbility { - public class DevourAbility extends SimpleStaticAbility { - - - - public DevourAbility(DevourFactor devourFactor) { - super(Zone.BATTLEFIELD, new DevourEffect(devourFactor)); + public DevourAbility(DevourFactor devourFactor) { + super(Zone.ALL, new DevourEffect(devourFactor)); } public DevourAbility(final DevourAbility ability) { @@ -82,4 +82,4 @@ import mage.abilities.effects.common.DevourEffect.DevourFactor; public DevourAbility copy() { return new DevourAbility(this); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/keyword/EvolveAbility.java b/Mage/src/mage/abilities/keyword/EvolveAbility.java index 16c1b316e01..00712d973c8 100644 --- a/Mage/src/mage/abilities/keyword/EvolveAbility.java +++ b/Mage/src/mage/abilities/keyword/EvolveAbility.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.keyword; import mage.abilities.Ability; @@ -44,46 +43,53 @@ import mage.target.targetpointer.FixedTarget; * FAQ 2013/01/11 * * 702.98. Evolve - * - * 702.98a Evolve is a triggered ability. "Evolve" means "Whenever a creature enters - * the battlefield under your control, if that creature's power is greater than this - * creature's power and/or that creature's toughness is greater than this creature's - * toughness, put a +1/+1 counter on this creature." * - * 702.98b If a creature has multiple instances of evolve, each triggers separately - * + * 702.98a Evolve is a triggered ability. "Evolve" means "Whenever a creature + * enters the battlefield under your control, if that creature's power is + * greater than this creature's power and/or that creature's toughness is + * greater than this creature's toughness, put a +1/+1 counter on this + * creature." + * + * 702.98b If a creature has multiple instances of evolve, each triggers + * separately + * * Rulings - * - * When comparing the stats of the two creatures, you always compare power to power and toughness to toughness. - * Whenever a creature enters the battlefield under your control, check its power and toughness against - * the power and toughness of the creature with evolve. If neither stat of the new creature is greater, - * evolve won't trigger at all. For example, if you control a 2/3 creature with evolve and a 2/2 creature - * enters the battlefield under your control, you won't have the opportunity to cast a spell like Giant Growth - * to make the 2/2 creature large enough to cause evolve to trigger. - * If evolve triggers, the stat comparison will happen again when the ability tries to resolve. If - * neither stat of the new creature is greater, the ability will do nothing. If the creature that - * entered the battlefield leaves the battlefield before evolve tries to resolve, use its last known - * power and toughness to compare the stats. - * If a creature enters the battlefield with +1/+1 counters on it, consider those counters when determining - * if evolve will trigger. For example, a 1/1 creature that enters the battlefield with two +1/+1 counters - * on it will cause the evolve ability of a 2/2 creature to trigger. - * If multiple creatures enter the battlefield at the same time, evolve may trigger multiple times, although the stat - * comparison will take place each time one of those abilities tries to resolve. For example, if you control a 2/2 - * creature with evolve and two 3/3 creatures enter the battlefield, evolve will trigger twice. The first ability - * will resolve and put a +1/+1 counter on the creature with evolve. When the second ability tries to resolve, - * neither the power nor the toughness of the new creature is greater than that of the creature with evolve, - * so that ability does nothing. - * When comparing the stats as the evolve ability resolves, it's possible that the stat that's greater changes - * from power to toughness or vice versa. If this happens, the ability will still resolve and you'll put a +1/+1 - * counter on the creature with evolve. For example, if you control a 2/2 creature with evolve and a 1/3 creature - * enters the battlefield under your control, it toughness is greater so evolve will trigger. In response, the 1/3 - * creature gets +2/-2. When the evolve trigger tries to resolve, its power is greater. You'll put a +1/+1 - * counter on the creature with evolve. - * + * + * When comparing the stats of the two creatures, you always compare power to + * power and toughness to toughness. Whenever a creature enters the battlefield + * under your control, check its power and toughness against the power and + * toughness of the creature with evolve. If neither stat of the new creature is + * greater, evolve won't trigger at all. For example, if you control a 2/3 + * creature with evolve and a 2/2 creature enters the battlefield under your + * control, you won't have the opportunity to cast a spell like Giant Growth to + * make the 2/2 creature large enough to cause evolve to trigger. If evolve + * triggers, the stat comparison will happen again when the ability tries to + * resolve. If neither stat of the new creature is greater, the ability will do + * nothing. If the creature that entered the battlefield leaves the battlefield + * before evolve tries to resolve, use its last known power and toughness to + * compare the stats. If a creature enters the battlefield with +1/+1 counters + * on it, consider those counters when determining if evolve will trigger. For + * example, a 1/1 creature that enters the battlefield with two +1/+1 counters + * on it will cause the evolve ability of a 2/2 creature to trigger. If multiple + * creatures enter the battlefield at the same time, evolve may trigger multiple + * times, although the stat comparison will take place each time one of those + * abilities tries to resolve. For example, if you control a 2/2 creature with + * evolve and two 3/3 creatures enter the battlefield, evolve will trigger + * twice. The first ability will resolve and put a +1/+1 counter on the creature + * with evolve. When the second ability tries to resolve, neither the power nor + * the toughness of the new creature is greater than that of the creature with + * evolve, so that ability does nothing. When comparing the stats as the evolve + * ability resolves, it's possible that the stat that's greater changes from + * power to toughness or vice versa. If this happens, the ability will still + * resolve and you'll put a +1/+1 counter on the creature with evolve. For + * example, if you control a 2/2 creature with evolve and a 1/3 creature enters + * the battlefield under your control, it toughness is greater so evolve will + * trigger. In response, the 1/3 creature gets +2/-2. When the evolve trigger + * tries to resolve, its power is greater. You'll put a +1/+1 counter on the + * creature with evolve. + * * @author LevelX2 */ - - public class EvolveAbility extends TriggeredAbilityImpl { public EvolveAbility() { @@ -169,4 +175,3 @@ class EvolveEffect extends OneShotEffect { return false; } } - diff --git a/Mage/src/mage/abilities/keyword/GraftAbility.java b/Mage/src/mage/abilities/keyword/GraftAbility.java index 45eed19b928..14132f4f128 100644 --- a/Mage/src/mage/abilities/keyword/GraftAbility.java +++ b/Mage/src/mage/abilities/keyword/GraftAbility.java @@ -1,30 +1,30 @@ /* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.abilities.keyword; import java.util.Locale; @@ -48,18 +48,19 @@ import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; /** - * 702.56. Graft - * 702.56a. Graft represents both a static ability and a triggered ability. Graft N means, - * "This permanent enters the battlefield with N +1/+1 counters on it" and, "Whenever - * another creature enters the battlefield, if this permanent has a +1/+1 counter on it, - * you may move a +1/+1 counter from this permanent onto that creature." + * 702.56. Graft 702.56a. Graft represents both a static ability and a triggered + * ability. Graft N means, "This permanent enters the battlefield with N +1/+1 + * counters on it" and, "Whenever another creature enters the battlefield, if + * this permanent has a +1/+1 counter on it, you may move a +1/+1 counter from + * this permanent onto that creature." * - * 702.56b. If a creature has multiple instances of graft, each one works separately. + * 702.56b. If a creature has multiple instances of graft, each one works + * separately. * * @author LevelX2 */ - public class GraftAbility extends TriggeredAbilityImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); private int amount; @@ -112,10 +113,10 @@ public class GraftAbility extends TriggeredAbilityImpl { @Override public String getRule() { StringBuilder sb = new StringBuilder("Graft"); - sb.append(" ").append(amount).append(" (This ").append(cardtype).append(" enters the battlefield with ") - .append(amount == 1 ? "a": CardUtil.numberToText(amount)) - .append(" +1/+1 counter on it. Whenever a creature enters the battlefield, you may move a +1/+1 counter from this ") - .append(cardtype).append(" onto it.)"); + sb.append(" ").append(amount).append(" (This ").append(cardtype).append(" enters the battlefield with ") + .append(amount == 1 ? "a" : CardUtil.numberToText(amount)) + .append(" +1/+1 counter on it. Whenever a creature enters the battlefield, you may move a +1/+1 counter from this ") + .append(cardtype).append(" onto it.)"); return sb.toString(); } @@ -126,7 +127,7 @@ class GraftStaticAbility extends StaticAbility { private String ruleText; public GraftStaticAbility(int amount) { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); + super(Zone.ALL, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); ruleText = new StringBuilder("This enters the battlefield with ").append(amount).append(" +1/+1 counter on it.").toString(); this.setRuleVisible(false); } @@ -147,7 +148,6 @@ class GraftStaticAbility extends StaticAbility { } } - class GraftDistributeCounterEffect extends OneShotEffect { public GraftDistributeCounterEffect() { diff --git a/Mage/src/mage/abilities/keyword/HideawayAbility.java b/Mage/src/mage/abilities/keyword/HideawayAbility.java index 57ff119d397..b312fc9f3fb 100644 --- a/Mage/src/mage/abilities/keyword/HideawayAbility.java +++ b/Mage/src/mage/abilities/keyword/HideawayAbility.java @@ -65,7 +65,7 @@ import mage.util.CardUtil; public class HideawayAbility extends StaticAbility { public HideawayAbility() { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new TapSourceEffect(true))); + super(Zone.ALL, new EntersBattlefieldEffect(new TapSourceEffect(true))); Ability ability = new EntersBattlefieldTriggeredAbility(new HideawayExileEffect(), false); ability.setRuleVisible(false); addSubAbility(ability); @@ -115,17 +115,17 @@ class HideawayExileEffect extends OneShotEffect { if (hideawaySource == null || controller == null) { return false; } - + Cards cards = new CardsImpl(Zone.LIBRARY); - cards.addAll(controller.getLibrary().getTopCards(game, 4)); + cards.addAll(controller.getLibrary().getTopCards(game, 4)); if (cards.size() > 0) { TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1); if (controller.choose(Outcome.Detriment, cards, target1, game)) { Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), - "Hideaway (" + hideawaySource.getIdName() +")", source.getSourceId(), game, Zone.LIBRARY, false); + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), + "Hideaway (" + hideawaySource.getIdName() + ")", source.getSourceId(), game, Zone.LIBRARY, false); card.setFaceDown(true, game); } } @@ -159,7 +159,7 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - if (game.getState().getZone(objectId) != Zone.EXILED + if (game.getState().getZone(objectId) != Zone.EXILED || !game.getState().getCardState(objectId).isFaceDown()) { return false; } @@ -180,4 +180,3 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl { return false; } } - diff --git a/Mage/src/mage/abilities/keyword/KickerAbility.java b/Mage/src/mage/abilities/keyword/KickerAbility.java index f7bc6c8ff84..138189fc086 100644 --- a/Mage/src/mage/abilities/keyword/KickerAbility.java +++ b/Mage/src/mage/abilities/keyword/KickerAbility.java @@ -203,7 +203,7 @@ public class KickerAbility extends StaticAbility implements OptionalAdditionalSo if (zcc == 0) { zcc = game.getState().getZoneChangeCounter(source.getSourceId()); } - if (zcc > 0 && (source.getAbilityType().equals(AbilityType.TRIGGERED) || source.getAbilityType().equals(AbilityType.STATIC))) { + if (zcc > 0 && (source.getAbilityType().equals(AbilityType.TRIGGERED))) { --zcc; } return String.valueOf(zcc) + ((kickerCosts.size() > 1) ? costText : ""); diff --git a/Mage/src/mage/abilities/keyword/ModularAbility.java b/Mage/src/mage/abilities/keyword/ModularAbility.java index 3d9133f57ec..5efdb7a01a7 100644 --- a/Mage/src/mage/abilities/keyword/ModularAbility.java +++ b/Mage/src/mage/abilities/keyword/ModularAbility.java @@ -108,7 +108,7 @@ class ModularStaticAbility extends StaticAbility { private String ruleText; public ModularStaticAbility(int amount) { - super(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); + super(Zone.ALL, new EntersBattlefieldEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance(amount)))); ruleText = "This enters the battlefield with " + CardUtil.numberToText(amount, "a") + " +1/+1 counter" + (amount != 1 ? "s" : "") + " on it."; this.setRuleVisible(false); } diff --git a/Mage/src/mage/abilities/keyword/SunburstAbility.java b/Mage/src/mage/abilities/keyword/SunburstAbility.java index bc4a9319046..ba1b59adcee 100644 --- a/Mage/src/mage/abilities/keyword/SunburstAbility.java +++ b/Mage/src/mage/abilities/keyword/SunburstAbility.java @@ -31,7 +31,6 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.SunburstCount; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.constants.CardType; @@ -89,7 +88,7 @@ class SunburstEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent permanent = game.getPermanentEntering(source.getSourceId()); if (permanent != null) { Counter counter; if (permanent.getCardType().contains(CardType.CREATURE)) { diff --git a/Mage/src/mage/abilities/keyword/TributeAbility.java b/Mage/src/mage/abilities/keyword/TributeAbility.java index f752865498b..5cf0b1cf8e5 100644 --- a/Mage/src/mage/abilities/keyword/TributeAbility.java +++ b/Mage/src/mage/abilities/keyword/TributeAbility.java @@ -30,7 +30,6 @@ package mage.abilities.keyword; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.EntersBattlefieldEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.constants.Outcome; @@ -51,7 +50,7 @@ public class TributeAbility extends EntersBattlefieldAbility { private int tributeValue; public TributeAbility(int tributeValue) { - super(new TributeEffect(tributeValue), false); + super(new TributeEffect(tributeValue)); this.tributeValue = tributeValue; } @@ -98,7 +97,7 @@ class TributeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = (Permanent) getValue(EntersBattlefieldEffect.ENTERING_PERMANENT); + Permanent sourcePermanent = game.getPermanentEntering(source.getSourceId()); if (controller != null && sourcePermanent != null) { UUID opponentId; if (game.getOpponents(controller.getId()).size() == 1) { diff --git a/Mage/src/mage/abilities/keyword/UnleashAbility.java b/Mage/src/mage/abilities/keyword/UnleashAbility.java index 45112f075b2..07cccfe4880 100644 --- a/Mage/src/mage/abilities/keyword/UnleashAbility.java +++ b/Mage/src/mage/abilities/keyword/UnleashAbility.java @@ -26,14 +26,14 @@ * or implied, of BetaSteward_at_googlemail.com. */ package mage.abilities.keyword; - -import mage.constants.Duration; -import mage.constants.Outcome; + import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.RestrictionEffect; +import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; @@ -41,49 +41,41 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; - -/** - * - * @author LevelX2 - */ - // // 702.96. Unleash // -// 702.96a Unleash is a keyword that represents two static abilities. +// 702.96a Unleash is a keyword that represents two static abilities. // "Unleash" means "You may have this permanent enter the battlefield with an additional +1/+1 counter on it" // and "This permanent can’t block as long as it has a +1/+1 counter on it." +public class UnleashAbility extends SimpleStaticAbility { - - public class UnleashAbility extends SimpleStaticAbility { - public UnleashAbility() { super(Zone.ALL, new UnleashReplacementEffect()); this.addEffect(new UnleashRestrictionEffect()); } - + public UnleashAbility(final UnleashAbility ability) { super(ability); } - + @Override public UnleashAbility copy() { return new UnleashAbility(this); } - + @Override public String getRule() { return "Unleash (You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it.)"; } } - + class UnleashReplacementEffect extends ReplacementEffectImpl { - + public UnleashReplacementEffect() { super(Duration.EndOfGame, Outcome.Detriment); } - + public UnleashReplacementEffect(UnleashReplacementEffect effect) { super(effect); } @@ -95,53 +87,51 @@ class UnleashReplacementEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getTargetId().equals(source.getSourceId())) { - return true; - } - return false; + return event.getTargetId().equals(source.getSourceId()); } - + @Override public boolean apply(Game game, Ability source) { return false; } - + @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Permanent creature = game.getPermanent(event.getTargetId()); + Permanent creature = game.getPermanentEntering(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); if (creature != null && controller != null) { - if (controller.chooseUse(outcome, "Unleash "+ creature.getName() +"?", source, game)) { - if (!game.isSimulation()) + if (controller.chooseUse(outcome, "Unleash " + creature.getName() + "?", source, game)) { + if (!game.isSimulation()) { game.informPlayers(controller.getLogName() + " unleashes " + creature.getName()); + } creature.addCounters(CounterType.P1P1.createInstance(), game); } } return false; } - + @Override public String getText(Mode mode) { return staticText; } - + @Override public UnleashReplacementEffect copy() { return new UnleashReplacementEffect(this); } - + } - + class UnleashRestrictionEffect extends RestrictionEffect { - + public UnleashRestrictionEffect() { super(Duration.WhileOnBattlefield); } - + public UnleashRestrictionEffect(final UnleashRestrictionEffect effect) { super(effect); } - + @Override public boolean applies(Permanent permanent, Ability source, Game game) { if (permanent != null && permanent.getId().equals(source.getSourceId())) { @@ -151,14 +141,14 @@ class UnleashRestrictionEffect extends RestrictionEffect { } return false; } - + @Override public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { return false; } - + @Override public UnleashRestrictionEffect copy() { return new UnleashRestrictionEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 2d3fa165cfe..a24fc9323df 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -512,7 +512,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card { } break; case STACK: - StackObject stackObject = game.getStack().getSpell(getSpellAbility().getId()); + StackObject stackObject; + if (getSpellAbility() != null) { + stackObject = game.getStack().getSpell(getSpellAbility().getId()); + } else { + stackObject = game.getStack().getSpell(this.getId()); + } if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId()); if (stackObject == null) { diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index b75ea6a76e5..432ade1bf80 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -115,6 +115,10 @@ public interface Game extends MageItem, Serializable { Permanent getPermanentOrLKIBattlefield(UUID permanentId); + Permanent getPermanentEntering(UUID permanentId); + + Map getPermanentsEntering(); + Map> getLKI(); Card getCard(UUID cardId); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index f67b6387437..816db0ded7b 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -176,6 +176,9 @@ public abstract class GameImpl implements Game, Serializable { // Used to check if an object was moved by the current effect in resolution (so Wrath like effect can be handled correctly) protected Map> shortLivingLKI = new EnumMap<>(Zone.class); + // Permanents entering the Battlefield while handling replacement effects before they are added to the battlefield + protected Map permanentsEntering = new HashMap<>(); + protected GameState state; private transient Stack savedStates = new Stack<>(); protected transient GameStates gameStates = new GameStates(); @@ -244,6 +247,7 @@ public abstract class GameImpl implements Game, Serializable { this.lki.putAll(game.lki); this.lkiExtended.putAll(game.lkiExtended); this.shortLivingLKI.putAll(game.shortLivingLKI); + this.permanentsEntering.putAll(game.permanentsEntering); if (logger.isDebugEnabled()) { copyCount++; copyTime += (System.currentTimeMillis() - t1); @@ -501,6 +505,16 @@ public abstract class GameImpl implements Game, Serializable { return permanent; } + @Override + public Permanent getPermanentEntering(UUID permanentId) { + return permanentsEntering.get(permanentId); + } + + @Override + public Map getPermanentsEntering() { + return permanentsEntering; + } + @Override public Card getCard(UUID cardId) { if (cardId == null) { @@ -891,7 +905,7 @@ public abstract class GameImpl implements Game, Serializable { return; } getState().setChoosingPlayerId(choosingPlayerId); // needed to start/stop the timer if active - if (choosingPlayer != null && choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { + if (choosingPlayer.choose(Outcome.Benefit, targetPlayer, null, this)) { startingPlayerId = targetPlayer.getTargets().get(0); } else if (getState().getPlayers().size() < 3) { // not possible to choose starting player, choosing player has probably conceded, so stop here @@ -2539,8 +2553,10 @@ public abstract class GameImpl implements Game, Serializable { card.setZone(Zone.BATTLEFIELD, this); card.setOwnerId(ownerId); PermanentCard permanent = new PermanentCard(card.getCard(), ownerId, this); - getBattlefield().addPermanent(permanent); + getPermanentsEntering().put(permanent.getId(), permanent); permanent.entersBattlefield(permanent.getId(), this, Zone.OUTSIDE, false); + getBattlefield().addPermanent(permanent); + getPermanentsEntering().remove(permanent.getId()); ((PermanentImpl) permanent).removeSummoningSickness(); if (card.isTapped()) { permanent.setTapped(true); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 783801dc7f2..3b767772abc 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -647,6 +647,9 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { if (!game.replaceEvent(new GameEvent(GameEvent.EventType.ATTACH, objectId, permanentId, controllerId))) { this.attachments.add(permanentId); Permanent attachment = game.getPermanent(permanentId); + if (attachment == null) { + attachment = game.getPermanentEntering(permanentId); + } if (attachment != null) { attachment.attachTo(objectId, game); game.fireEvent(new GameEvent(GameEvent.EventType.ATTACHED, objectId, permanentId, controllerId)); diff --git a/Mage/src/mage/game/permanent/token/Token.java b/Mage/src/mage/game/permanent/token/Token.java index e60605b0892..5f9686cf8a9 100644 --- a/Mage/src/mage/game/permanent/token/Token.java +++ b/Mage/src/mage/game/permanent/token/Token.java @@ -42,6 +42,7 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; import mage.game.permanent.PermanentToken; import mage.players.Player; @@ -148,31 +149,43 @@ public class Token extends MageObjectImpl { GameEvent event = new GameEvent(EventType.CREATE_TOKEN, null, sourceId, controllerId, amount, this.getCardType().contains(CardType.CREATURE)); if (!game.replaceEvent(event)) { amount = event.getAmount(); + + List permanents = new ArrayList<>(); + List permanentsEntered = new ArrayList<>(); + for (int i = 0; i < amount; i++) { PermanentToken newToken = new PermanentToken(this, event.getPlayerId(), setCode, game); // use event.getPlayerId() because it can be replaced by replacement effect game.getState().addCard(newToken); - game.addPermanent(newToken); - if (tapped) { - newToken.setTapped(true); - } - this.lastAddedTokenIds.add(newToken.getId()); - this.lastAddedTokenId = newToken.getId(); - game.setScopeRelevant(true); - game.applyEffects(); - boolean entered = newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true); - game.setScopeRelevant(false); - game.applyEffects(); - if (entered) { - game.fireEvent(new ZoneChangeEvent(newToken, event.getPlayerId(), Zone.OUTSIDE, Zone.BATTLEFIELD)); - if (attacking && game.getCombat() != null) { - game.getCombat().addAttackingCreature(newToken.getId(), game); - } - if (!game.isSimulation()) { - game.informPlayers(controller.getLogName() + " puts a " + newToken.getLogName() + " token onto the battlefield"); - } + permanents.add(newToken); + game.getPermanentsEntering().put(newToken.getId(), newToken); + newToken.setTapped(tapped); + } + game.setScopeRelevant(true); + for (Permanent permanent : permanents) { + if (permanent.entersBattlefield(sourceId, game, Zone.OUTSIDE, true)) { + permanentsEntered.add(permanent); + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } + game.setScopeRelevant(false); + for (Permanent permanent : permanentsEntered) { + game.addPermanent(permanent); + permanent.setZone(Zone.BATTLEFIELD, game); + game.getPermanentsEntering().remove(permanent.getId()); + this.lastAddedTokenIds.add(permanent.getId()); + this.lastAddedTokenId = permanent.getId(); + game.addSimultaneousEvent(new ZoneChangeEvent(permanent, permanent.getControllerId(), Zone.OUTSIDE, Zone.BATTLEFIELD)); + if (attacking && game.getCombat() != null) { + game.getCombat().addAttackingCreature(permanent.getId(), game); + } + if (!game.isSimulation()) { + game.informPlayers(controller.getLogName() + " puts a " + permanent.getLogName() + " token onto the battlefield"); + } + + } + game.applyEffects(); return true; } return false; diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 482bfb8451e..83b99d90d46 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -232,7 +232,7 @@ public class Spell extends StackObjImpl implements Card { card.getCardType().remove(CardType.CREATURE); card.getSubtype().add("Aura"); } - if (card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId)) { + if (controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null)) { if (bestow) { // card will be copied during putOntoBattlefield, so the card of CardPermanent has to be changed // TODO: Find a better way to prevent bestow creatures from being effected by creature affecting abilities @@ -253,8 +253,7 @@ public class Spell extends StackObjImpl implements Card { // Aura has no legal target and its a bestow enchantment -> Add it to battlefield as creature if (this.getSpellAbility() instanceof BestowAbility) { updateOptionalCosts(0); - result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId); - return result; + return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); } else { //20091005 - 608.2b if (!game.isSimulation()) { @@ -265,9 +264,7 @@ public class Spell extends StackObjImpl implements Card { } } else { updateOptionalCosts(0); -// return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); - result = card.putOntoBattlefield(game, Zone.STACK, ability.getSourceId(), controllerId, false, faceDown); - return result; + return controller.moveCards(card, Zone.BATTLEFIELD, ability, game, false, faceDown, false, null); } } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index b484fb8ccf9..60edef58aba 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -629,15 +629,26 @@ public interface Player extends MageItem, Copyable { * @param game * @return */ + @Deprecated boolean moveCards(Cards cards, Zone fromZone, Zone toZone, Ability source, Game game); + @Deprecated boolean moveCards(Card card, Zone fromZone, Zone toZone, Ability source, Game game); + @Deprecated boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game); + boolean moveCards(Card card, Zone toZone, Ability source, Game game); + boolean moveCards(Card card, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects); + boolean moveCards(Cards cards, Zone toZone, Ability source, Game game); + + boolean moveCards(Set cards, Zone toZone, Ability source, Game game); + /** + * Iniversal method to move cards from one zone to another. Do not mix + * objects from different from zones to move. * * @param cards * @param toZone @@ -740,6 +751,7 @@ public interface Player extends MageItem, Copyable { * @param sourceId * @return */ + @Deprecated boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId); /** diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 011d716acd2..2330bd54541 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -773,6 +773,9 @@ public abstract class PlayerImpl implements Player, Serializable { public boolean addAttachment(UUID permanentId, Game game) { if (!this.attachments.contains(permanentId)) { Permanent aura = game.getPermanent(permanentId); + if (aura == null) { + aura = game.getPermanentEntering(permanentId); + } if (aura != null) { if (!game.replaceEvent(new GameEvent(GameEvent.EventType.ENCHANT_PLAYER, playerId, permanentId, aura.getControllerId()))) { this.attachments.add(permanentId); @@ -1016,8 +1019,7 @@ public abstract class PlayerImpl implements Player, Serializable { //20091005 - 305.1 if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) { // int bookmark = game.bookmarkState(); - Zone zone = game.getState().getZone(card.getId()); - if (card.putOntoBattlefield(game, zone, null, playerId)) { + if (moveCards(card, Zone.BATTLEFIELD, playLandAbility, game, false, false, false, null)) { landsPlayed++; game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), card.getId(), playerId)); game.fireInformEvent(getLogName() + " plays " + card.getLogName()); @@ -2980,40 +2982,12 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean moveCards(Set cards, Zone fromZone, Zone toZone, Ability source, Game game) { - if (cards.isEmpty()) { - return true; - } - Set successfulMovedCards = new LinkedHashSet<>(); - switch (toZone) { - case EXILED: - for (Card card : cards) { - fromZone = game.getState().getZone(card.getId()); - boolean withName = (fromZone.equals(Zone.BATTLEFIELD) || fromZone.equals(Zone.STACK)) || !card.isFaceDown(game); - if (moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName)) { - successfulMovedCards.add(card); - } - } - break; - case GRAVEYARD: - successfulMovedCards = moveCardsToGraveyardWithInfo(cards, source, game, fromZone); - break; - case HAND: - case BATTLEFIELD: - return moveCards(cards, toZone, source, game, false, false, false, null); - case LIBRARY: - for (Card card : cards) { - fromZone = game.getState().getZone(card.getId()); - boolean hideCard = fromZone.equals(Zone.HAND) || fromZone.equals(Zone.LIBRARY); - if (moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, !hideCard)) { - successfulMovedCards.add(card); - } - } - break; - default: - throw new UnsupportedOperationException("to Zone not supported yet"); - } - game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); - return successfulMovedCards.size() > 0; + return moveCards(cards, toZone, source, game, false, false, false, null); + } + + @Override + public boolean moveCards(Card card, Zone toZone, Ability source, Game game) { + return moveCards(card, toZone, source, game, false, false, false, null); } @Override @@ -3025,6 +2999,16 @@ public abstract class PlayerImpl implements Player, Serializable { return moveCards(cardList, toZone, source, game, tapped, faceDown, byOwner, appliedEffects); } + @Override + public boolean moveCards(Cards cards, Zone toZone, Ability source, Game game) { + return moveCards(cards.getCards(game), toZone, source, game); + } + + @Override + public boolean moveCards(Set cards, Zone toZone, Ability source, Game game) { + return moveCards(cards, toZone, source, game, false, false, false, null); + } + @Override public boolean moveCards(Set cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, ArrayList appliedEffects) { if (cards.isEmpty()) { @@ -3033,7 +3017,11 @@ public abstract class PlayerImpl implements Player, Serializable { Set successfulMovedCards = new LinkedHashSet<>(); Zone fromZone = null; switch (toZone) { - case BATTLEFIELD: + case GRAVEYARD: + fromZone = game.getState().getZone(cards.iterator().next().getId()); + successfulMovedCards = moveCardsToGraveyardWithInfo(cards, source, game, fromZone); + break; + case BATTLEFIELD: // new logic that does not yet add the permanents to battlefield while replacement effects are handled List permanents = new ArrayList<>(); List permanentsEntered = new ArrayList<>(); for (Card card : cards) { @@ -3047,6 +3035,7 @@ public abstract class PlayerImpl implements Player, Serializable { // get permanent Permanent permanent = new PermanentCard(card, event.getPlayerId(), game);// controlling player can be replaced so use event player now permanents.add(permanent); + game.getPermanentsEntering().put(permanent.getId(), permanent); card.checkForCountersToAdd(permanent, game); permanent.setTapped(tapped); permanent.setFaceDown(faceDown, game); @@ -3060,6 +3049,8 @@ public abstract class PlayerImpl implements Player, Serializable { fromZone = game.getState().getZone(permanent.getId()); if (permanent.entersBattlefield(source.getSourceId(), game, fromZone, true)) { permanentsEntered.add(permanent); + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } game.setScopeRelevant(false); @@ -3071,11 +3062,16 @@ public abstract class PlayerImpl implements Player, Serializable { game.getContinuousEffects().setController(permanent.getId(), permanent.getControllerId()); game.addPermanent(permanent); permanent.setZone(Zone.BATTLEFIELD, game); - // check if there are counters to add to the permanent (e.g. from non replacement effects like Persist) - + game.getPermanentsEntering().remove(permanent.getId()); game.setScopeRelevant(true); successfulMovedCards.add(permanent); game.addSimultaneousEvent(new ZoneChangeEvent(permanent, permanent.getControllerId(), fromZone, Zone.BATTLEFIELD)); + if (!game.isSimulation()) { + game.informPlayers(this.getLogName() + " puts " + (faceDown ? "a card face down " : permanent.getLogName()) + + " from " + fromZone.toString().toLowerCase(Locale.ENGLISH) + " onto the Battlefield"); + } + } else { + game.getPermanentsEntering().remove(permanent.getId()); } } game.applyEffects(); @@ -3090,8 +3086,26 @@ public abstract class PlayerImpl implements Player, Serializable { } } break; + case EXILED: + for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); + boolean withName = (fromZone.equals(Zone.BATTLEFIELD) || fromZone.equals(Zone.STACK)) || !card.isFaceDown(game); + if (moveCardToExileWithInfo(card, null, "", source == null ? null : source.getSourceId(), game, fromZone, withName)) { + successfulMovedCards.add(card); + } + } + break; + case LIBRARY: + for (Card card : cards) { + fromZone = game.getState().getZone(card.getId()); + boolean hideCard = fromZone.equals(Zone.HAND) || fromZone.equals(Zone.LIBRARY); + if (moveCardToLibraryWithInfo(card, source == null ? null : source.getSourceId(), game, fromZone, true, !hideCard)) { + successfulMovedCards.add(card); + } + } + break; default: - throw new UnsupportedOperationException("to Zone not supported yet"); + throw new UnsupportedOperationException("to Zone" + toZone.toString() + " not supported yet"); } game.fireEvent(new ZoneChangeGroupEvent(successfulMovedCards, source == null ? null : source.getSourceId(), this.getId(), fromZone, toZone)); @@ -3293,16 +3307,19 @@ public abstract class PlayerImpl implements Player, Serializable { return result; } + @Deprecated @Override public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId) { return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, false, false); } + @Deprecated @Override public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) { return this.putOntoBattlefieldWithInfo(card, game, fromZone, sourceId, tapped, false); } + @Deprecated @Override public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped, boolean facedown) { boolean result = false; diff --git a/Mage/src/mage/util/functions/AddSubtypeApplier.java b/Mage/src/mage/util/functions/AddSubtypeApplier.java new file mode 100644 index 00000000000..a007b6a9f31 --- /dev/null +++ b/Mage/src/mage/util/functions/AddSubtypeApplier.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package mage.util.functions; + +import mage.MageObject; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class AddSubtypeApplier extends ApplyToPermanent { + + private final String subtype; + + public AddSubtypeApplier(String subtype) { + this.subtype = subtype; + } + + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getSubtype().contains(subtype)) { + permanent.getSubtype().add(subtype); + } + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getSubtype().contains(subtype)) { + mageObject.getSubtype().add(subtype); + } + return true; + } + +} diff --git a/Mage/src/mage/util/functions/CardTypeApplier.java b/Mage/src/mage/util/functions/CardTypeApplier.java index dcb8eeb8c33..48a3eb54130 100644 --- a/Mage/src/mage/util/functions/CardTypeApplier.java +++ b/Mage/src/mage/util/functions/CardTypeApplier.java @@ -27,10 +27,36 @@ */ package mage.util.functions; +import mage.MageObject; +import mage.constants.CardType; +import mage.game.Game; +import mage.game.permanent.Permanent; + /** * * @author LevelX2 */ -public class CardTypeApplier { +public class CardTypeApplier extends ApplyToPermanent { + private final CardType cardType; + + public CardTypeApplier(CardType cardType) { + this.cardType = cardType; + } + + @Override + public Boolean apply(Game game, Permanent permanent) { + if (!permanent.getCardType().contains(cardType)) { + permanent.getCardType().add(cardType); + } + return true; + } + + @Override + public Boolean apply(Game game, MageObject mageObject) { + if (!mageObject.getCardType().contains(cardType)) { + mageObject.getCardType().add(cardType); + } + return true; + } }