From 9b3ff32a3399aa71828e9f337438581c8384c4d5 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Sun, 31 Dec 2023 14:10:37 -0500 Subject: [PATCH] Rework sacrifice effects to support "can't be sacrificed" (#11587) * add TargetSacrifice and canBeSacrificed * SacrificeTargetCost refactor, now uses TargetSacrifice, constructors simplified, subclasses aligned * fix text errors introduced by refactor * refactor SacrificeEffect, SacrificeAllEffect, SacrificeOpponentsEffect * cleanup keyword abilities involving sacrifice * fix a bunch of custom effect classes involving sacrifice * fix test choices * update Assault Suit implementation * fix filter check arguments * add documentation to refactored common classes * [CLB] Implement Jon Irenicus, Shattered One * implement "{this} can't be sacrificed" * add tests for Assault Suit and Jon Irenicus * refactor out PlayerToRightGainsControlOfSourceEffect * implement [LTC] Hithlain Rope * add choose hint to all TargetSacrifice --------- Co-authored-by: Evan Kranzler Co-authored-by: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com> --- .../java/mage/player/ai/ComputerPlayer.java | 10 +- Mage.Sets/src/mage/cards/a/AJedisFervor.java | 6 +- Mage.Sets/src/mage/cards/a/Abjure.java | 2 +- .../src/mage/cards/a/AcererakTheArchlich.java | 5 +- Mage.Sets/src/mage/cards/a/AgentOfShauku.java | 4 +- .../src/mage/cards/a/AggressiveMining.java | 3 +- .../src/mage/cards/a/AhnCropInvader.java | 2 +- Mage.Sets/src/mage/cards/a/AirdropCondor.java | 2 +- .../src/mage/cards/a/AkkiAvalanchers.java | 2 +- .../src/mage/cards/a/AkutaBornOfAsh.java | 3 +- Mage.Sets/src/mage/cards/a/AltarsReap.java | 2 +- .../src/mage/cards/a/AmbushCommander.java | 2 +- .../src/mage/cards/a/AnakinSkywalker.java | 2 +- Mage.Sets/src/mage/cards/a/AngelicPurge.java | 3 +- Mage.Sets/src/mage/cards/a/AngelsHerald.java | 4 +- .../src/mage/cards/a/AnnihilatingGlare.java | 2 +- .../src/mage/cards/a/ApocalypseDemon.java | 2 +- .../src/mage/cards/a/ArcaneSpyglass.java | 2 +- .../src/mage/cards/a/ArcboundRavager.java | 2 +- .../src/mage/cards/a/ArchdemonOfGreed.java | 3 +- Mage.Sets/src/mage/cards/a/ArensonsAura.java | 2 +- Mage.Sets/src/mage/cards/a/ArgothianWurm.java | 5 +- Mage.Sets/src/mage/cards/a/ArmsDealer.java | 2 +- Mage.Sets/src/mage/cards/a/ArmyAnts.java | 2 +- Mage.Sets/src/mage/cards/a/Artillerize.java | 2 +- .../mage/cards/a/AshnodFleshMechanist.java | 2 +- .../a/Asmoranomardicadaistinaculdacar.java | 2 +- Mage.Sets/src/mage/cards/a/AssaultSuit.java | 87 ++++++------- Mage.Sets/src/mage/cards/a/Atog.java | 2 +- Mage.Sets/src/mage/cards/a/Atogatog.java | 12 +- Mage.Sets/src/mage/cards/a/Attrition.java | 2 +- .../src/mage/cards/a/AudaciousReshapers.java | 4 +- Mage.Sets/src/mage/cards/a/AuraFracture.java | 3 +- Mage.Sets/src/mage/cards/a/Auratog.java | 2 +- .../mage/cards/a/AyaraFirstOfLocthwain.java | 2 +- .../src/mage/cards/a/AyliEternalPilgrim.java | 4 +- .../mage/cards/b/BabaLysagaNightWitch.java | 6 +- .../src/mage/cards/b/BagOfDevouring.java | 2 +- .../mage/cards/b/BalduvianTradingPost.java | 2 +- .../src/mage/cards/b/BankruptInBlood.java | 3 +- Mage.Sets/src/mage/cards/b/BanquetGuests.java | 2 +- Mage.Sets/src/mage/cards/b/BarrageOgre.java | 2 +- Mage.Sets/src/mage/cards/b/BarrageTyrant.java | 2 +- Mage.Sets/src/mage/cards/b/BayouGroff.java | 4 +- .../src/mage/cards/b/BehemothsHerald.java | 4 +- .../src/mage/cards/b/BellowingMauler.java | 5 +- .../src/mage/cards/b/BetrayalOfFlesh.java | 2 +- .../src/mage/cards/b/BetrothedOfFire.java | 2 +- Mage.Sets/src/mage/cards/b/BillThePony.java | 4 +- .../src/mage/cards/b/BiolumeSerpent.java | 3 +- Mage.Sets/src/mage/cards/b/BirthingPod.java | 4 +- .../cards/b/BjornaNightfallAlchemist.java | 2 +- .../src/mage/cards/b/BlazingHellhound.java | 2 +- .../src/mage/cards/b/BlightedShaman.java | 2 +- Mage.Sets/src/mage/cards/b/BloodAspirant.java | 4 +- Mage.Sets/src/mage/cards/b/BloodBairn.java | 2 +- .../src/mage/cards/b/BloodChinFanatic.java | 2 +- Mage.Sets/src/mage/cards/b/BloodHost.java | 2 +- .../mage/cards/b/BloodmistInfiltrator.java | 2 +- .../src/mage/cards/b/BloodsoakedAltar.java | 4 +- Mage.Sets/src/mage/cards/b/BogDown.java | 3 +- Mage.Sets/src/mage/cards/b/BogElemental.java | 2 +- Mage.Sets/src/mage/cards/b/BogGlider.java | 4 +- Mage.Sets/src/mage/cards/b/BogNaughty.java | 2 +- .../src/mage/cards/b/BogardanDragonheart.java | 2 +- Mage.Sets/src/mage/cards/b/BolassCitadel.java | 4 +- Mage.Sets/src/mage/cards/b/BoneShards.java | 3 +- .../src/mage/cards/b/BontuTheGlorified.java | 2 +- Mage.Sets/src/mage/cards/b/BoshIronGolem.java | 3 +- .../src/mage/cards/b/BoundByMoonsilver.java | 2 +- .../mage/cards/b/BraidsArisenNightmare.java | 9 +- Mage.Sets/src/mage/cards/b/BrawlBashOgre.java | 4 +- .../src/mage/cards/b/BreyaEtheriumShaper.java | 3 +- .../src/mage/cards/b/BreyasApprentice.java | 4 +- Mage.Sets/src/mage/cards/b/BrionStoutarm.java | 2 +- .../mage/cards/b/BroadsideBombardiers.java | 3 +- .../src/mage/cards/b/BrutalSuppression.java | 4 +- .../src/mage/cards/b/BubblingCauldron.java | 2 +- .../mage/cards/b/BucknardsEverfullPurse.java | 28 +---- .../src/mage/cards/b/BurningOfXinye.java | 5 +- .../src/mage/cards/b/BushmeatPoacher.java | 4 +- .../src/mage/cards/b/ButcherOfTheHorde.java | 3 +- Mage.Sets/src/mage/cards/c/CabalArchon.java | 2 +- .../src/mage/cards/c/CabalTherapist.java | 3 +- Mage.Sets/src/mage/cards/c/CabalTherapy.java | 4 +- Mage.Sets/src/mage/cards/c/CaribouRange.java | 2 +- .../src/mage/cards/c/CartelAristocrat.java | 2 +- .../src/mage/cards/c/CauldronFamiliar.java | 2 +- .../src/mage/cards/c/CavalierOfNight.java | 2 +- Mage.Sets/src/mage/cards/c/CephalidScout.java | 2 +- .../src/mage/cards/c/ChainOfSilence.java | 5 +- Mage.Sets/src/mage/cards/c/ChainOfVapor.java | 3 +- Mage.Sets/src/mage/cards/c/ChainedBrute.java | 4 +- .../src/mage/cards/c/Chitterspitter.java | 2 +- .../src/mage/cards/c/ChoiceOfDamnations.java | 6 +- Mage.Sets/src/mage/cards/c/Clickslither.java | 2 +- .../src/mage/cards/c/CoastalHornclaw.java | 2 +- Mage.Sets/src/mage/cards/c/CoffinPuppets.java | 4 +- .../src/mage/cards/c/CombineChrysalis.java | 2 +- .../src/mage/cards/c/ConsecratedByBlood.java | 2 +- Mage.Sets/src/mage/cards/c/ConstantMists.java | 5 +- .../src/mage/cards/c/ConsumingVapors.java | 7 +- Mage.Sets/src/mage/cards/c/CoralReef.java | 2 +- .../src/mage/cards/c/CorpseBlockade.java | 2 +- Mage.Sets/src/mage/cards/c/CorpseCobble.java | 3 +- Mage.Sets/src/mage/cards/c/CosmicLarva.java | 4 +- Mage.Sets/src/mage/cards/c/Crash.java | 2 +- Mage.Sets/src/mage/cards/c/CropRotation.java | 2 +- Mage.Sets/src/mage/cards/c/CruelReality.java | 4 +- Mage.Sets/src/mage/cards/c/CryptLurker.java | 4 +- .../src/mage/cards/c/CurseOfTheCabal.java | 5 +- Mage.Sets/src/mage/cards/c/CustodyBattle.java | 2 +- Mage.Sets/src/mage/cards/d/DampingEngine.java | 4 +- Mage.Sets/src/mage/cards/d/DanseMacabre.java | 4 +- .../cards/d/DarettiIngeniousIconoclast.java | 4 +- .../src/mage/cards/d/DarkDwellerOracle.java | 4 +- .../src/mage/cards/d/DarkHeartOfTheWood.java | 2 +- .../src/mage/cards/d/DarkIntimations.java | 6 +- .../src/mage/cards/d/DarkSupplicant.java | 2 +- .../cards/d/DarthTyranusCountOfSerenno.java | 6 +- Mage.Sets/src/mage/cards/d/Deadapult.java | 2 +- Mage.Sets/src/mage/cards/d/DeathBomb.java | 2 +- .../src/mage/cards/d/DeathlessBehemoth.java | 3 +- .../src/mage/cards/d/DeathmarkPrelate.java | 2 +- .../src/mage/cards/d/DeathsporeThallid.java | 2 +- .../src/mage/cards/d/DefilerOfSouls.java | 79 ++---------- Mage.Sets/src/mage/cards/d/Delraich.java | 4 +- .../src/mage/cards/d/DemandingDragon.java | 4 +- .../src/mage/cards/d/DemonOfDeathsGate.java | 2 +- .../src/mage/cards/d/DemonlordOfAshmouth.java | 2 +- Mage.Sets/src/mage/cards/d/DemonsHerald.java | 4 +- .../src/mage/cards/d/DerangedOutcast.java | 2 +- .../src/mage/cards/d/DescendantsFury.java | 5 +- Mage.Sets/src/mage/cards/d/Desolation.java | 9 +- .../src/mage/cards/d/DestructiveDigger.java | 2 +- Mage.Sets/src/mage/cards/d/DevourFlesh.java | 15 ++- .../src/mage/cards/d/DevouringGreed.java | 3 +- Mage.Sets/src/mage/cards/d/DevouringRage.java | 3 +- .../src/mage/cards/d/DiamondKaleidoscope.java | 2 +- .../src/mage/cards/d/DinaSoulSteeper.java | 4 +- .../src/mage/cards/d/DireFleetWarmonger.java | 2 +- Mage.Sets/src/mage/cards/d/DispersingOrb.java | 2 +- Mage.Sets/src/mage/cards/d/DoomCannon.java | 2 +- Mage.Sets/src/mage/cards/d/DoomForetold.java | 12 +- Mage.Sets/src/mage/cards/d/Doomgape.java | 5 +- .../src/mage/cards/d/DownhillCharge.java | 2 +- Mage.Sets/src/mage/cards/d/DragonsHerald.java | 4 +- Mage.Sets/src/mage/cards/d/DreadReturn.java | 2 +- .../src/mage/cards/d/DreadfeastDemon.java | 4 +- Mage.Sets/src/mage/cards/d/Dreadmalkin.java | 2 +- .../src/mage/cards/d/DreamscapeArtist.java | 2 +- .../src/mage/cards/d/DreamshaperShaman.java | 4 +- Mage.Sets/src/mage/cards/d/Dreamwinder.java | 2 +- .../src/mage/cards/d/DroolingGroodion.java | 2 +- Mage.Sets/src/mage/cards/d/Drought.java | 4 +- Mage.Sets/src/mage/cards/d/DrownerOfHope.java | 7 +- .../src/mage/cards/d/DuskRoseReliquary.java | 2 +- Mage.Sets/src/mage/cards/d/DustBowl.java | 3 +- .../src/mage/cards/d/DutifulGriffin.java | 3 +- Mage.Sets/src/mage/cards/d/DwarvenArmory.java | 2 +- .../src/mage/cards/d/DwarvenLandslide.java | 3 +- .../src/mage/cards/d/DwarvenWeaponsmith.java | 3 +- Mage.Sets/src/mage/cards/e/Earthblighter.java | 2 +- Mage.Sets/src/mage/cards/e/EatenAlive.java | 3 +- Mage.Sets/src/mage/cards/e/EaterOfHope.java | 4 +- .../src/mage/cards/e/EcstaticAwakener.java | 2 +- Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java | 2 +- Mage.Sets/src/mage/cards/e/ElderSpawn.java | 3 +- .../src/mage/cards/e/EldraziMonument.java | 5 +- .../src/mage/cards/e/EldritchEvolution.java | 2 +- Mage.Sets/src/mage/cards/e/EleshNorn.java | 2 +- Mage.Sets/src/mage/cards/e/ElvenPalisade.java | 2 +- Mage.Sets/src/mage/cards/e/ElvishFarmer.java | 2 +- .../src/mage/cards/e/ElvishReclaimer.java | 4 +- .../src/mage/cards/e/EmbraalGearSmasher.java | 3 +- .../src/mage/cards/e/EmptyTheLaboratory.java | 4 +- .../src/mage/cards/e/EmrakulsEvangel.java | 11 +- .../src/mage/cards/e/EntrapmentManeuver.java | 19 ++- .../src/mage/cards/e/EradicatorValkyrie.java | 2 +- .../src/mage/cards/e/ErebosBleakHearted.java | 4 +- .../src/mage/cards/e/ErtaiTheCorrupted.java | 2 +- .../src/mage/cards/e/EtchingsOfTheChosen.java | 2 +- .../src/mage/cards/e/EtheriumAstrolabe.java | 2 +- .../src/mage/cards/e/EverythingamajigE.java | 4 +- Mage.Sets/src/mage/cards/e/EvolvingDoor.java | 2 +- Mage.Sets/src/mage/cards/e/ExaltedDragon.java | 3 +- .../src/mage/cards/e/ExcavatingAnurid.java | 4 +- Mage.Sets/src/mage/cards/e/Excavation.java | 3 +- Mage.Sets/src/mage/cards/e/Excavator.java | 2 +- .../src/mage/cards/e/ExtricatorOfSin.java | 2 +- Mage.Sets/src/mage/cards/e/Extruder.java | 2 +- Mage.Sets/src/mage/cards/f/Facevaulter.java | 2 +- Mage.Sets/src/mage/cards/f/FadeAway.java | 6 +- Mage.Sets/src/mage/cards/f/FainTheBroker.java | 8 +- Mage.Sets/src/mage/cards/f/FaithHealer.java | 3 +- .../src/mage/cards/f/FalkenrathForebear.java | 3 +- .../mage/cards/f/FalkenrathPitFighter.java | 2 +- Mage.Sets/src/mage/cards/f/FallingTimber.java | 4 +- Mage.Sets/src/mage/cards/f/FatalGrudge.java | 5 +- Mage.Sets/src/mage/cards/f/FaultRiders.java | 3 +- Mage.Sets/src/mage/cards/f/FeastOfWorms.java | 11 +- .../src/mage/cards/f/FeastingTrollKing.java | 2 +- Mage.Sets/src/mage/cards/f/FellShepherd.java | 2 +- Mage.Sets/src/mage/cards/f/Ferrovore.java | 2 +- Mage.Sets/src/mage/cards/f/FiendArtisan.java | 4 +- .../src/mage/cards/f/FiendOfTheShadows.java | 2 +- Mage.Sets/src/mage/cards/f/FinalFlare.java | 2 +- Mage.Sets/src/mage/cards/f/FinalPayment.java | 2 +- .../src/mage/cards/f/FirebladeArtist.java | 3 +- Mage.Sets/src/mage/cards/f/Fireblast.java | 2 +- Mage.Sets/src/mage/cards/f/Flamewright.java | 2 +- Mage.Sets/src/mage/cards/f/FleshCarver.java | 2 +- Mage.Sets/src/mage/cards/f/Fleshtaker.java | 4 +- .../src/mage/cards/f/FloodedWoodlands.java | 3 +- Mage.Sets/src/mage/cards/f/FodderLaunch.java | 5 +- Mage.Sets/src/mage/cards/f/Foratog.java | 2 +- Mage.Sets/src/mage/cards/f/ForgeArmor.java | 2 +- Mage.Sets/src/mage/cards/f/Fortitude.java | 2 +- Mage.Sets/src/mage/cards/f/FoundryHelix.java | 2 +- .../src/mage/cards/f/FrayingOmnipotence.java | 3 +- .../src/mage/cards/f/FreyaliseSupplicant.java | 2 +- Mage.Sets/src/mage/cards/f/FungalPlots.java | 2 +- .../src/mage/cards/f/FungusElemental.java | 2 +- Mage.Sets/src/mage/cards/g/GaeasBalance.java | 8 +- .../src/mage/cards/g/GargantuanGorilla.java | 3 +- .../src/mage/cards/g/GarrukTheVeilCursed.java | 4 +- .../src/mage/cards/g/GathererOfGraces.java | 2 +- .../mage/cards/g/GeneralKudroOfDrannith.java | 2 +- .../src/mage/cards/g/GhenArcanumWeaver.java | 2 +- .../src/mage/cards/g/GhoulcallerGisa.java | 2 +- .../src/mage/cards/g/GiantOpportunity.java | 3 +- Mage.Sets/src/mage/cards/g/GiftOfDoom.java | 4 +- .../src/mage/cards/g/GildedAssaultCart.java | 3 +- Mage.Sets/src/mage/cards/g/GildedGoose.java | 2 +- .../src/mage/cards/g/GlacialCrevasses.java | 2 +- .../src/mage/cards/g/GlassCastHeart.java | 3 +- Mage.Sets/src/mage/cards/g/GlimmerBairn.java | 2 +- .../src/mage/cards/g/GluttonousTroll.java | 2 +- Mage.Sets/src/mage/cards/g/Gnathosaur.java | 2 +- Mage.Sets/src/mage/cards/g/GobblingOoze.java | 2 +- .../src/mage/cards/g/GoblinAssassin.java | 7 +- Mage.Sets/src/mage/cards/g/GoblinBarrage.java | 4 +- .../src/mage/cards/g/GoblinBombardment.java | 2 +- .../src/mage/cards/g/GoblinChirurgeon.java | 5 +- .../src/mage/cards/g/GoblinClearcutter.java | 2 +- .../src/mage/cards/g/GoblinEngineer.java | 2 +- Mage.Sets/src/mage/cards/g/GoblinGrenade.java | 2 +- Mage.Sets/src/mage/cards/g/GoblinLookout.java | 2 +- .../src/mage/cards/g/GoblinRazerunners.java | 2 +- Mage.Sets/src/mage/cards/g/GoblinSledder.java | 2 +- .../src/mage/cards/g/GoblinSoothsayer.java | 2 +- .../src/mage/cards/g/GoblinTrashmaster.java | 4 +- .../src/mage/cards/g/GoblinTrenches.java | 2 +- .../src/mage/cards/g/GoblinTurncoat.java | 4 +- Mage.Sets/src/mage/cards/g/GoblinWarrens.java | 2 +- Mage.Sets/src/mage/cards/g/Goremand.java | 4 +- Mage.Sets/src/mage/cards/g/GrabTheReins.java | 8 +- .../src/mage/cards/g/GraftedIdentity.java | 4 +- Mage.Sets/src/mage/cards/g/GraveExchange.java | 49 +------- Mage.Sets/src/mage/cards/g/GravePact.java | 7 +- .../mage/cards/g/GreatHallOfStarnheim.java | 3 +- .../src/mage/cards/g/GreaterGargadon.java | 2 +- .../mage/cards/g/GretaSweettoothScourge.java | 4 +- .../src/mage/cards/g/GrimgrinCorpseBorn.java | 2 +- .../src/mage/cards/g/GrindingStation.java | 2 +- .../src/mage/cards/g/GristTheHungerTide.java | 4 +- .../src/mage/cards/g/GruulGuildmage.java | 2 +- .../mage/cards/g/GuardianOfCloverdell.java | 2 +- .../src/mage/cards/g/GyomeMasterChef.java | 2 +- .../src/mage/cards/h/HammerOfPurphoros.java | 2 +- Mage.Sets/src/mage/cards/h/HandOfEmrakul.java | 2 +- Mage.Sets/src/mage/cards/h/Harrow.java | 2 +- .../src/mage/cards/h/HarvesterTroll.java | 2 +- Mage.Sets/src/mage/cards/h/HashepOasis.java | 2 +- Mage.Sets/src/mage/cards/h/HeWhoHungers.java | 4 +- .../src/mage/cards/h/HeartOfYavimaya.java | 2 +- Mage.Sets/src/mage/cards/h/Heartfire.java | 2 +- .../src/mage/cards/h/HearthcageGiant.java | 2 +- .../src/mage/cards/h/HeartwoodGiant.java | 2 +- Mage.Sets/src/mage/cards/h/Hecatomb.java | 2 +- .../src/mage/cards/h/HedronDetonator.java | 3 +- .../src/mage/cards/h/HeraldOfAnguish.java | 2 +- Mage.Sets/src/mage/cards/h/Heroism.java | 2 +- .../mage/cards/h/HidetsuguDevouringChaos.java | 4 +- Mage.Sets/src/mage/cards/h/HitRun.java | 8 +- Mage.Sets/src/mage/cards/h/HithlainRope.java | 56 +++++++++ Mage.Sets/src/mage/cards/h/Hobblefiend.java | 4 +- .../src/mage/cards/h/HomaridSpawningBed.java | 2 +- .../src/mage/cards/h/HorrorOfHorrors.java | 2 +- .../cards/i/IbHalfheartGoblinTactician.java | 2 +- .../src/mage/cards/i/IchorExplosion.java | 2 +- .../src/mage/cards/i/IfnirDeadlands.java | 4 +- .../src/mage/cards/i/IizukaTheRuthless.java | 2 +- .../src/mage/cards/i/ImmersturmPredator.java | 2 +- .../src/mage/cards/i/IncendiarySabotage.java | 3 +- Mage.Sets/src/mage/cards/i/Incriminate.java | 9 +- .../src/mage/cards/i/InfernalTribute.java | 2 +- .../src/mage/cards/i/IngenuityEngine.java | 2 +- .../src/mage/cards/i/InsatiableAppetite.java | 2 +- Mage.Sets/src/mage/cards/i/IpnuRivulet.java | 2 +- .../mage/cards/i/IroncladRevolutionary.java | 3 +- .../src/mage/cards/i/IzoniThousandEyed.java | 4 +- .../cards/j/JaliraMasterPolymorphist.java | 2 +- .../mage/cards/j/JaradGolgariLichLord.java | 6 +- Mage.Sets/src/mage/cards/j/JeweledSpirit.java | 3 +- Mage.Sets/src/mage/cards/j/Jokulmorder.java | 3 +- .../mage/cards/j/JoleneThePlunderQueen.java | 2 +- .../mage/cards/j/JonIrenicusShatteredOne.java | 110 ++++++++++++++++ Mage.Sets/src/mage/cards/j/JunglePatrol.java | 2 +- .../mage/cards/k/KalitasTraitorOfGhet.java | 2 +- .../mage/cards/k/KardursViciousReturn.java | 2 +- .../src/mage/cards/k/KeldonArsonist.java | 3 +- .../src/mage/cards/k/KeldonFirebombers.java | 10 +- .../src/mage/cards/k/KelsFightFixer.java | 2 +- .../mage/cards/k/KeskitTheFleshSculptor.java | 2 +- .../mage/cards/k/KethekCrucibleGoliath.java | 5 +- .../src/mage/cards/k/KheruBloodsucker.java | 2 +- Mage.Sets/src/mage/cards/k/KheruDreadmaw.java | 2 +- .../src/mage/cards/k/KjeldoranOutpost.java | 2 +- .../src/mage/cards/k/KnightCaptainOfEos.java | 2 +- .../mage/cards/k/KnightOfTheLastBreath.java | 2 +- .../src/mage/cards/k/KomaCosmosSerpent.java | 2 +- .../src/mage/cards/k/KorozdaGuildmage.java | 2 +- .../src/mage/cards/k/KrarkClanEngineers.java | 3 +- .../src/mage/cards/k/KrarkClanGrunt.java | 2 +- .../src/mage/cards/k/KrarkClanIronworks.java | 2 +- Mage.Sets/src/mage/cards/k/KrarkClanOgre.java | 3 +- .../src/mage/cards/k/KrarkClanShaman.java | 2 +- .../src/mage/cards/k/KrarkClanStoker.java | 3 +- .../src/mage/cards/k/KukemssaSerpent.java | 2 +- .../src/mage/cards/k/KuldothaFlamefiend.java | 2 +- .../src/mage/cards/k/KuldothaForgemaster.java | 2 +- .../src/mage/cards/k/KuldothaRebirth.java | 2 +- .../src/mage/cards/k/KykarWindsFury.java | 2 +- Mage.Sets/src/mage/cards/k/KyscuDrake.java | 2 +- Mage.Sets/src/mage/cards/l/LakeOfTheDead.java | 4 +- .../src/mage/cards/l/LampadOfDeathsVigil.java | 4 +- .../src/mage/cards/l/LastDitchEffort.java | 17 ++- Mage.Sets/src/mage/cards/l/LavaDart.java | 2 +- .../src/mage/cards/l/LegionVanguard.java | 4 +- Mage.Sets/src/mage/cards/l/Leviathan.java | 4 +- Mage.Sets/src/mage/cards/l/Lich.java | 3 +- .../src/mage/cards/l/LichKnightsConquest.java | 5 +- Mage.Sets/src/mage/cards/l/LiegeOfThePit.java | 3 +- Mage.Sets/src/mage/cards/l/Lifespinner.java | 4 +- Mage.Sets/src/mage/cards/l/Lithatog.java | 5 +- Mage.Sets/src/mage/cards/l/Lithophage.java | 2 +- .../src/mage/cards/l/LochmereSerpent.java | 4 +- .../src/mage/cards/l/LordOfTheForsaken.java | 4 +- Mage.Sets/src/mage/cards/l/LordOfThePit.java | 3 +- Mage.Sets/src/mage/cards/l/LotusVale.java | 2 +- Mage.Sets/src/mage/cards/l/LunarchMantle.java | 3 +- .../src/mage/cards/m/MagdaBrazenOutlaw.java | 2 +- Mage.Sets/src/mage/cards/m/MagmaBurst.java | 6 +- Mage.Sets/src/mage/cards/m/MagmaRift.java | 2 +- Mage.Sets/src/mage/cards/m/MagmaVein.java | 2 +- Mage.Sets/src/mage/cards/m/Magmaw.java | 2 +- .../src/mage/cards/m/MagusOfTheOrder.java | 2 +- Mage.Sets/src/mage/cards/m/MakeAnExample.java | 5 +- .../src/mage/cards/m/MalevolentNoble.java | 2 +- .../src/mage/cards/m/MalevolentWitchkite.java | 7 +- Mage.Sets/src/mage/cards/m/ManaSeism.java | 10 +- Mage.Sets/src/mage/cards/m/ManaVortex.java | 4 +- Mage.Sets/src/mage/cards/m/MaraleafRider.java | 2 +- Mage.Sets/src/mage/cards/m/MarrowGnawer.java | 2 +- Mage.Sets/src/mage/cards/m/MarshFlitter.java | 2 +- Mage.Sets/src/mage/cards/m/MarshLurker.java | 2 +- Mage.Sets/src/mage/cards/m/MartyrsBond.java | 5 +- .../src/mage/cards/m/MawOfTheObzedat.java | 2 +- Mage.Sets/src/mage/cards/m/Megatog.java | 2 +- .../src/mage/cards/m/MercilessResolve.java | 2 +- .../src/mage/cards/m/MetalworkColossus.java | 5 +- .../src/mage/cards/m/MindExtraction.java | 6 +- Mage.Sets/src/mage/cards/m/MineCollapse.java | 2 +- Mage.Sets/src/mage/cards/m/MireShade.java | 2 +- Mage.Sets/src/mage/cards/m/MoggAlarm.java | 2 +- Mage.Sets/src/mage/cards/m/MoggRaider.java | 2 +- .../src/mage/cards/m/MogisGodOfSlaughter.java | 6 +- Mage.Sets/src/mage/cards/m/MoldDemon.java | 2 +- .../src/mage/cards/m/MondrakGloryDominus.java | 3 +- .../src/mage/cards/m/MorkrutBehemoth.java | 4 +- .../src/mage/cards/m/MukotaiSoulripper.java | 2 +- Mage.Sets/src/mage/cards/m/Mycologist.java | 2 +- .../src/mage/cards/n/NahirisSacrifice.java | 3 +- Mage.Sets/src/mage/cards/n/NaturalOrder.java | 2 +- Mage.Sets/src/mage/cards/n/NeedForSpeed.java | 3 +- .../src/mage/cards/n/NemataGroveGuardian.java | 2 +- .../mage/cards/n/NemataPrimevalWarden.java | 4 +- Mage.Sets/src/mage/cards/n/Neoform.java | 4 +- Mage.Sets/src/mage/cards/n/NimDevourer.java | 44 +------ .../src/mage/cards/n/NoviceDissector.java | 4 +- Mage.Sets/src/mage/cards/n/NuteGunray.java | 2 +- .../mage/cards/o/ObNixilisTheAdversary.java | 12 +- Mage.Sets/src/mage/cards/o/OozeGarden.java | 4 +- Mage.Sets/src/mage/cards/o/OrcGeneral.java | 2 +- .../src/mage/cards/o/OrcishLumberjack.java | 2 +- .../src/mage/cards/o/OrcishMechanics.java | 3 +- Mage.Sets/src/mage/cards/o/OrcishVandal.java | 2 +- .../mage/cards/o/OrmendahlTheCorrupter.java | 4 +- .../mage/cards/o/OsgirTheReconstructor.java | 2 +- .../src/mage/cards/o/OswaldFiddlebender.java | 4 +- .../src/mage/cards/o/OvergrownEstate.java | 2 +- .../src/mage/cards/o/OxiddaDaredevil.java | 2 +- .../src/mage/cards/p/PallidMycoderm.java | 2 +- Mage.Sets/src/mage/cards/p/PashalikMons.java | 2 +- .../src/mage/cards/p/PegasusStampede.java | 2 +- Mage.Sets/src/mage/cards/p/Pentavus.java | 2 +- Mage.Sets/src/mage/cards/p/PeregrinTook.java | 4 +- .../src/mage/cards/p/PerilousPredicament.java | 11 +- Mage.Sets/src/mage/cards/p/Phantatog.java | 3 +- .../src/mage/cards/p/PhyrexianAltar.java | 2 +- .../src/mage/cards/p/PhyrexianTribute.java | 3 +- Mage.Sets/src/mage/cards/p/PhyrexiasCore.java | 2 +- .../src/mage/cards/p/PiaAndKiranNalaar.java | 3 +- Mage.Sets/src/mage/cards/p/PiaNalaar.java | 2 +- .../src/mage/cards/p/PillarTombsOfAku.java | 3 +- Mage.Sets/src/mage/cards/p/PiousEvangel.java | 2 +- .../src/mage/cards/p/PiperOfTheSwarm.java | 2 +- .../mage/cards/p/PippinWardenOfIsengard.java | 2 +- Mage.Sets/src/mage/cards/p/PistonSledge.java | 2 +- .../src/mage/cards/p/PitilessPontiff.java | 4 +- Mage.Sets/src/mage/cards/p/Plaguecrafter.java | 9 +- .../src/mage/cards/p/PlantElemental.java | 2 +- .../src/mage/cards/p/PlumbTheForbidden.java | 4 +- .../src/mage/cards/p/PlungeIntoDarkness.java | 6 +- Mage.Sets/src/mage/cards/p/PolarKraken.java | 2 +- Mage.Sets/src/mage/cards/p/PollenRemedy.java | 4 +- .../src/mage/cards/p/PortcullisVine.java | 4 +- .../src/mage/cards/p/PossessedPortal.java | 3 +- Mage.Sets/src/mage/cards/p/Pox.java | 5 +- .../src/mage/cards/p/PrestonTheVanisher.java | 2 +- .../mage/cards/p/PriestOfForgottenGods.java | 4 +- .../src/mage/cards/p/PriestOfYawgmoth.java | 2 +- .../mage/cards/p/PrimeSpeakerVannifar.java | 4 +- Mage.Sets/src/mage/cards/p/PrimevalForce.java | 2 +- .../mage/cards/p/ProsshSkyraiderOfKher.java | 2 +- .../src/mage/cards/p/ProwlingPangolin.java | 3 +- .../src/mage/cards/p/PsychicAllergy.java | 2 +- .../src/mage/cards/p/PsychotropeThallid.java | 2 +- Mage.Sets/src/mage/cards/p/Pulverize.java | 2 +- Mage.Sets/src/mage/cards/p/PyreOfHeroes.java | 4 +- .../src/mage/cards/q/QarsiHighPriest.java | 2 +- Mage.Sets/src/mage/cards/r/Ragamuffyn.java | 2 +- Mage.Sets/src/mage/cards/r/RaidingParty.java | 2 +- Mage.Sets/src/mage/cards/r/RamunapRuins.java | 2 +- Mage.Sets/src/mage/cards/r/RathiDragon.java | 2 +- Mage.Sets/src/mage/cards/r/RathsEdge.java | 2 +- .../src/mage/cards/r/RavenousBaloth.java | 2 +- Mage.Sets/src/mage/cards/r/RavenousDemon.java | 4 +- Mage.Sets/src/mage/cards/r/RavenousHarpy.java | 4 +- .../src/mage/cards/r/RavenousIntruder.java | 2 +- .../src/mage/cards/r/RavenousVampire.java | 2 +- Mage.Sets/src/mage/cards/r/RavenousWampa.java | 22 ++-- .../mage/cards/r/RazakethTheFoulblooded.java | 3 +- Mage.Sets/src/mage/cards/r/Raze.java | 2 +- Mage.Sets/src/mage/cards/r/ReadTheRunes.java | 6 +- .../src/mage/cards/r/ReapingTheRewards.java | 3 +- Mage.Sets/src/mage/cards/r/Reclamation.java | 3 +- .../src/mage/cards/r/RecurringNightmare.java | 2 +- .../src/mage/cards/r/RedcapGutterDweller.java | 2 +- Mage.Sets/src/mage/cards/r/ReignOfThePit.java | 4 +- Mage.Sets/src/mage/cards/r/RelicVial.java | 4 +- Mage.Sets/src/mage/cards/r/Renewal.java | 2 +- Mage.Sets/src/mage/cards/r/Renounce.java | 12 +- Mage.Sets/src/mage/cards/r/Reprocess.java | 5 +- .../mage/cards/r/RescueFromTheUnderworld.java | 2 +- Mage.Sets/src/mage/cards/r/Reshape.java | 3 +- .../src/mage/cards/r/RestlessBloodseeker.java | 3 +- .../src/mage/cards/r/RetrofitterFoundry.java | 4 +- Mage.Sets/src/mage/cards/r/RhysTheExiled.java | 2 +- .../src/mage/cards/r/RiteOfConsumption.java | 2 +- .../src/mage/cards/r/RiteOfOblivion.java | 2 +- Mage.Sets/src/mage/cards/r/RogueElephant.java | 2 +- .../src/mage/cards/r/RootwaterAlligator.java | 2 +- Mage.Sets/src/mage/cards/r/Rupture.java | 6 +- Mage.Sets/src/mage/cards/r/RushingRiver.java | 5 +- Mage.Sets/src/mage/cards/r/RustElemental.java | 3 +- Mage.Sets/src/mage/cards/r/RustMonster.java | 2 +- Mage.Sets/src/mage/cards/r/RustedSlasher.java | 2 +- Mage.Sets/src/mage/cards/r/RuthlessKnave.java | 2 +- Mage.Sets/src/mage/cards/s/SacredMesa.java | 2 +- Mage.Sets/src/mage/cards/s/SageOfLatNam.java | 2 +- .../src/mage/cards/s/SaiMasterThopterist.java | 4 +- Mage.Sets/src/mage/cards/s/SalvageSquad.java | 3 +- Mage.Sets/src/mage/cards/s/SalvageTitan.java | 2 +- Mage.Sets/src/mage/cards/s/SamwiseGamgee.java | 2 +- .../src/mage/cards/s/SandstoneDeadfall.java | 3 +- Mage.Sets/src/mage/cards/s/Sarcatog.java | 3 +- Mage.Sets/src/mage/cards/s/SarlaccPit.java | 3 +- Mage.Sets/src/mage/cards/s/SavageThallid.java | 2 +- .../mage/cards/s/SavraQueenOfTheGolgari.java | 7 +- Mage.Sets/src/mage/cards/s/SavvyHunter.java | 3 +- Mage.Sets/src/mage/cards/s/Scapeshift.java | 6 +- Mage.Sets/src/mage/cards/s/Scarecrone.java | 2 +- .../src/mage/cards/s/ScavengerGrounds.java | 2 +- .../src/mage/cards/s/ScionOfOpulence.java | 2 +- Mage.Sets/src/mage/cards/s/ScorchedRuins.java | 2 +- .../src/mage/cards/s/ScourgeOfNelToth.java | 3 +- .../src/mage/cards/s/ScourgeOfSkolaVale.java | 2 +- .../src/mage/cards/s/ScrapyardRecombiner.java | 2 +- .../mage/cards/s/ScrapyardSteelbreaker.java | 2 +- Mage.Sets/src/mage/cards/s/ScytheTiger.java | 2 +- Mage.Sets/src/mage/cards/s/SeasideHaven.java | 2 +- .../src/mage/cards/s/SeethingPathblazer.java | 2 +- .../src/mage/cards/s/SekkiSeasonsGuide.java | 3 +- .../src/mage/cards/s/SelfInflictedWound.java | 20 +-- .../src/mage/cards/s/SepulcherGhoul.java | 2 +- Mage.Sets/src/mage/cards/s/SerendibDjinn.java | 3 +- .../src/mage/cards/s/SeveredStrands.java | 2 +- .../src/mage/cards/s/ShadowbornApostle.java | 2 +- Mage.Sets/src/mage/cards/s/ShardVolley.java | 2 +- .../src/mage/cards/s/ShattergangBrothers.java | 4 +- Mage.Sets/src/mage/cards/s/ShefetDunes.java | 2 +- Mage.Sets/src/mage/cards/s/ShivanWumpus.java | 3 +- Mage.Sets/src/mage/cards/s/ShrapnelBlast.java | 2 +- .../src/mage/cards/s/SiegeGangCommander.java | 2 +- .../mage/cards/s/SilvarDevourerOfTheFree.java | 2 +- .../src/mage/cards/s/SkeletalVampire.java | 5 +- .../src/mage/cards/s/SkirkProspector.java | 2 +- .../src/mage/cards/s/SkirkVolcanist.java | 3 +- .../src/mage/cards/s/SkirsdagFlayer.java | 2 +- Mage.Sets/src/mage/cards/s/SkizzikSurger.java | 3 +- .../src/mage/cards/s/SkophosWarleader.java | 2 +- .../src/mage/cards/s/SkullportMerchant.java | 2 +- Mage.Sets/src/mage/cards/s/Skulltap.java | 2 +- .../src/mage/cards/s/SkyclaveShadowcat.java | 4 +- Mage.Sets/src/mage/cards/s/SlagStrider.java | 4 +- .../mage/cards/s/SlaughterPriestOfMogis.java | 2 +- .../src/mage/cards/s/SlingGangLieutenant.java | 2 +- .../mage/cards/s/SlobadGoblinTinkerer.java | 2 +- Mage.Sets/src/mage/cards/s/Smokestack.java | 6 +- .../src/mage/cards/s/SokenzanSmelter.java | 4 +- Mage.Sets/src/mage/cards/s/SolarTide.java | 3 +- Mage.Sets/src/mage/cards/s/SoldeviAdnate.java | 2 +- .../src/mage/cards/s/SoldeviExcavations.java | 2 +- Mage.Sets/src/mage/cards/s/SoldeviSage.java | 5 +- .../mage/cards/s/SorinImperiousBloodlord.java | 2 +- .../src/mage/cards/s/SoulreaperOfMogis.java | 4 +- .../src/mage/cards/s/SoulsOfTheLost.java | 2 +- Mage.Sets/src/mage/cards/s/SparkHarvest.java | 3 +- Mage.Sets/src/mage/cards/s/SparkReaper.java | 2 +- Mage.Sets/src/mage/cards/s/SphinxsHerald.java | 4 +- Mage.Sets/src/mage/cards/s/SpiritBonds.java | 2 +- .../src/mage/cards/s/SpittingSpider.java | 2 +- .../src/mage/cards/s/SquanderedResources.java | 2 +- .../src/mage/cards/s/SquirrelWrangler.java | 5 +- .../src/mage/cards/s/StarlitSanctum.java | 4 +- .../src/mage/cards/s/StormwatchEagle.java | 3 +- .../src/mage/cards/s/StrandsOfNight.java | 2 +- .../mage/cards/s/StrefanMaurerProgenitor.java | 10 +- .../src/mage/cards/s/StrongholdAssassin.java | 2 +- Mage.Sets/src/mage/cards/s/Sunstone.java | 2 +- Mage.Sets/src/mage/cards/s/Sustenance.java | 3 +- .../src/mage/cards/s/SwordOfTheAges.java | 4 +- .../src/mage/cards/s/SylvanSafekeeper.java | 3 +- .../src/mage/cards/s/SyndicateTrafficker.java | 2 +- Mage.Sets/src/mage/cards/s/SyphonFlesh.java | 9 +- .../src/mage/cards/t/TamiyosJournal.java | 2 +- Mage.Sets/src/mage/cards/t/TarPitcher.java | 2 +- .../src/mage/cards/t/TavernScoundrel.java | 2 +- .../mage/cards/t/TawnosSolemnSurvivor.java | 2 +- Mage.Sets/src/mage/cards/t/TeferisCare.java | 2 +- .../mage/cards/t/TelJiladLifebreather.java | 2 +- Mage.Sets/src/mage/cards/t/TemptingWitch.java | 2 +- Mage.Sets/src/mage/cards/t/TendThePests.java | 4 +- .../src/mage/cards/t/TergridGodOfFright.java | 4 +- .../src/mage/cards/t/TerritorialDispute.java | 5 +- .../src/mage/cards/t/TeysaOrzhovScion.java | 2 +- .../src/mage/cards/t/ThaliasGeistcaller.java | 2 +- .../src/mage/cards/t/ThallidDevourer.java | 2 +- .../src/mage/cards/t/ThallidGerminator.java | 2 +- .../src/mage/cards/t/ThallidOmnivore.java | 2 +- Mage.Sets/src/mage/cards/t/Thaumatog.java | 5 +- .../mage/cards/t/TheBookOfVileDarkness.java | 4 +- .../src/mage/cards/t/TheDalekEmperor.java | 4 +- .../src/mage/cards/t/TheFirstEruption.java | 5 +- .../src/mage/cards/t/TheGitrogMonster.java | 3 +- Mage.Sets/src/mage/cards/t/TheloniteMonk.java | 2 +- .../src/mage/cards/t/ThermalNavigator.java | 3 +- .../src/mage/cards/t/ThingFromTheDeep.java | 2 +- .../src/mage/cards/t/ThopterFoundry.java | 2 +- .../src/mage/cards/t/ThopterSquadron.java | 2 +- Mage.Sets/src/mage/cards/t/ThroneOfGeth.java | 2 +- Mage.Sets/src/mage/cards/t/Thunderclap.java | 2 +- Mage.Sets/src/mage/cards/t/TimeSieve.java | 2 +- Mage.Sets/src/mage/cards/t/Tinker.java | 3 +- Mage.Sets/src/mage/cards/t/TitanHunter.java | 4 +- Mage.Sets/src/mage/cards/t/TombBlade.java | 2 +- Mage.Sets/src/mage/cards/t/ToothAndClaw.java | 5 +- .../src/mage/cards/t/TormentedThoughts.java | 3 +- Mage.Sets/src/mage/cards/t/TorpidMoloch.java | 3 +- .../src/mage/cards/t/TorrentOfStone.java | 2 +- Mage.Sets/src/mage/cards/t/TourachsGate.java | 2 +- Mage.Sets/src/mage/cards/t/ToweringTitan.java | 4 +- .../src/mage/cards/t/ToxrillTheCorrosive.java | 2 +- Mage.Sets/src/mage/cards/t/TradingPost.java | 2 +- .../src/mage/cards/t/TransmuteArtifact.java | 6 +- Mage.Sets/src/mage/cards/t/TrapDigger.java | 2 +- .../src/mage/cards/t/TrashForTreasure.java | 2 +- Mage.Sets/src/mage/cards/t/TreasureCove.java | 2 +- .../src/mage/cards/t/TrenchingSteed.java | 3 +- .../src/mage/cards/t/TributeToHunger.java | 6 +- .../src/mage/cards/t/TroubledHealer.java | 3 +- .../src/mage/cards/t/TurntimberSower.java | 2 +- .../src/mage/cards/t/TwistedJustice.java | 7 +- .../mage/cards/t/TymaretTheMurderKing.java | 2 +- .../src/mage/cards/u/UktabiWildcats.java | 2 +- .../src/mage/cards/u/UndercityNecrolisk.java | 6 +- .../src/mage/cards/u/UndercityScavenger.java | 2 +- .../src/mage/cards/u/UnnaturalHunger.java | 2 +- Mage.Sets/src/mage/cards/u/UrborgPanther.java | 4 +- Mage.Sets/src/mage/cards/u/UtopiaMycon.java | 2 +- Mage.Sets/src/mage/cards/v/Valleymaker.java | 4 +- .../src/mage/cards/v/VampireAristocrat.java | 14 +-- .../src/mage/cards/v/VampireWarlord.java | 4 +- .../mage/cards/v/VarolzTheScarStriped.java | 2 +- Mage.Sets/src/mage/cards/v/VerminGorger.java | 2 +- Mage.Sets/src/mage/cards/v/VillageElder.java | 2 +- Mage.Sets/src/mage/cards/v/VillageRites.java | 4 +- .../src/mage/cards/v/VirtussManeuver.java | 3 +- Mage.Sets/src/mage/cards/v/VisceridDrone.java | 4 +- .../src/mage/cards/v/VitasporeThallid.java | 2 +- .../src/mage/cards/v/VivienOnTheHunt.java | 5 +- .../src/mage/cards/v/VoidmageProdigy.java | 2 +- .../src/mage/cards/v/VoldarenPariah.java | 2 +- Mage.Sets/src/mage/cards/v/VolrathsCurse.java | 4 +- Mage.Sets/src/mage/cards/v/VoltageSurge.java | 5 +- Mage.Sets/src/mage/cards/v/VonasHunger.java | 5 +- .../src/mage/cards/v/VoraciousFellBeast.java | 6 +- Mage.Sets/src/mage/cards/v/VoraciousNull.java | 2 +- .../src/mage/cards/v/VraskaGolgariQueen.java | 2 +- .../src/mage/cards/v/VulshokWarBoar.java | 2 +- Mage.Sets/src/mage/cards/w/WalkTheAeons.java | 2 +- Mage.Sets/src/mage/cards/w/WallOfMulch.java | 2 +- .../src/mage/cards/w/WandOfTheElements.java | 4 +- .../src/mage/cards/w/WanderwineProphets.java | 2 +- .../src/mage/cards/w/WasitoraNekoruQueen.java | 6 +- .../mage/cards/w/WeaponizeTheMonsters.java | 4 +- .../src/mage/cards/w/WeddingSecurity.java | 2 +- .../src/mage/cards/w/WeirdingShaman.java | 2 +- Mage.Sets/src/mage/cards/w/WestvaleAbbey.java | 3 +- .../mage/cards/w/WhisperBloodLiturgist.java | 2 +- Mage.Sets/src/mage/cards/w/Whiteout.java | 2 +- Mage.Sets/src/mage/cards/w/WickedWolf.java | 2 +- .../mage/cards/w/WilheltTheRotcleaver.java | 2 +- .../src/mage/cards/w/WitchsCauldron.java | 2 +- Mage.Sets/src/mage/cards/w/WitchsOven.java | 4 +- Mage.Sets/src/mage/cards/w/WoeStrider.java | 2 +- .../src/mage/cards/w/WoebringerDemon.java | 7 +- Mage.Sets/src/mage/cards/w/WorldBreaker.java | 2 +- Mage.Sets/src/mage/cards/w/WorldQueller.java | 6 +- .../src/mage/cards/w/WormsOfTheEarth.java | 3 +- Mage.Sets/src/mage/cards/x/XathridDemon.java | 3 +- .../mage/cards/y/YahenniUndyingPartisan.java | 2 +- .../mage/cards/y/YawgmothThranPhysician.java | 4 +- .../mage/cards/z/ZiatoraTheIncinerator.java | 5 +- .../mage/cards/z/ZopandrelHungerDominus.java | 3 +- Mage.Sets/src/mage/cards/z/ZuranOrb.java | 2 +- .../CommanderLegendsBattleForBaldursGate.java | 3 + .../sets/TalesOfMiddleEarthCommander.java | 1 + .../test/AI/basic/TargetRequiredTest.java | 2 +- .../enters/ValakutTheMoltenPinnacleTest.java | 6 +- .../cards/abilities/keywords/BestowTest.java | 2 +- .../cards/abilities/keywords/ExploitTest.java | 8 +- .../cards/abilities/keywords/KickerTest.java | 2 +- .../abilities/keywords/OfferingTest.java | 10 +- ...CastFromHandWithoutPayingManaCostTest.java | 28 ++--- .../cards/rules/CantBeSacrificedTest.java | 117 ++++++++++++++++++ .../cards/single/clb/MyrkulsEdictTest.java | 6 +- .../single/ltr/WitchKingOfAngmarTest.java | 4 +- .../cards/single/stx/DaemogothTitanTest.java | 2 +- .../damage/DealsCombatDamageTriggerTest.java | 6 +- .../triggers/dies/OmnathLocusOfRageTest.java | 2 +- .../triggers/dies/SilumgarScavengerTest.java | 2 +- .../commander/duel/CastCommanderTest.java | 2 +- .../costs/common/SacrificeAllCost.java | 5 +- .../costs/common/SacrificeAttachmentCost.java | 8 ++ .../costs/common/SacrificeTargetCost.java | 48 ++++--- .../costs/common/SacrificeXTargetCost.java | 18 ++- .../effects/common/DevourEffect.java | 5 +- ...ayerToRightGainsControlOfSourceEffect.java | 53 ++++++++ .../effects/common/SacrificeAllEffect.java | 96 +++++++++----- .../effects/common/SacrificeEffect.java | 52 ++++---- .../common/SacrificeOpponentsEffect.java | 87 +++---------- .../SacrificeOpponentsUnlessPayEffect.java | 51 ++++---- .../SacrificeSourceUnlessConditionEffect.java | 12 +- .../CantBeSacrificedSourceEffect.java | 45 +++++++ .../abilities/keyword/AnnihilatorAbility.java | 77 ++---------- .../abilities/keyword/CasualtyAbility.java | 6 +- .../mage/abilities/keyword/EmergeAbility.java | 16 ++- .../abilities/keyword/ExploitAbility.java | 15 ++- .../abilities/keyword/OfferingAbility.java | 6 +- .../permanent/CanBeSacrificedPredicate.java | 17 +++ .../dungeons/TombOfAnnihilationDungeon.java | 6 +- .../java/mage/game/permanent/Permanent.java | 4 + .../mage/game/permanent/PermanentImpl.java | 15 ++- .../main/java/mage/players/PlayerImpl.java | 3 +- .../mage/target/common/TargetSacrifice.java | 49 ++++++++ ... => TargetSacrificeCreatureEachColor.java} | 12 +- 699 files changed, 1837 insertions(+), 1619 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/h/HithlainRope.java create mode 100644 Mage.Sets/src/mage/cards/j/JonIrenicusShatteredOne.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeSacrificedTest.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/PlayerToRightGainsControlOfSourceEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java create mode 100644 Mage/src/main/java/mage/filter/predicate/permanent/CanBeSacrificedPredicate.java create mode 100644 Mage/src/main/java/mage/target/common/TargetSacrifice.java rename Mage/src/main/java/mage/target/common/{TargetControlledCreatureEachColor.java => TargetSacrificeCreatureEachColor.java} (83%) diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java index 608fb678e3d..e6573046e7b 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java @@ -192,9 +192,10 @@ public class ComputerPlayer extends PlayerImpl implements Player { return false; } - if (target.getOriginalTarget() instanceof TargetControlledPermanent) { + if (target.getOriginalTarget() instanceof TargetControlledPermanent + || target.getOriginalTarget() instanceof TargetSacrifice) { List targets; - TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget(); + TargetPermanent origTarget = (TargetPermanent) target.getOriginalTarget(); targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets()); if (!outcome.isGood()) { Collections.reverse(targets); @@ -689,8 +690,9 @@ public class ComputerPlayer extends PlayerImpl implements Player { return false; } - if (target.getOriginalTarget() instanceof TargetControlledPermanent) { - TargetControlledPermanent origTarget = (TargetControlledPermanent) target.getOriginalTarget(); + if (target.getOriginalTarget() instanceof TargetControlledPermanent + || target.getOriginalTarget() instanceof TargetSacrifice) { + TargetPermanent origTarget = (TargetPermanent) target.getOriginalTarget(); List targets; targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets()); if (!outcome.isGood()) { diff --git a/Mage.Sets/src/mage/cards/a/AJedisFervor.java b/Mage.Sets/src/mage/cards/a/AJedisFervor.java index df36687f1e2..022195987dc 100644 --- a/Mage.Sets/src/mage/cards/a/AJedisFervor.java +++ b/Mage.Sets/src/mage/cards/a/AJedisFervor.java @@ -14,6 +14,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.watchers.common.SpellsCastWatcher; import java.util.*; @@ -76,9 +77,8 @@ class AJedisFervorEffect extends OneShotEffect { } //get that opponents to pick a creature or planeswalker for (UUID opponentId : opponentsBlack) { - TargetPermanent target = new TargetPermanent(1, 1, - StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER, false); - game.getPlayer(opponentId).chooseTarget(Outcome.Sacrifice, target, source, game); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER); + game.getPlayer(opponentId).choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } //sacrifices the picked cards diff --git a/Mage.Sets/src/mage/cards/a/Abjure.java b/Mage.Sets/src/mage/cards/a/Abjure.java index 706986415d2..257420b6b9e 100644 --- a/Mage.Sets/src/mage/cards/a/Abjure.java +++ b/Mage.Sets/src/mage/cards/a/Abjure.java @@ -29,7 +29,7 @@ public final class Abjure extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}"); // As an additional cost to cast Abjure, sacrifice a blue permanent. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1,1,filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Counter target spell. this.getSpellAbility().addEffect(new CounterTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java b/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java index 9932cc4de58..0a07dbceb15 100644 --- a/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java +++ b/Mage.Sets/src/mage/cards/a/AcererakTheArchlich.java @@ -16,12 +16,14 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.SuperType; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import mage.watchers.common.CompletedDungeonWatcher; import java.util.UUID; @@ -101,8 +103,7 @@ class AcererakTheArchlichEffect extends OneShotEffect { if (player == null) { continue; } - TargetPermanent target = new TargetControlledCreaturePermanent(0, 1); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(0, 1, StaticFilters.FILTER_PERMANENT_CREATURE); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null && permanent.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/a/AgentOfShauku.java b/Mage.Sets/src/mage/cards/a/AgentOfShauku.java index 00ad0580380..d7ef7bd67c4 100644 --- a/Mage.Sets/src/mage/cards/a/AgentOfShauku.java +++ b/Mage.Sets/src/mage/cards/a/AgentOfShauku.java @@ -37,7 +37,7 @@ public final class AgentOfShauku extends CardImpl { // {1}{B}, Sacrifice a land: Target creature gets +2/+0 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } @@ -50,4 +50,4 @@ public final class AgentOfShauku extends CardImpl { public AgentOfShauku copy() { return new AgentOfShauku(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/a/AggressiveMining.java b/Mage.Sets/src/mage/cards/a/AggressiveMining.java index f4ffe419c9d..d0afd2241c0 100644 --- a/Mage.Sets/src/mage/cards/a/AggressiveMining.java +++ b/Mage.Sets/src/mage/cards/a/AggressiveMining.java @@ -14,6 +14,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -35,7 +36,7 @@ public final class AggressiveMining extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AggressiveMiningEffect())); // Sacrifice a land: Draw two cards. Activate this ability only once each turn. - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_LAND); this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(2), cost)); } diff --git a/Mage.Sets/src/mage/cards/a/AhnCropInvader.java b/Mage.Sets/src/mage/cards/a/AhnCropInvader.java index ba881a3edaf..8f178b0fdd6 100644 --- a/Mage.Sets/src/mage/cards/a/AhnCropInvader.java +++ b/Mage.Sets/src/mage/cards/a/AhnCropInvader.java @@ -54,7 +54,7 @@ public final class AhnCropInvader extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostSourceEffect(2, 0, Duration.EndOfTurn), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AirdropCondor.java b/Mage.Sets/src/mage/cards/a/AirdropCondor.java index 416c1e8f56b..5f2b553949f 100644 --- a/Mage.Sets/src/mage/cards/a/AirdropCondor.java +++ b/Mage.Sets/src/mage/cards/a/AirdropCondor.java @@ -43,7 +43,7 @@ public final class AirdropCondor extends CardImpl { // {1}{R}, Sacrifice a Goblin creature: Airdrop Condor deals damage equal to the sacrificed creature's power to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(SacrificeCostCreaturesPower.instance) .setText("{this} deals damage equal to the sacrificed creature's power to any target"), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AkkiAvalanchers.java b/Mage.Sets/src/mage/cards/a/AkkiAvalanchers.java index 66b482c10d6..d9047c2aa36 100644 --- a/Mage.Sets/src/mage/cards/a/AkkiAvalanchers.java +++ b/Mage.Sets/src/mage/cards/a/AkkiAvalanchers.java @@ -33,7 +33,7 @@ public final class AkkiAvalanchers extends CardImpl { this.toughness = new MageInt(1); // Sacrifice a land: Akki Avalanchers gets +2/+0 until end of turn. Activate this ability only once each turn. - this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn), new SacrificeTargetCost(filter))); } private AkkiAvalanchers(final AkkiAvalanchers card) { diff --git a/Mage.Sets/src/mage/cards/a/AkutaBornOfAsh.java b/Mage.Sets/src/mage/cards/a/AkutaBornOfAsh.java index b021712a853..ea228730a7b 100644 --- a/Mage.Sets/src/mage/cards/a/AkutaBornOfAsh.java +++ b/Mage.Sets/src/mage/cards/a/AkutaBornOfAsh.java @@ -41,7 +41,7 @@ public final class AkutaBornOfAsh extends CardImpl { // At the beginning of your upkeep, if you have more cards in hand than each opponent, you may sacrifice a Swamp. If you do, return Akuta, Born of Ash from your graveyard to the battlefield. Ability ability = new ConditionalInterveningIfTriggeredAbility( new BeginningOfUpkeepTriggeredAbility(Zone.GRAVEYARD, - new DoIfCostPaid(new ReturnSourceFromGraveyardToBattlefieldEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filterSwamp))), + new DoIfCostPaid(new ReturnSourceFromGraveyardToBattlefieldEffect(), new SacrificeTargetCost(filterSwamp)), TargetController.YOU, false), MoreCardsInHandThanOpponentsCondition.instance, "At the beginning of your upkeep, if you have more cards in hand than each opponent, you may sacrifice a Swamp. If you do, return {this} from your graveyard to the battlefield."); @@ -57,4 +57,3 @@ public final class AkutaBornOfAsh extends CardImpl { return new AkutaBornOfAsh(this); } } - diff --git a/Mage.Sets/src/mage/cards/a/AltarsReap.java b/Mage.Sets/src/mage/cards/a/AltarsReap.java index 2313dadc8fa..78d3a802cf1 100644 --- a/Mage.Sets/src/mage/cards/a/AltarsReap.java +++ b/Mage.Sets/src/mage/cards/a/AltarsReap.java @@ -21,7 +21,7 @@ public final class AltarsReap extends CardImpl { // As an additional cost to cast Altar's Reap, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Draw two cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); } diff --git a/Mage.Sets/src/mage/cards/a/AmbushCommander.java b/Mage.Sets/src/mage/cards/a/AmbushCommander.java index b21ba4a8461..c8326fa36ba 100644 --- a/Mage.Sets/src/mage/cards/a/AmbushCommander.java +++ b/Mage.Sets/src/mage/cards/a/AmbushCommander.java @@ -48,7 +48,7 @@ public final class AmbushCommander extends CardImpl { // {1}{G}, Sacrifice an Elf: Target creature gets +3/+3 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(3, 3, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java b/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java index be9b208f348..ff037d42aa1 100644 --- a/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java +++ b/Mage.Sets/src/mage/cards/a/AnakinSkywalker.java @@ -45,7 +45,7 @@ public final class AnakinSkywalker extends CardImpl { // Sacrifice another creature: Target creature gets -1/-1 until end of turn. Activate this ability only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1, -1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/AngelicPurge.java b/Mage.Sets/src/mage/cards/a/AngelicPurge.java index 69282a672e5..dc8b1fb025f 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicPurge.java +++ b/Mage.Sets/src/mage/cards/a/AngelicPurge.java @@ -7,6 +7,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.target.TargetPermanent; @@ -30,7 +31,7 @@ public final class AngelicPurge extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}"); // As an additional cost to cast Angelic Purge, sacrifice a permanent. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledPermanent("a permanent")))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT)); // Exile target artifact, creature, or enchantment. this.getSpellAbility().addEffect(new ExileTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/a/AngelsHerald.java b/Mage.Sets/src/mage/cards/a/AngelsHerald.java index 9947d5e8b4c..4dc95e52071 100644 --- a/Mage.Sets/src/mage/cards/a/AngelsHerald.java +++ b/Mage.Sets/src/mage/cards/a/AngelsHerald.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetControlledCreatureEachColor; +import mage.target.common.TargetSacrificeCreatureEachColor; import java.util.UUID; @@ -43,7 +43,7 @@ public final class AngelsHerald extends CardImpl { new TargetCardInLibrary(filter)), new ManaCostsImpl<>("{2}{W}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreatureEachColor("GWU"))); + ability.addCost(new SacrificeTargetCost(new TargetSacrificeCreatureEachColor("GWU"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AnnihilatingGlare.java b/Mage.Sets/src/mage/cards/a/AnnihilatingGlare.java index 1a007db5a91..f34cf249d1d 100644 --- a/Mage.Sets/src/mage/cards/a/AnnihilatingGlare.java +++ b/Mage.Sets/src/mage/cards/a/AnnihilatingGlare.java @@ -27,7 +27,7 @@ public final class AnnihilatingGlare extends CardImpl { // As an additional cost to cast this spell, pay {4} or sacrifice an artifact or creature. this.getSpellAbility().addCost(new OrCost("pay {4} or sacrifice an artifact or creature", new GenericManaCost(4), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_OR_CREATURE) )); // Destroy target creature or planeswalker. this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java index 57a8d56da79..099dc99680b 100644 --- a/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java +++ b/Mage.Sets/src/mage/cards/a/ApocalypseDemon.java @@ -32,7 +32,7 @@ public final class ApocalypseDemon extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(new CardsInControllerGraveyardCount()))); // At the beginning of your upkeep, tap Apocalypse Demon unless you sacrifice another creature. - TapSourceUnlessPaysEffect tapEffect = new TapSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + TapSourceUnlessPaysEffect tapEffect = new TapSourceUnlessPaysEffect(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); tapEffect.setText("tap {this} unless you sacrifice another creature."); this.addAbility(new BeginningOfUpkeepTriggeredAbility(tapEffect, TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/a/ArcaneSpyglass.java b/Mage.Sets/src/mage/cards/a/ArcaneSpyglass.java index 5eb9a3f7087..6f102bd4d04 100644 --- a/Mage.Sets/src/mage/cards/a/ArcaneSpyglass.java +++ b/Mage.Sets/src/mage/cards/a/ArcaneSpyglass.java @@ -34,7 +34,7 @@ public final class ArcaneSpyglass extends CardImpl { // {2}, {T} , Sacrifice a land: Draw a card and put a charge counter on Arcane Spyglass. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addEffect(new AddCountersSourceEffect(CounterType.CHARGE.createInstance()).concatBy("and")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/ArcboundRavager.java b/Mage.Sets/src/mage/cards/a/ArcboundRavager.java index 7c1831127cd..829e7f9a714 100644 --- a/Mage.Sets/src/mage/cards/a/ArcboundRavager.java +++ b/Mage.Sets/src/mage/cards/a/ArcboundRavager.java @@ -35,7 +35,7 @@ public final class ArcboundRavager extends CardImpl { this.toughness = new MageInt(0); // Sacrifice an artifact: Put a +1/+1 counter on Arcbound Ravager. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new SacrificeTargetCost(filter))); // Modular 1 this.addAbility(new ModularAbility(this, 1)); } diff --git a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java b/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java index 8ccd2c9af44..da8abdf3155 100644 --- a/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java +++ b/Mage.Sets/src/mage/cards/a/ArchdemonOfGreed.java @@ -18,6 +18,7 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -82,7 +83,7 @@ public final class ArchdemonOfGreed extends CardImpl { // create cost for sacrificing a human Player player = game.getPlayer(source.getControllerId()); if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); + TargetSacrifice target = new TargetSacrifice(filter); // if they can pay the cost, then they must pay if (target.canChoose(player.getId(), source, game)) { player.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/a/ArensonsAura.java b/Mage.Sets/src/mage/cards/a/ArensonsAura.java index 8b53bc85503..fdff3569661 100644 --- a/Mage.Sets/src/mage/cards/a/ArensonsAura.java +++ b/Mage.Sets/src/mage/cards/a/ArensonsAura.java @@ -36,7 +36,7 @@ public final class ArensonsAura extends CardImpl { // {W}, Sacrifice an enchantment: Destroy target enchantment. Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ManaCostsImpl<>("{W}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetEnchantmentPermanent().withChooseHint("to destroy")); this.addAbility(ability); // {3}{U}{U}: Counter target enchantment spell. diff --git a/Mage.Sets/src/mage/cards/a/ArgothianWurm.java b/Mage.Sets/src/mage/cards/a/ArgothianWurm.java index 53ab4f7babb..3434cb648cc 100644 --- a/Mage.Sets/src/mage/cards/a/ArgothianWurm.java +++ b/Mage.Sets/src/mage/cards/a/ArgothianWurm.java @@ -14,6 +14,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.players.Player; @@ -70,7 +71,7 @@ class ArgothianWurmEffect extends PutOnLibrarySourceEffect { if (controller != null) { boolean costPaid = false; for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent())); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_LAND); Player player = game.getPlayer(playerId); if (player != null && cost.canPay(source, source, playerId, game) @@ -86,4 +87,4 @@ class ArgothianWurmEffect extends PutOnLibrarySourceEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/a/ArmsDealer.java b/Mage.Sets/src/mage/cards/a/ArmsDealer.java index 67da3c871f4..652e00bb8a4 100644 --- a/Mage.Sets/src/mage/cards/a/ArmsDealer.java +++ b/Mage.Sets/src/mage/cards/a/ArmsDealer.java @@ -40,7 +40,7 @@ public final class ArmsDealer extends CardImpl { SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(4), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/ArmyAnts.java b/Mage.Sets/src/mage/cards/a/ArmyAnts.java index dce10d3f5bc..44bccf4b0cf 100644 --- a/Mage.Sets/src/mage/cards/a/ArmyAnts.java +++ b/Mage.Sets/src/mage/cards/a/ArmyAnts.java @@ -33,7 +33,7 @@ public final class ArmyAnts extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); ability.addTarget(new TargetLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/Artillerize.java b/Mage.Sets/src/mage/cards/a/Artillerize.java index 569a6a06aa3..ae20cdf0f98 100644 --- a/Mage.Sets/src/mage/cards/a/Artillerize.java +++ b/Mage.Sets/src/mage/cards/a/Artillerize.java @@ -20,7 +20,7 @@ public final class Artillerize extends CardImpl { public Artillerize(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ARTIFACT_OR_CREATURE_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ARTIFACT_OR_CREATURE_SHORT_TEXT)); this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addEffect(new DamageTargetEffect(5)); } diff --git a/Mage.Sets/src/mage/cards/a/AshnodFleshMechanist.java b/Mage.Sets/src/mage/cards/a/AshnodFleshMechanist.java index 4adf0b89d0e..60df458a138 100644 --- a/Mage.Sets/src/mage/cards/a/AshnodFleshMechanist.java +++ b/Mage.Sets/src/mage/cards/a/AshnodFleshMechanist.java @@ -43,7 +43,7 @@ public final class AshnodFleshMechanist extends CardImpl { new DoIfCostPaid( new CreateTokenEffect( new PowerstoneToken(), 1, true, false - ), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + ), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ), false )); diff --git a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java index e174bc387ff..0e37b7f1243 100644 --- a/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java +++ b/Mage.Sets/src/mage/cards/a/Asmoranomardicadaistinaculdacar.java @@ -66,7 +66,7 @@ public final class Asmoranomardicadaistinaculdacar extends CardImpl { // Sacrifice two Foods: Target creature deals 6 damage to itself. Ability ability = new SimpleActivatedAbility( new AsmoranomardicadaistinaculdacarEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter2)) + new SacrificeTargetCost(2, filter2) ); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/a/AssaultSuit.java b/Mage.Sets/src/mage/cards/a/AssaultSuit.java index d180d8c7191..fa6b8675421 100644 --- a/Mage.Sets/src/mage/cards/a/AssaultSuit.java +++ b/Mage.Sets/src/mage/cards/a/AssaultSuit.java @@ -1,13 +1,10 @@ - package mage.cards.a; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.Effect; +import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.combat.CantAttackControllerAttachedEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; @@ -19,11 +16,11 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import java.util.Optional; import java.util.UUID; /** @@ -36,23 +33,22 @@ public final class AssaultSuit extends CardImpl { this.subtype.add(SubType.EQUIPMENT); // Equipped creature gets +2/+2, has haste, can't attack you or a planeswalker you control, and can't be sacrificed. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)); - Effect effect = new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.EQUIPMENT); - effect.setText(", has haste"); - ability.addEffect(effect); - effect = new CantAttackControllerAttachedEffect(AttachmentType.EQUIPMENT, true); - effect.setText(", can't attack you or planeswalkers you control"); - ability.addEffect(effect); - effect = new AssaultSuitCantBeSacrificed(); - effect.setText(", and can't be sacrificed"); - ability.addEffect(effect); + Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2)); + ability.addEffect(new GainAbilityAttachedEffect( + HasteAbility.getInstance(), AttachmentType.EQUIPMENT + ).setText(", has haste")); + ability.addEffect(new CantAttackControllerAttachedEffect(AttachmentType.EQUIPMENT, true) + .setText(", can't attack you or planeswalkers you control")); + ability.addEffect(new AssaultSuitCantBeSacrificed()); this.addAbility(ability); // At the beginning of each opponent's upkeep, you may have that player gain control of equipped creature until end of turn. If you do, untap it. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AssaultSuitGainControlEffect(), TargetController.OPPONENT, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new AssaultSuitGainControlEffect(), TargetController.OPPONENT, false + )); // Equip {3} - this.addAbility(new EquipAbility(Outcome.Detriment, new GenericManaCost(3), false)); + this.addAbility(new EquipAbility(3, false)); } private AssaultSuit(final AssaultSuit card) { @@ -65,14 +61,14 @@ public final class AssaultSuit extends CardImpl { } } -class AssaultSuitCantBeSacrificed extends ContinuousRuleModifyingEffectImpl { +class AssaultSuitCantBeSacrificed extends ContinuousEffectImpl { public AssaultSuitCantBeSacrificed() { - super(Duration.WhileOnBattlefield, Outcome.Detriment, true, false); - staticText = "and can't be sacrificed"; + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); + staticText = ", and can't be sacrificed"; } - private AssaultSuitCantBeSacrificed(final AssaultSuitCantBeSacrificed effect) { + public AssaultSuitCantBeSacrificed(final AssaultSuitCantBeSacrificed effect) { super(effect); } @@ -82,19 +78,12 @@ class AssaultSuitCantBeSacrificed extends ContinuousRuleModifyingEffectImpl { } @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - return "This creature can't be sacrificed."; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.SACRIFICE_PERMANENT; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Permanent equipment = game.getPermanent(source.getSourceId()); - return equipment != null && equipment.isAttachedTo(event.getTargetId()); + public boolean apply(Game game, Ability source) { + Optional.ofNullable(source.getSourcePermanentIfItStillExists(game)) + .map(Permanent::getAttachedTo) + .map(game::getPermanent) + .ifPresent(permanent -> permanent.setCanBeSacrificed(false)); + return true; } } @@ -105,7 +94,7 @@ class AssaultSuitGainControlEffect extends OneShotEffect { this.staticText = "you may have that player gain control of equipped creature until end of turn. If you do, untap it"; } - private AssaultSuitGainControlEffect(final AssaultSuitGainControlEffect effect) { + public AssaultSuitGainControlEffect(final AssaultSuitGainControlEffect effect) { super(effect); } @@ -118,22 +107,24 @@ class AssaultSuitGainControlEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player activePlayer = game.getPlayer(game.getActivePlayerId()); - Permanent equipment = game.getPermanent(source.getSourceId()); - if (controller != null && activePlayer != null && equipment != null) { - if (equipment.getAttachedTo() != null) { - Permanent equippedCreature = game.getPermanent(equipment.getAttachedTo()); - if (equippedCreature != null && controller.chooseUse(outcome, - "Let have " + activePlayer.getLogName() + " gain control of " + equippedCreature.getLogName() + '?', source, game)) { - equippedCreature.untap(game); - ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, activePlayer.getId()); - effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game)); - game.addEffect(effect, source); - } - } + Permanent equipment = source.getSourcePermanentIfItStillExists(game); + if (controller == null || activePlayer == null || equipment == null) { + return false; + } + if (equipment.getAttachedTo() == null) { return true; } + Permanent equippedCreature = game.getPermanent(equipment.getAttachedTo()); + if (equippedCreature == null || !controller.chooseUse(outcome, + "Have " + activePlayer.getLogName() + " gain control of " + equippedCreature.getLogName() + '?', source, game)) { + return true; + } + equippedCreature.untap(game); + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfTurn, activePlayer.getId()); + effect.setTargetPointer(new FixedTarget(equipment.getAttachedTo(), game)); + game.addEffect(effect, source); + return true; - return false; } } diff --git a/Mage.Sets/src/mage/cards/a/Atog.java b/Mage.Sets/src/mage/cards/a/Atog.java index baba0172b69..f2a9e5ae6f8 100644 --- a/Mage.Sets/src/mage/cards/a/Atog.java +++ b/Mage.Sets/src/mage/cards/a/Atog.java @@ -27,7 +27,7 @@ public final class Atog extends CardImpl { this.toughness = new MageInt(2); this.addAbility(new SimpleActivatedAbility( new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) )); } diff --git a/Mage.Sets/src/mage/cards/a/Atogatog.java b/Mage.Sets/src/mage/cards/a/Atogatog.java index 6de92ac7b76..2559213c5f4 100644 --- a/Mage.Sets/src/mage/cards/a/Atogatog.java +++ b/Mage.Sets/src/mage/cards/a/Atogatog.java @@ -12,6 +12,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent; /** @@ -20,12 +21,7 @@ import mage.target.common.TargetControlledCreaturePermanent; */ public final class Atogatog extends CardImpl { - private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("an Atog creature"); - - static { - filter.add(TargetController.YOU.getControllerPredicate()); - filter.add(SubType.ATOG.getPredicate()); - } + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.ATOG, "an Atog creature"); public Atogatog(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}{R}{G}"); @@ -38,8 +34,8 @@ public final class Atogatog extends CardImpl { DynamicValue xValue = SacrificeCostCreaturesPower.instance; // Sacrifice an Atog creature: Atogatog gets +X/+X until end of turn, where X is the sacrificed creature's power. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BoostSourceEffect(xValue, xValue,Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,new FilterControlledCreaturePermanent(SubType.ATOG, "an Atog creature"), false)))); + new BoostSourceEffect(xValue, xValue, Duration.EndOfTurn), + new SacrificeTargetCost(filter))); } diff --git a/Mage.Sets/src/mage/cards/a/Attrition.java b/Mage.Sets/src/mage/cards/a/Attrition.java index 9813bdeaa3f..aa675d80593 100644 --- a/Mage.Sets/src/mage/cards/a/Attrition.java +++ b/Mage.Sets/src/mage/cards/a/Attrition.java @@ -24,7 +24,7 @@ public final class Attrition extends CardImpl { //{B}, Sacrifice a creature: Destroy target nonblack creature. SimpleActivatedAbility ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ColoredManaCost(ColoredManaSymbol.B)); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE_NON_BLACK).withChooseHint("to destroy")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AudaciousReshapers.java b/Mage.Sets/src/mage/cards/a/AudaciousReshapers.java index e9ab69146e7..5c210fe89f6 100644 --- a/Mage.Sets/src/mage/cards/a/AudaciousReshapers.java +++ b/Mage.Sets/src/mage/cards/a/AudaciousReshapers.java @@ -33,9 +33,7 @@ public final class AudaciousReshapers extends CardImpl { // {T}, Sacrifice an artifact: Reveal cards from the top of your library until you reveal an artifact card. Put that card onto the battlefield and the rest on the bottom of your library in a random order. Audacious Reshapers deals damage to you equal to the number of cards revealed this way. Ability ability = new SimpleActivatedAbility(new AudaciousReshapersEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AuraFracture.java b/Mage.Sets/src/mage/cards/a/AuraFracture.java index eefd5cbb544..15cf0c13b8b 100644 --- a/Mage.Sets/src/mage/cards/a/AuraFracture.java +++ b/Mage.Sets/src/mage/cards/a/AuraFracture.java @@ -10,6 +10,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetEnchantmentPermanent; @@ -27,7 +28,7 @@ public final class AuraFracture extends CardImpl { Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, new DestroyTargetEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetEnchantmentPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/Auratog.java b/Mage.Sets/src/mage/cards/a/Auratog.java index db649876dd7..0425f2cff93 100644 --- a/Mage.Sets/src/mage/cards/a/Auratog.java +++ b/Mage.Sets/src/mage/cards/a/Auratog.java @@ -33,7 +33,7 @@ public final class Auratog extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(2); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new SacrificeTargetCost(filter))); } private Auratog(final Auratog card) { diff --git a/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java b/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java index bee7db2aec5..1c546942f58 100644 --- a/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java +++ b/Mage.Sets/src/mage/cards/a/AyaraFirstOfLocthwain.java @@ -59,7 +59,7 @@ public final class AyaraFirstOfLocthwain extends CardImpl { // {T}, Sacrifice another black creature: Draw a card. ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java b/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java index 930ef23840f..bc3106c8f87 100644 --- a/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java +++ b/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java @@ -46,7 +46,7 @@ public final class AyliEternalPilgrim extends CardImpl { Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance); effect.setText("You gain life equal to the sacrificed creature's toughness"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); // {1}{W}{B}, Sacrifice another creature: Exile target nonland permanent. Activate only if you have at least 10 life more than your starting life total. @@ -56,7 +56,7 @@ public final class AyliEternalPilgrim extends CardImpl { new ManaCostsImpl<>("{1}{W}{B}"), new AyliEternalPilgrimCondition() ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetNonlandPermanent().withChooseHint("to exile")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BabaLysagaNightWitch.java b/Mage.Sets/src/mage/cards/b/BabaLysagaNightWitch.java index 0b8a14a93f9..e8785b5803c 100644 --- a/Mage.Sets/src/mage/cards/b/BabaLysagaNightWitch.java +++ b/Mage.Sets/src/mage/cards/b/BabaLysagaNightWitch.java @@ -13,7 +13,7 @@ import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.*; @@ -50,10 +50,10 @@ public final class BabaLysagaNightWitch extends CardImpl { class BabaLysagaNightWitchSacrificeCost extends SacrificeTargetCost { - private Set sacrificeTypes = new HashSet<>(); + private final Set sacrificeTypes = new HashSet<>(); BabaLysagaNightWitchSacrificeCost() { - super(new TargetControlledPermanent(0, 3, StaticFilters.FILTER_CONTROLLED_PERMANENTS, true)); + super(new TargetSacrifice(0, 3, StaticFilters.FILTER_CONTROLLED_PERMANENTS)); setText("Sacrifice up to three permanents"); } diff --git a/Mage.Sets/src/mage/cards/b/BagOfDevouring.java b/Mage.Sets/src/mage/cards/b/BagOfDevouring.java index ccf323b84b6..296d47c9c7c 100644 --- a/Mage.Sets/src/mage/cards/b/BagOfDevouring.java +++ b/Mage.Sets/src/mage/cards/b/BagOfDevouring.java @@ -64,7 +64,7 @@ public final class BagOfDevouring extends CardImpl { // {2}, {T}, Sacrifice another artifact or creature: Draw a card. Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); // {3}, {T}, Sacrifice Bag of Devouring: Roll a d10. Return up to X cards from among cards exiled with Bag of Devouring to their owners' hands, where X is the result. diff --git a/Mage.Sets/src/mage/cards/b/BalduvianTradingPost.java b/Mage.Sets/src/mage/cards/b/BalduvianTradingPost.java index f93ca32a852..66d6621a12e 100644 --- a/Mage.Sets/src/mage/cards/b/BalduvianTradingPost.java +++ b/Mage.Sets/src/mage/cards/b/BalduvianTradingPost.java @@ -39,7 +39,7 @@ public final class BalduvianTradingPost extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},""); // If Balduvian Trading Post would enter the battlefield, sacrifice an untapped Mountain instead. If you do, put Balduvian Trading Post onto the battlefield. If you don't, put it into its owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(filter)))); // {tap}: Add {C}{R}. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 0, 0, 1, 0, 0, 0, 1), new TapSourceCost())); diff --git a/Mage.Sets/src/mage/cards/b/BankruptInBlood.java b/Mage.Sets/src/mage/cards/b/BankruptInBlood.java index 7b59afbfc5c..d5031b9a277 100644 --- a/Mage.Sets/src/mage/cards/b/BankruptInBlood.java +++ b/Mage.Sets/src/mage/cards/b/BankruptInBlood.java @@ -8,6 +8,7 @@ import mage.constants.CardType; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -23,7 +24,7 @@ public final class BankruptInBlood extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // As an additional cost to cast this spell, sacrifice two creatures. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(2, filter)); // Draw three cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(3)); diff --git a/Mage.Sets/src/mage/cards/b/BanquetGuests.java b/Mage.Sets/src/mage/cards/b/BanquetGuests.java index b184f3aa97f..6f58fb799bc 100644 --- a/Mage.Sets/src/mage/cards/b/BanquetGuests.java +++ b/Mage.Sets/src/mage/cards/b/BanquetGuests.java @@ -63,7 +63,7 @@ public final class BanquetGuests extends CardImpl { new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new GenericManaCost(2) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BarrageOgre.java b/Mage.Sets/src/mage/cards/b/BarrageOgre.java index 0e8b8e1d1c1..a29fdbeb0bd 100644 --- a/Mage.Sets/src/mage/cards/b/BarrageOgre.java +++ b/Mage.Sets/src/mage/cards/b/BarrageOgre.java @@ -38,7 +38,7 @@ public final class BarrageOgre extends CardImpl { this.toughness = new MageInt(3); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); ability.addTarget(new TargetAnyTarget()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BarrageTyrant.java b/Mage.Sets/src/mage/cards/b/BarrageTyrant.java index b3690361ab1..8be91c7ffea 100644 --- a/Mage.Sets/src/mage/cards/b/BarrageTyrant.java +++ b/Mage.Sets/src/mage/cards/b/BarrageTyrant.java @@ -48,7 +48,7 @@ public final class BarrageTyrant extends CardImpl { Effect effect = new DamageTargetEffect(SacrificeCostCreaturesPower.instance); effect.setText("{this} deals damage equal to the sacrificed creature's power to any target"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BayouGroff.java b/Mage.Sets/src/mage/cards/b/BayouGroff.java index 52f441c2c2a..36faa464fb2 100644 --- a/Mage.Sets/src/mage/cards/b/BayouGroff.java +++ b/Mage.Sets/src/mage/cards/b/BayouGroff.java @@ -28,9 +28,7 @@ public final class BayouGroff extends CardImpl { // As an additional cost to cast this spell, sacrifice a creature or pay {3}. this.getSpellAbility().addCost(new OrCost( - "sacrifice a creature or pay {3}", new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )), new GenericManaCost(3) + "sacrifice a creature or pay {3}", new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), new GenericManaCost(3) )); } diff --git a/Mage.Sets/src/mage/cards/b/BehemothsHerald.java b/Mage.Sets/src/mage/cards/b/BehemothsHerald.java index bfcae12781f..e4e385ce81f 100644 --- a/Mage.Sets/src/mage/cards/b/BehemothsHerald.java +++ b/Mage.Sets/src/mage/cards/b/BehemothsHerald.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetControlledCreatureEachColor; +import mage.target.common.TargetSacrificeCreatureEachColor; import java.util.UUID; @@ -42,7 +42,7 @@ public final class BehemothsHerald extends CardImpl { new TargetCardInLibrary(filter)), new ManaCostsImpl<>("{2}{G}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreatureEachColor("RGW"))); + ability.addCost(new SacrificeTargetCost(new TargetSacrificeCreatureEachColor("RGW"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BellowingMauler.java b/Mage.Sets/src/mage/cards/b/BellowingMauler.java index c3d2c18d19e..ec7a7f0ad63 100644 --- a/Mage.Sets/src/mage/cards/b/BellowingMauler.java +++ b/Mage.Sets/src/mage/cards/b/BellowingMauler.java @@ -17,6 +17,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -68,10 +69,10 @@ class BellowingMaulerEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { boolean sacrificed = false; - TargetPermanent target = new TargetPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN); if (target.canChoose(playerId, source, game) && player.chooseUse(Outcome.Sacrifice, "Sacrifice a nontoken creature or lose 4 life?", null, "Sacrifice", "Lose 4 life", source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); sacrificed = permanent != null && permanent.sacrifice(source, game); } diff --git a/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java b/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java index 82670293c57..bad86d69e04 100644 --- a/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java +++ b/Mage.Sets/src/mage/cards/b/BetrayalOfFlesh.java @@ -37,7 +37,7 @@ public final class BetrayalOfFlesh extends CardImpl { mode.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.getSpellAbility().getModes().addMode(mode); // Entwine-Sacrifice three lands. - this.addAbility(new EntwineAbility(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, new FilterControlledLandPermanent("lands"), true)))); + this.addAbility(new EntwineAbility(new SacrificeTargetCost(3, StaticFilters.FILTER_LANDS))); } private BetrayalOfFlesh(final BetrayalOfFlesh card) { diff --git a/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java b/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java index 0081b5d9329..98343cfe184 100644 --- a/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java +++ b/Mage.Sets/src/mage/cards/b/BetrothedOfFire.java @@ -49,7 +49,7 @@ public final class BetrothedOfFire extends CardImpl { // Sacrifice an untapped creature: Enchanted creature gets +2/+0 until end of turn. this.addAbility(new SimpleActivatedAbility( new BoostEnchantedEffect(2, 0, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) )); // Sacrifice enchanted creature: Creatures you control get +2/+0 until end of turn. diff --git a/Mage.Sets/src/mage/cards/b/BillThePony.java b/Mage.Sets/src/mage/cards/b/BillThePony.java index 60d69e3a2d1..cd2b01c69ca 100644 --- a/Mage.Sets/src/mage/cards/b/BillThePony.java +++ b/Mage.Sets/src/mage/cards/b/BillThePony.java @@ -36,7 +36,7 @@ public final class BillThePony extends CardImpl { // Sacrifice a Food: Until end of turn, target creature you control assigns combat damage equal to its toughness rather than its power. Ability ability = new SimpleActivatedAbility( new CombatDamageByToughnessTargetEffect(Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD) ); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE)); @@ -51,4 +51,4 @@ public final class BillThePony extends CardImpl { public BillThePony copy() { return new BillThePony(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/BiolumeSerpent.java b/Mage.Sets/src/mage/cards/b/BiolumeSerpent.java index 80c351540fe..bcee214b7b3 100644 --- a/Mage.Sets/src/mage/cards/b/BiolumeSerpent.java +++ b/Mage.Sets/src/mage/cards/b/BiolumeSerpent.java @@ -11,6 +11,7 @@ import mage.constants.Duration; import mage.constants.SubType; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -34,7 +35,7 @@ public final class BiolumeSerpent extends CardImpl { // Sacrifice two Islands: Biolume Serpent can't be blocked this turn. this.addAbility(new SimpleActivatedAbility( new CantBeBlockedSourceEffect(Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) )); } diff --git a/Mage.Sets/src/mage/cards/b/BirthingPod.java b/Mage.Sets/src/mage/cards/b/BirthingPod.java index bfebdd16471..ce38bbc94dd 100644 --- a/Mage.Sets/src/mage/cards/b/BirthingPod.java +++ b/Mage.Sets/src/mage/cards/b/BirthingPod.java @@ -40,9 +40,7 @@ public final class BirthingPod extends CardImpl { Zone.BATTLEFIELD, new BirthingPodEffect(), new ManaCostsImpl<>("{1}{G/P}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java b/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java index a5b43154950..a87b4b6189e 100644 --- a/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java +++ b/Mage.Sets/src/mage/cards/b/BjornaNightfallAlchemist.java @@ -34,7 +34,7 @@ public final class BjornaNightfallAlchemist extends CardImpl { // {T}, Sacrifice an artifact: Lucas, the Sharpshooter deals 1 damage to target creature. Goad that creature. Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); ability.addEffect(new GoadTargetEffect().setText("Goad that creature")); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BlazingHellhound.java b/Mage.Sets/src/mage/cards/b/BlazingHellhound.java index efa0e35f666..39ca6600224 100644 --- a/Mage.Sets/src/mage/cards/b/BlazingHellhound.java +++ b/Mage.Sets/src/mage/cards/b/BlazingHellhound.java @@ -31,7 +31,7 @@ public final class BlazingHellhound extends CardImpl { // {1}, Sacrifice another creature: Blazing Hellhound deals 1 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl<>("{1}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BlightedShaman.java b/Mage.Sets/src/mage/cards/b/BlightedShaman.java index 785ea1d5789..eb2f4cc7fea 100644 --- a/Mage.Sets/src/mage/cards/b/BlightedShaman.java +++ b/Mage.Sets/src/mage/cards/b/BlightedShaman.java @@ -41,7 +41,7 @@ public final class BlightedShaman extends CardImpl { // {tap}, Sacrifice a Swamp: Target creature gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterSwamp))); + ability.addCost(new SacrificeTargetCost(filterSwamp)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BloodAspirant.java b/Mage.Sets/src/mage/cards/b/BloodAspirant.java index 8f5a07f4534..16a32fbfec3 100644 --- a/Mage.Sets/src/mage/cards/b/BloodAspirant.java +++ b/Mage.Sets/src/mage/cards/b/BloodAspirant.java @@ -56,7 +56,7 @@ public final class BloodAspirant extends CardImpl { new DamageTargetEffect(1), new ManaCostsImpl<>("{1}{R}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addEffect(new CantBlockTargetEffect(Duration.EndOfTurn) .setText("That creature can't block this turn.")); ability.addTarget(new TargetCreaturePermanent()); @@ -102,4 +102,4 @@ class BloodAspirantAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever you sacrifice a permanent, put a +1/+1 counter on {this}."; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/BloodBairn.java b/Mage.Sets/src/mage/cards/b/BloodBairn.java index 6929077900a..46d04541c03 100644 --- a/Mage.Sets/src/mage/cards/b/BloodBairn.java +++ b/Mage.Sets/src/mage/cards/b/BloodBairn.java @@ -32,7 +32,7 @@ public final class BloodBairn extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } diff --git a/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java b/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java index 00f55ae1760..37af0c253ca 100644 --- a/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java +++ b/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java @@ -47,7 +47,7 @@ public final class BloodChinFanatic extends CardImpl { effect2.setText("and you gain X life, where X is the sacrificed creature's power"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}{B}")); ability.addEffect(effect2); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BloodHost.java b/Mage.Sets/src/mage/cards/b/BloodHost.java index 08379195f41..dfa52cbe9e8 100644 --- a/Mage.Sets/src/mage/cards/b/BloodHost.java +++ b/Mage.Sets/src/mage/cards/b/BloodHost.java @@ -36,7 +36,7 @@ public final class BloodHost extends CardImpl { Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); effect.setText("Put a +1/+1 counter on {this}"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); // and you gain 2 life. effect = new GainLifeEffect(2); effect.setText("and you gain 2 life"); diff --git a/Mage.Sets/src/mage/cards/b/BloodmistInfiltrator.java b/Mage.Sets/src/mage/cards/b/BloodmistInfiltrator.java index 22216e76baa..5095af0309a 100644 --- a/Mage.Sets/src/mage/cards/b/BloodmistInfiltrator.java +++ b/Mage.Sets/src/mage/cards/b/BloodmistInfiltrator.java @@ -30,7 +30,7 @@ public final class BloodmistInfiltrator extends CardImpl { // Whenever Bloodmist Infiltrator attacks, you may sacrifice another creature. If you do, Bloodmist Infiltrator can't be blocked this turn. this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( new CantBeBlockedSourceEffect(Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ), false)); } diff --git a/Mage.Sets/src/mage/cards/b/BloodsoakedAltar.java b/Mage.Sets/src/mage/cards/b/BloodsoakedAltar.java index c894157d36a..e700d8bf20d 100644 --- a/Mage.Sets/src/mage/cards/b/BloodsoakedAltar.java +++ b/Mage.Sets/src/mage/cards/b/BloodsoakedAltar.java @@ -31,9 +31,7 @@ public final class BloodsoakedAltar extends CardImpl { ); ability.addCost(new PayLifeCost(2)); ability.addCost(new DiscardCardCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BogDown.java b/Mage.Sets/src/mage/cards/b/BogDown.java index 6ea18fb5bcb..3077040492f 100644 --- a/Mage.Sets/src/mage/cards/b/BogDown.java +++ b/Mage.Sets/src/mage/cards/b/BogDown.java @@ -12,6 +12,7 @@ import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -27,7 +28,7 @@ public final class BogDown extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Kicker-Sacrifice two lands. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, filter)))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(2, filter))); // Target player discards two cards. If Bog Down was kicked, that player discards three cards instead. this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DiscardTargetEffect(3), diff --git a/Mage.Sets/src/mage/cards/b/BogElemental.java b/Mage.Sets/src/mage/cards/b/BogElemental.java index b75f8e24ed0..281e9dfe064 100644 --- a/Mage.Sets/src/mage/cards/b/BogElemental.java +++ b/Mage.Sets/src/mage/cards/b/BogElemental.java @@ -34,7 +34,7 @@ public final class BogElemental extends CardImpl { // At the beginning of your upkeep, sacrifice Bog Elemental unless you sacrifice a land. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))), + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/b/BogGlider.java b/Mage.Sets/src/mage/cards/b/BogGlider.java index 9331d4a6203..4a59b270524 100644 --- a/Mage.Sets/src/mage/cards/b/BogGlider.java +++ b/Mage.Sets/src/mage/cards/b/BogGlider.java @@ -48,7 +48,7 @@ public final class BogGlider extends CardImpl { // {T}, Sacrifice a land: Search your library for a Mercenary permanent card with converted mana cost 2 or less and put it onto the battlefield. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(landFilter))); + ability.addCost(new SacrificeTargetCost(landFilter)); this.addAbility(ability); } @@ -60,4 +60,4 @@ public final class BogGlider extends CardImpl { public BogGlider copy() { return new BogGlider(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/BogNaughty.java b/Mage.Sets/src/mage/cards/b/BogNaughty.java index ce1a5206b7b..85d4d7242ee 100644 --- a/Mage.Sets/src/mage/cards/b/BogNaughty.java +++ b/Mage.Sets/src/mage/cards/b/BogNaughty.java @@ -37,7 +37,7 @@ public final class BogNaughty extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostTargetEffect(-3, -3, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BogardanDragonheart.java b/Mage.Sets/src/mage/cards/b/BogardanDragonheart.java index e05f3aa1499..326bd480e31 100644 --- a/Mage.Sets/src/mage/cards/b/BogardanDragonheart.java +++ b/Mage.Sets/src/mage/cards/b/BogardanDragonheart.java @@ -33,7 +33,7 @@ public final class BogardanDragonheart extends CardImpl { // Sacrifice another creature: Until end of turn, Bogardan Dragonheart becomes a Dragon with base power and toughness 4/4, flying, and haste. this.addAbility(new SimpleActivatedAbility(new BecomesCreatureSourceEffect( new BogardanDragonheartToken(), CardType.CREATURE, Duration.EndOfTurn - ), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)))); + ), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private BogardanDragonheart(final BogardanDragonheart card) { diff --git a/Mage.Sets/src/mage/cards/b/BolassCitadel.java b/Mage.Sets/src/mage/cards/b/BolassCitadel.java index eff8385f182..50807825044 100644 --- a/Mage.Sets/src/mage/cards/b/BolassCitadel.java +++ b/Mage.Sets/src/mage/cards/b/BolassCitadel.java @@ -49,9 +49,7 @@ public final class BolassCitadel extends CardImpl { // {T}, Sacrifice ten nonland permanents: Each opponent loses 10 life. Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(10), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - 10, 10, filter, true - ))); + ability.addCost(new SacrificeTargetCost(10, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BoneShards.java b/Mage.Sets/src/mage/cards/b/BoneShards.java index 8b79ba03d06..d2dabdc9b58 100644 --- a/Mage.Sets/src/mage/cards/b/BoneShards.java +++ b/Mage.Sets/src/mage/cards/b/BoneShards.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -22,7 +23,7 @@ public final class BoneShards extends CardImpl { // As an additional cost to cast this spell, sacrifice a creature or discard a card. this.getSpellAbility().addCost(new OrCost( - "sacrifice a creature or discard a card", new SacrificeTargetCost(new TargetControlledCreaturePermanent()), + "sacrifice a creature or discard a card", new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE), new DiscardCardCost() )); diff --git a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java index 243ac46ad6f..e543b30a5f5 100644 --- a/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java +++ b/Mage.Sets/src/mage/cards/b/BontuTheGlorified.java @@ -58,7 +58,7 @@ public final class BontuTheGlorified extends CardImpl { Effect effect = new GainLifeEffect(1); effect.setText("and you gain 1 life"); ability.addEffect(effect); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BoshIronGolem.java b/Mage.Sets/src/mage/cards/b/BoshIronGolem.java index 924b84a1984..86995273df6 100644 --- a/Mage.Sets/src/mage/cards/b/BoshIronGolem.java +++ b/Mage.Sets/src/mage/cards/b/BoshIronGolem.java @@ -16,6 +16,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetControlledPermanent; @@ -42,7 +43,7 @@ public final class BoshIronGolem extends CardImpl { Effect effect = new DamageTargetEffect(SacrificeCostManaValue.ARTIFACT); effect.setText("{this} deals damage equal to the sacrificed artifact's mana value to any target"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{3}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BoundByMoonsilver.java b/Mage.Sets/src/mage/cards/b/BoundByMoonsilver.java index d517e063c05..72fa4ff1284 100644 --- a/Mage.Sets/src/mage/cards/b/BoundByMoonsilver.java +++ b/Mage.Sets/src/mage/cards/b/BoundByMoonsilver.java @@ -48,7 +48,7 @@ public final class BoundByMoonsilver extends CardImpl { // Sacrifice another permanent: Attach Bound by Moonsilver to target creature. Activate this ability only any time you could cast a sorcery and only once each turn. LimitedTimesPerTurnActivatedAbility limitedAbility = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "Attach {this} to target creature"), - new SacrificeTargetCost(new TargetControlledPermanent(filter)), 1); + new SacrificeTargetCost(filter), 1); limitedAbility.setTiming(TimingRule.SORCERY); limitedAbility.addTarget(new TargetCreaturePermanent()); this.addAbility(limitedAbility); diff --git a/Mage.Sets/src/mage/cards/b/BraidsArisenNightmare.java b/Mage.Sets/src/mage/cards/b/BraidsArisenNightmare.java index 48b22a6950b..da6a239d47d 100644 --- a/Mage.Sets/src/mage/cards/b/BraidsArisenNightmare.java +++ b/Mage.Sets/src/mage/cards/b/BraidsArisenNightmare.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; /** @@ -86,11 +87,11 @@ class BraidsArisenNightmareEffect extends OneShotEffect { if (controller == null) { return false; } - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(filter); if (!target.canChoose(controller.getId(), source, game)) { return false; } - controller.chooseTarget(Outcome.Sacrifice, target, source, game); + controller.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null) { return false; @@ -115,14 +116,14 @@ class BraidsArisenNightmareEffect extends OneShotEffect { } private boolean braidsSacrifice(Player opponent, FilterControlledPermanent opponentFilter, Game game, Ability source) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, opponentFilter, true); + TargetSacrifice target = new TargetSacrifice(opponentFilter); if (!target.canChoose(opponent.getId(), source, game)) { return false; } if (!opponent.chooseUse(Outcome.Sacrifice, "Sacrifice " + CardUtil.addArticle(opponentFilter.getMessage()) + '?', source, game)) { return false; } - opponent.chooseTarget(Outcome.Sacrifice, target, source, game); + opponent.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); return permanent != null && permanent.sacrifice(source, game); } diff --git a/Mage.Sets/src/mage/cards/b/BrawlBashOgre.java b/Mage.Sets/src/mage/cards/b/BrawlBashOgre.java index 1ad8e9cce8f..2ce5e025722 100644 --- a/Mage.Sets/src/mage/cards/b/BrawlBashOgre.java +++ b/Mage.Sets/src/mage/cards/b/BrawlBashOgre.java @@ -36,9 +36,7 @@ public final class BrawlBashOgre extends CardImpl { this.addAbility(new AttacksTriggeredAbility( new DoIfCostPaid( new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - )) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ), false )); } diff --git a/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java b/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java index f7177678765..3bf6071a81f 100644 --- a/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java +++ b/Mage.Sets/src/mage/cards/b/BreyaEtheriumShaper.java @@ -15,6 +15,7 @@ import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.permanent.token.ThopterToken; import mage.target.common.TargetControlledPermanent; @@ -45,7 +46,7 @@ public final class BreyaEtheriumShaper extends CardImpl { Zone.BATTLEFIELD, new DamageTargetEffect(3), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledArtifactPermanent("artifacts"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_ARTIFACTS)); ability.addTarget(new TargetPlayerOrPlaneswalker()); // Target creature gets -4/-4 until end of turn. diff --git a/Mage.Sets/src/mage/cards/b/BreyasApprentice.java b/Mage.Sets/src/mage/cards/b/BreyasApprentice.java index bc062ac069f..63c7d0662e9 100644 --- a/Mage.Sets/src/mage/cards/b/BreyasApprentice.java +++ b/Mage.Sets/src/mage/cards/b/BreyasApprentice.java @@ -45,9 +45,7 @@ public final class BreyasApprentice extends CardImpl { // {T}, Sacrifice an artifact: Choose one — // • Exile the top card of your library. Until the end of your next turn, you may play that card. Ability ability = new SimpleActivatedAbility(new BreyasApprenticeEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); // • Target creature gets +2/+0 until end of turn. Mode mode = new Mode(new BoostTargetEffect(2, 0, Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/b/BrionStoutarm.java b/Mage.Sets/src/mage/cards/b/BrionStoutarm.java index e7b727f2006..05fb94be695 100644 --- a/Mage.Sets/src/mage/cards/b/BrionStoutarm.java +++ b/Mage.Sets/src/mage/cards/b/BrionStoutarm.java @@ -41,7 +41,7 @@ public final class BrionStoutarm extends CardImpl { Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(SacrificeCostCreaturesPower.instance) .setText("{this} deals damage equal to the sacrificed creature's power to target player or planeswalker"), new ManaCostsImpl<>("{R}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BroadsideBombardiers.java b/Mage.Sets/src/mage/cards/b/BroadsideBombardiers.java index 5f9926ae7eb..99af79f1d41 100644 --- a/Mage.Sets/src/mage/cards/b/BroadsideBombardiers.java +++ b/Mage.Sets/src/mage/cards/b/BroadsideBombardiers.java @@ -41,8 +41,7 @@ public final class BroadsideBombardiers extends CardImpl { Ability ability = new BoastAbility(new DamageTargetEffect( new IntPlusDynamicValue(2, SacrificeCostManaValue.PERMANENT)) .setText("{this} deals damage equal to 2 plus the sacrificed permanent's mana value to any target."), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT_SHORT_TEXT)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE_OR_ARTIFACT_SHORT_TEXT) ); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/BrutalSuppression.java b/Mage.Sets/src/mage/cards/b/BrutalSuppression.java index a3c84ff4ddf..c4b03a7bc32 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalSuppression.java +++ b/Mage.Sets/src/mage/cards/b/BrutalSuppression.java @@ -69,9 +69,7 @@ class BrutalSuppressionAdditionalCostEffect extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - target.setRequired(false); - abilityToModify.addCost(new SacrificeTargetCost(target)); + abilityToModify.addCost(new SacrificeTargetCost(filter)); return true; } diff --git a/Mage.Sets/src/mage/cards/b/BubblingCauldron.java b/Mage.Sets/src/mage/cards/b/BubblingCauldron.java index cc7b03d08ce..e66ff592edd 100644 --- a/Mage.Sets/src/mage/cards/b/BubblingCauldron.java +++ b/Mage.Sets/src/mage/cards/b/BubblingCauldron.java @@ -43,7 +43,7 @@ public final class BubblingCauldron extends CardImpl { // {1}, {T}, Sacrifice a creature named Festering Newt: Each opponent loses 4 life. You gain life equal to the life lost this way. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BubblingCauldronEffect(), new ManaCostsImpl<>("{1}")); ability2.addCost(new TapSourceCost()); - ability2.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); + ability2.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/b/BucknardsEverfullPurse.java b/Mage.Sets/src/mage/cards/b/BucknardsEverfullPurse.java index aa28abec800..3c41e5055e2 100644 --- a/Mage.Sets/src/mage/cards/b/BucknardsEverfullPurse.java +++ b/Mage.Sets/src/mage/cards/b/BucknardsEverfullPurse.java @@ -5,17 +5,14 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.effects.common.PlayerToRightGainsControlOfSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.permanent.token.TreasureToken; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -30,6 +27,7 @@ public final class BucknardsEverfullPurse extends CardImpl { // {1}, {T}: Roll a d4 and create a number of Treasure tokens equal to the result. The player to your right gains control of Bucknard's Everfull Purse. Ability ability = new SimpleActivatedAbility(new BucknardsEverfullPurseEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); + ability.addEffect(new PlayerToRightGainsControlOfSourceEffect()); this.addAbility(ability); } @@ -47,8 +45,7 @@ class BucknardsEverfullPurseEffect extends OneShotEffect { BucknardsEverfullPurseEffect() { super(Outcome.Benefit); - staticText = "roll a d4 and create a number of Treasure tokens equal to the result. " + - "The player to your right gains control of {this}"; + staticText = "roll a d4 and create a number of Treasure tokens equal to the result"; } private BucknardsEverfullPurseEffect(final BucknardsEverfullPurseEffect effect) { @@ -66,26 +63,9 @@ class BucknardsEverfullPurseEffect extends OneShotEffect { if (player == null) { return false; } - new TreasureToken().putOntoBattlefield( + return new TreasureToken().putOntoBattlefield( player.rollDice(outcome, source, game, 4), game, source, source.getControllerId() ); - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - if (permanent == null) { - return true; - } - UUID playerToRightId = game - .getState() - .getPlayersInRange(source.getControllerId(), game) - .stream() - .reduce((u1, u2) -> u2) - .orElse(null); - if (playerToRightId == null) { - return false; - } - game.addEffect(new GainControlTargetEffect( - Duration.Custom, true, playerToRightId - ).setTargetPointer(new FixedTarget(permanent, game)), source); - return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java index cc81dfbf8d5..f898f531b96 100644 --- a/Mage.Sets/src/mage/cards/b/BurningOfXinye.java +++ b/Mage.Sets/src/mage/cards/b/BurningOfXinye.java @@ -17,6 +17,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; /** * @@ -81,7 +82,7 @@ class BurningOfXinyeEffect extends OneShotEffect{ int realCount = game.getBattlefield().countAll(filter, player.getId(), game); int amount = Math.min(4, realCount); - Target target = new TargetControlledPermanent(amount, amount, filter, true); + Target target = new TargetSacrifice(amount, filter); if (amount > 0 && target.canChoose(player.getId(), source, game)) { while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) { player.choose(Outcome.Sacrifice, target, source, game); @@ -102,4 +103,4 @@ class BurningOfXinyeEffect extends OneShotEffect{ public BurningOfXinyeEffect copy() { return new BurningOfXinyeEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java index 5219f808060..53c40006dcf 100644 --- a/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java +++ b/Mage.Sets/src/mage/cards/b/BushmeatPoacher.java @@ -36,7 +36,7 @@ public final class BushmeatPoacher extends CardImpl { // {1}, {T}, Sacrifice another creature: You gain life equal to that creature's toughness. Draw a card. Ability ability = new SimpleActivatedAbility(new BushmeatPoacherEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } @@ -92,4 +92,4 @@ class BushmeatPoacherEffect extends OneShotEffect { } return player.drawCards(1, source, game) > 0; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java b/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java index f6704096914..7bc2ca25f08 100644 --- a/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java +++ b/Mage.Sets/src/mage/cards/b/ButcherOfTheHorde.java @@ -43,8 +43,7 @@ public final class ButcherOfTheHorde extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Sacrifice another creature: Butcher of the Horde gains your choice of vigilance, lifelink, or haste until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new ButcherOfTheHordeEffect(), new SacrificeTargetCost( - new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false)))); + new ButcherOfTheHordeEffect(), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private ButcherOfTheHorde(final ButcherOfTheHorde card) { diff --git a/Mage.Sets/src/mage/cards/c/CabalArchon.java b/Mage.Sets/src/mage/cards/c/CabalArchon.java index f07a2ef18ba..a700fa702ad 100644 --- a/Mage.Sets/src/mage/cards/c/CabalArchon.java +++ b/Mage.Sets/src/mage/cards/c/CabalArchon.java @@ -43,7 +43,7 @@ public final class CabalArchon extends CardImpl { Effect effect = new GainLifeEffect(2); effect.setText("and you gain 2 life"); ability.addEffect(effect); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapist.java b/Mage.Sets/src/mage/cards/c/CabalTherapist.java index 6f4395e7281..56315f5366f 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapist.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapist.java @@ -51,8 +51,7 @@ public final class CabalTherapist extends CardImpl { ability.addEffect(new CabalTherapistDiscardEffect()); ability.addTarget(new TargetPlayer()); this.addAbility(new BeginningOfPreCombatMainTriggeredAbility( - new DoWhenCostPaid(ability, new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) + new DoWhenCostPaid(ability, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT ), "Sacrifice a creature?"), TargetController.YOU, false )); } diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapy.java b/Mage.Sets/src/mage/cards/c/CabalTherapy.java index 77794236808..ef71932bd1d 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapy.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapy.java @@ -35,9 +35,7 @@ public final class CabalTherapy extends CardImpl { this.getSpellAbility().addEffect(new CabalTherapyEffect()); // Flashback-Sacrifice a creature. - this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost( - new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - ))); + this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); } private CabalTherapy(final CabalTherapy card) { diff --git a/Mage.Sets/src/mage/cards/c/CaribouRange.java b/Mage.Sets/src/mage/cards/c/CaribouRange.java index 0c27bafeefe..69721ec5449 100644 --- a/Mage.Sets/src/mage/cards/c/CaribouRange.java +++ b/Mage.Sets/src/mage/cards/c/CaribouRange.java @@ -55,7 +55,7 @@ public final class CaribouRange extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); // Sacrifice a Caribou token: You gain 1 life. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(1), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)))); + new SacrificeTargetCost(filter))); } private CaribouRange(final CaribouRange card) { diff --git a/Mage.Sets/src/mage/cards/c/CartelAristocrat.java b/Mage.Sets/src/mage/cards/c/CartelAristocrat.java index dc05ed357fd..f9e6bc7c2c7 100644 --- a/Mage.Sets/src/mage/cards/c/CartelAristocrat.java +++ b/Mage.Sets/src/mage/cards/c/CartelAristocrat.java @@ -33,7 +33,7 @@ public final class CartelAristocrat extends CardImpl { // Sacrifice another creature: Cartel Aristocrat gains protection from the color of your choice until end of turn. this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new GainProtectionFromColorSourceEffect(Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private CartelAristocrat(final CartelAristocrat card) { diff --git a/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java b/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java index dbce19bf7bc..b04ceadc762 100644 --- a/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java +++ b/Mage.Sets/src/mage/cards/c/CauldronFamiliar.java @@ -39,7 +39,7 @@ public final class CauldronFamiliar extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, false), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD) )); } diff --git a/Mage.Sets/src/mage/cards/c/CavalierOfNight.java b/Mage.Sets/src/mage/cards/c/CavalierOfNight.java index 231879c76d8..ef94b856b75 100644 --- a/Mage.Sets/src/mage/cards/c/CavalierOfNight.java +++ b/Mage.Sets/src/mage/cards/c/CavalierOfNight.java @@ -54,7 +54,7 @@ public final class CavalierOfNight extends CardImpl { ); triggeredAbility.addTarget(new TargetOpponentsCreaturePermanent()); this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( - triggeredAbility, new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)), + triggeredAbility, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE), "Sacrifice a creature?" ))); diff --git a/Mage.Sets/src/mage/cards/c/CephalidScout.java b/Mage.Sets/src/mage/cards/c/CephalidScout.java index 2b4223caf76..7f69636cdd6 100644 --- a/Mage.Sets/src/mage/cards/c/CephalidScout.java +++ b/Mage.Sets/src/mage/cards/c/CephalidScout.java @@ -36,7 +36,7 @@ public final class CephalidScout extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // {2}{U}, Sacrifice a land: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{2}{U}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ChainOfSilence.java b/Mage.Sets/src/mage/cards/c/ChainOfSilence.java index b00d3abdbaf..fb418061f16 100644 --- a/Mage.Sets/src/mage/cards/c/ChainOfSilence.java +++ b/Mage.Sets/src/mage/cards/c/ChainOfSilence.java @@ -19,6 +19,7 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -74,8 +75,8 @@ class ChainOfSilenceEffect extends OneShotEffect { ContinuousEffect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn); game.addEffect(effect, source); Player player = game.getPlayer(permanent.getControllerId()); - TargetControlledPermanent target = new TargetControlledPermanent(0, 1, new FilterControlledLandPermanent("a land to sacrifice (to be able to copy " + sourceObject.getName() + ')'), true); - if (player != null && player.chooseTarget(Outcome.Sacrifice, target, source, game)) { + TargetSacrifice target = new TargetSacrifice(0, 1, new FilterControlledLandPermanent("a land to sacrifice (to be able to copy " + sourceObject.getName() + ')')); + if (player != null && player.choose(Outcome.Sacrifice, target, source, game)) { Permanent land = game.getPermanent(target.getFirstTarget()); if (land != null && land.sacrifice(source, game)) { if (player.chooseUse(outcome, "Copy the spell?", source, game)) { diff --git a/Mage.Sets/src/mage/cards/c/ChainOfVapor.java b/Mage.Sets/src/mage/cards/c/ChainOfVapor.java index 3009188aeb0..4b138a80827 100644 --- a/Mage.Sets/src/mage/cards/c/ChainOfVapor.java +++ b/Mage.Sets/src/mage/cards/c/ChainOfVapor.java @@ -17,6 +17,7 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetNonlandPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -70,7 +71,7 @@ class ChainOfVaporEffect extends OneShotEffect { if (permanent != null) { controller.moveCards(permanent, Zone.HAND, source, game); Player player = game.getPlayer(permanent.getControllerId()); - TargetControlledPermanent target = new TargetControlledPermanent(0, 1, new FilterControlledLandPermanent("a land to sacrifice (to be able to copy " + sourceObject.getName() + ')'), true); + TargetSacrifice target = new TargetSacrifice(0, 1, new FilterControlledLandPermanent("a land to sacrifice (to be able to copy " + sourceObject.getName() + ')')); if (player != null && player.chooseTarget(Outcome.Sacrifice, target, source, game)) { Permanent land = game.getPermanent(target.getFirstTarget()); if (land != null && land.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/c/ChainedBrute.java b/Mage.Sets/src/mage/cards/c/ChainedBrute.java index 6d3134d5118..dd39e3422ba 100644 --- a/Mage.Sets/src/mage/cards/c/ChainedBrute.java +++ b/Mage.Sets/src/mage/cards/c/ChainedBrute.java @@ -39,9 +39,7 @@ public final class ChainedBrute extends CardImpl { Zone.BATTLEFIELD, new UntapSourceEffect(), new GenericManaCost(1), MyTurnCondition.instance ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/Chitterspitter.java b/Mage.Sets/src/mage/cards/c/Chitterspitter.java index 74924dd04ae..fae95fefc53 100644 --- a/Mage.Sets/src/mage/cards/c/Chitterspitter.java +++ b/Mage.Sets/src/mage/cards/c/Chitterspitter.java @@ -47,7 +47,7 @@ public final class Chitterspitter extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility( new DoIfCostPaid( new AddCountersSourceEffect(CounterType.ACORN.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) ), TargetController.YOU, false diff --git a/Mage.Sets/src/mage/cards/c/ChoiceOfDamnations.java b/Mage.Sets/src/mage/cards/c/ChoiceOfDamnations.java index 8257ce6819b..fb51573da4b 100644 --- a/Mage.Sets/src/mage/cards/c/ChoiceOfDamnations.java +++ b/Mage.Sets/src/mage/cards/c/ChoiceOfDamnations.java @@ -8,6 +8,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -15,6 +16,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -98,8 +100,8 @@ class ChoiceOfDamnationsEffect extends OneShotEffect { // (2005-06-01) if (numberPermanents > amount) { int numberToSacrifice = numberPermanents - amount; - Target target = new TargetControlledPermanent(numberToSacrifice, numberToSacrifice, new FilterControlledPermanent("permanent you control to sacrifice"), false); - targetPlayer.chooseTarget(Outcome.Sacrifice, target, source, game); + Target target = new TargetSacrifice(numberToSacrifice, numberToSacrifice == 1 ? StaticFilters.FILTER_PERMANENT : StaticFilters.FILTER_PERMANENTS); + targetPlayer.choose(Outcome.Sacrifice, target, source, game); for (UUID uuid : target.getTargets()) { Permanent permanent = game.getPermanent(uuid); if (permanent != null) { diff --git a/Mage.Sets/src/mage/cards/c/Clickslither.java b/Mage.Sets/src/mage/cards/c/Clickslither.java index 9e69d27cc6c..ce1e01d9e29 100644 --- a/Mage.Sets/src/mage/cards/c/Clickslither.java +++ b/Mage.Sets/src/mage/cards/c/Clickslither.java @@ -45,7 +45,7 @@ public final class Clickslither extends CardImpl { Effect effect = new BoostSourceEffect(2,2,Duration.EndOfTurn); effect.setText("{this} gets +2/+2"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true))); + new SacrificeTargetCost(filter)); effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains trample until end of turn"); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/c/CoastalHornclaw.java b/Mage.Sets/src/mage/cards/c/CoastalHornclaw.java index 020641fcaca..b9e44d1f4fe 100644 --- a/Mage.Sets/src/mage/cards/c/CoastalHornclaw.java +++ b/Mage.Sets/src/mage/cards/c/CoastalHornclaw.java @@ -34,7 +34,7 @@ public final class CoastalHornclaw extends CardImpl { this.toughness = new MageInt(3); // Sacrifice a land: Coastal Hornclaw gains flying until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(filter))); } private CoastalHornclaw(final CoastalHornclaw card) { diff --git a/Mage.Sets/src/mage/cards/c/CoffinPuppets.java b/Mage.Sets/src/mage/cards/c/CoffinPuppets.java index 67c9fde117c..7ca089511df 100644 --- a/Mage.Sets/src/mage/cards/c/CoffinPuppets.java +++ b/Mage.Sets/src/mage/cards/c/CoffinPuppets.java @@ -52,9 +52,7 @@ public final class CoffinPuppets extends CardImpl { this.addAbility(new ActivateIfConditionActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(), - new SacrificeTargetCost( - new TargetControlledPermanent(2, 2, filter2, true) - ), condition + new SacrificeTargetCost(2, filter2), condition )); } diff --git a/Mage.Sets/src/mage/cards/c/CombineChrysalis.java b/Mage.Sets/src/mage/cards/c/CombineChrysalis.java index de5ee3dba89..979f146e16b 100644 --- a/Mage.Sets/src/mage/cards/c/CombineChrysalis.java +++ b/Mage.Sets/src/mage/cards/c/CombineChrysalis.java @@ -45,7 +45,7 @@ public final class CombineChrysalis extends CardImpl { new CreateTokenEffect(new BeastToken2()), new ManaCostsImpl<>("{2}{G}{U}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ConsecratedByBlood.java b/Mage.Sets/src/mage/cards/c/ConsecratedByBlood.java index 24d48b93d7d..b057de08be8 100644 --- a/Mage.Sets/src/mage/cards/c/ConsecratedByBlood.java +++ b/Mage.Sets/src/mage/cards/c/ConsecratedByBlood.java @@ -51,7 +51,7 @@ public final class ConsecratedByBlood extends CardImpl { effect.setText("and has flying"); ability.addEffect(effect); effect = new GainAbilityAttachedEffect(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, true))), AttachmentType.AURA); + new SacrificeTargetCost(2, filter)), AttachmentType.AURA); effect.setText("and \"Sacrifice two other creatures: Regenerate this creature.\""); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/c/ConstantMists.java b/Mage.Sets/src/mage/cards/c/ConstantMists.java index def533f40cf..471399803ea 100644 --- a/Mage.Sets/src/mage/cards/c/ConstantMists.java +++ b/Mage.Sets/src/mage/cards/c/ConstantMists.java @@ -9,6 +9,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -22,7 +23,7 @@ public final class ConstantMists extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); // Buyback-Sacrifice a land. - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + this.addAbility(new BuybackAbility(new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // Prevent all combat damage that would be dealt this turn. this.getSpellAbility().addEffect(new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true)); @@ -36,4 +37,4 @@ public final class ConstantMists extends CardImpl { public ConstantMists copy() { return new ConstantMists(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/c/ConsumingVapors.java b/Mage.Sets/src/mage/cards/c/ConsumingVapors.java index 2f1c393e641..493147d1f07 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumingVapors.java +++ b/Mage.Sets/src/mage/cards/c/ConsumingVapors.java @@ -9,12 +9,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -59,10 +61,7 @@ class ConsumingVaporsEffect extends OneShotEffect { Player player = game.getPlayer(source.getTargets().getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - FilterControlledPermanent filter = new FilterControlledPermanent("creature"); - filter.add(CardType.CREATURE.getPredicate()); - filter.add(TargetController.YOU.getControllerPredicate()); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (player != null && target.canChoose(player.getId(), source, game)) { player.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/c/CoralReef.java b/Mage.Sets/src/mage/cards/c/CoralReef.java index 4a0d1b0b704..02f39c91d02 100644 --- a/Mage.Sets/src/mage/cards/c/CoralReef.java +++ b/Mage.Sets/src/mage/cards/c/CoralReef.java @@ -54,7 +54,7 @@ public final class CoralReef extends CardImpl { effect = new AddCountersSourceEffect(CounterType.POLYP.createInstance(2), true); effect.setText("Put two polyp counters on {this}"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, - new SacrificeTargetCost(new TargetControlledPermanent(islandFilter)))); + new SacrificeTargetCost(islandFilter))); // {U}, Tap an untapped blue creature you control, Remove a polyp counter from Coral Reef: Put a +0/+1 counter on target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P0P1.createInstance()), new ManaCostsImpl<>("{U}")); diff --git a/Mage.Sets/src/mage/cards/c/CorpseBlockade.java b/Mage.Sets/src/mage/cards/c/CorpseBlockade.java index d9274afb8ea..544005e85ee 100644 --- a/Mage.Sets/src/mage/cards/c/CorpseBlockade.java +++ b/Mage.Sets/src/mage/cards/c/CorpseBlockade.java @@ -37,7 +37,7 @@ public final class CorpseBlockade extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private CorpseBlockade(final CorpseBlockade card) { diff --git a/Mage.Sets/src/mage/cards/c/CorpseCobble.java b/Mage.Sets/src/mage/cards/c/CorpseCobble.java index 91d695c606d..9988d40641b 100644 --- a/Mage.Sets/src/mage/cards/c/CorpseCobble.java +++ b/Mage.Sets/src/mage/cards/c/CorpseCobble.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.ZombieMenaceToken; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -32,7 +33,7 @@ public final class CorpseCobble extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{B}"); // As an additional cost to cast this spell, sacrifice any number of creatures. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetSacrifice(0, Integer.MAX_VALUE, filter))); // Create an X/X blue and black Zombie creature token with menace, where X is the total power of the sacrificed creatures. this.getSpellAbility().addEffect(new CorpseCobbleEffect()); diff --git a/Mage.Sets/src/mage/cards/c/CosmicLarva.java b/Mage.Sets/src/mage/cards/c/CosmicLarva.java index 07c7fe654b9..e0ee63261ca 100644 --- a/Mage.Sets/src/mage/cards/c/CosmicLarva.java +++ b/Mage.Sets/src/mage/cards/c/CosmicLarva.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -31,7 +32,8 @@ public final class CosmicLarva extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); // At the beginning of your upkeep, sacrifice Cosmic Larva unless you sacrifice two lands. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true))), TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect( + new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS)), TargetController.YOU, false)); } private CosmicLarva(final CosmicLarva card) { diff --git a/Mage.Sets/src/mage/cards/c/Crash.java b/Mage.Sets/src/mage/cards/c/Crash.java index e65da637fbc..e2d07e0e89a 100644 --- a/Mage.Sets/src/mage/cards/c/Crash.java +++ b/Mage.Sets/src/mage/cards/c/Crash.java @@ -34,7 +34,7 @@ public final class Crash extends CardImpl { // You may sacrifice a Mountain rather than pay Crash's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, alternativeCostFilter, true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(alternativeCostFilter))); // Destroy target artifact. this.getSpellAbility().addEffect(new DestroyTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/c/CropRotation.java b/Mage.Sets/src/mage/cards/c/CropRotation.java index 1c5fb4f9756..4c738ab8ab8 100644 --- a/Mage.Sets/src/mage/cards/c/CropRotation.java +++ b/Mage.Sets/src/mage/cards/c/CropRotation.java @@ -23,7 +23,7 @@ public final class CropRotation extends CardImpl { // As an additional cost to cast Crop Rotation, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); // Search your library for a land card and put that card onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterLandCard()), false, true)); diff --git a/Mage.Sets/src/mage/cards/c/CruelReality.java b/Mage.Sets/src/mage/cards/c/CruelReality.java index 8e65acd2d2f..9a7fa48fb40 100644 --- a/Mage.Sets/src/mage/cards/c/CruelReality.java +++ b/Mage.Sets/src/mage/cards/c/CruelReality.java @@ -19,6 +19,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -84,8 +85,7 @@ class CruelRealityEffect extends OneShotEffect { if (cursedPlayer == null || controller == null) { return false; } - TargetPermanent target = new TargetPermanent(filter); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(filter); if (target.canChoose(cursedPlayer.getId(), source, game) && cursedPlayer.choose(Outcome.Sacrifice, target, source, game)) { Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/c/CryptLurker.java b/Mage.Sets/src/mage/cards/c/CryptLurker.java index 903b417678a..ddf646ed027 100644 --- a/Mage.Sets/src/mage/cards/c/CryptLurker.java +++ b/Mage.Sets/src/mage/cards/c/CryptLurker.java @@ -33,9 +33,7 @@ public final class CryptLurker extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( new DrawCardSourceControllerEffect(1), new OrCost( - "sacrifice a creature or discard a creature card", new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )), new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)) + "sacrifice a creature or discard a creature card", new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)) ) ))); } diff --git a/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java b/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java index 01db1122e48..62187d16bc9 100644 --- a/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java +++ b/Mage.Sets/src/mage/cards/c/CurseOfTheCabal.java @@ -25,6 +25,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.Objects; import java.util.UUID; @@ -84,7 +85,7 @@ class CurseOfTheCabalSacrificeEffect extends OneShotEffect { if (amount < 1) { return true; } - Target target = new TargetControlledPermanent(amount, amount, StaticFilters.FILTER_CONTROLLED_PERMANENT, true); + Target target = new TargetSacrifice(amount, StaticFilters.FILTER_CONTROLLED_PERMANENT); if (target.canChoose(targetPlayer.getId(), source, game)) { while (!target.isChosen() && target.canChoose(targetPlayer.getId(), source, game) && targetPlayer.canRespond()) { @@ -138,7 +139,7 @@ class CurseOfTheCabalTriggeredAbilityConditionalDelay extends AddCountersSourceE public boolean apply(Game game, Ability source) { UUID activePlayerId = game.getActivePlayerId(); Player target = game.getPlayer(activePlayerId); - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledPermanent())); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT); if (target == null) { return false; } diff --git a/Mage.Sets/src/mage/cards/c/CustodyBattle.java b/Mage.Sets/src/mage/cards/c/CustodyBattle.java index 43b9715fb50..3faf5459de7 100644 --- a/Mage.Sets/src/mage/cards/c/CustodyBattle.java +++ b/Mage.Sets/src/mage/cards/c/CustodyBattle.java @@ -58,7 +58,7 @@ public final class CustodyBattle extends CardImpl { this.addAbility(ability); // Enchanted creature has "At the beginning of your upkeep, target opponent gains control of this creature unless you sacrifice a land." - ability = new BeginningOfUpkeepTriggeredAbility(new CustodyBattleUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))), TargetController.YOU, false); + ability = new BeginningOfUpkeepTriggeredAbility(new CustodyBattleUnlessPaysEffect(new SacrificeTargetCost(filter)), TargetController.YOU, false); ability.addTarget(new TargetOpponent()); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.AURA))); diff --git a/Mage.Sets/src/mage/cards/d/DampingEngine.java b/Mage.Sets/src/mage/cards/d/DampingEngine.java index 390008e1067..d298afd4fd0 100644 --- a/Mage.Sets/src/mage/cards/d/DampingEngine.java +++ b/Mage.Sets/src/mage/cards/d/DampingEngine.java @@ -12,12 +12,12 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Controllable; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetControlledPermanent; import java.util.Map; import java.util.Objects; @@ -144,7 +144,7 @@ class DampingEngineSpecialAction extends SpecialAction { DampingEngineSpecialAction() { super(Zone.BATTLEFIELD); - this.addCost(new SacrificeTargetCost(new TargetControlledPermanent(), true)); + this.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT)); this.addEffect(new DampingEngineIgnoreEffect()); this.setMayActivate(TargetController.ANY); this.setRuleVisible(false); diff --git a/Mage.Sets/src/mage/cards/d/DanseMacabre.java b/Mage.Sets/src/mage/cards/d/DanseMacabre.java index 18febb8800d..b84c31e6881 100644 --- a/Mage.Sets/src/mage/cards/d/DanseMacabre.java +++ b/Mage.Sets/src/mage/cards/d/DanseMacabre.java @@ -21,6 +21,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetSacrifice; import java.util.UUID; import java.util.stream.Collectors; @@ -85,8 +86,7 @@ class DanseMacabreEffect extends OneShotEffect { ) < 1) { continue; } - TargetPermanent target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null) { diff --git a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java index f345c12cb86..ba6e0a0299a 100644 --- a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java +++ b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java @@ -39,9 +39,7 @@ public final class DarettiIngeniousIconoclast extends CardImpl { Ability ability = new LoyaltyAbility( new DoIfCostPaid( new DestroyTargetEffect(), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN - )) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) ), -1 ); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE).withChooseHint("to destroy")); diff --git a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java index a5023748889..5be72ec05d2 100644 --- a/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java +++ b/Mage.Sets/src/mage/cards/d/DarkDwellerOracle.java @@ -34,9 +34,7 @@ public final class DarkDwellerOracle extends CardImpl { .setText("exile the top card of your library. You may play that card this turn"), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DarkHeartOfTheWood.java b/Mage.Sets/src/mage/cards/d/DarkHeartOfTheWood.java index dd12fc04c20..09442d42c6d 100644 --- a/Mage.Sets/src/mage/cards/d/DarkHeartOfTheWood.java +++ b/Mage.Sets/src/mage/cards/d/DarkHeartOfTheWood.java @@ -30,7 +30,7 @@ public final class DarkHeartOfTheWood extends CardImpl { // Sacrifice a Forest: You gain 3 life. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(3), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(3), new SacrificeTargetCost(filter))); } private DarkHeartOfTheWood(final DarkHeartOfTheWood card) { diff --git a/Mage.Sets/src/mage/cards/d/DarkIntimations.java b/Mage.Sets/src/mage/cards/d/DarkIntimations.java index 886c224f3f2..5d69892a83b 100644 --- a/Mage.Sets/src/mage/cards/d/DarkIntimations.java +++ b/Mage.Sets/src/mage/cards/d/DarkIntimations.java @@ -23,6 +23,7 @@ import mage.game.stack.Spell; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.ArrayList; @@ -99,13 +100,12 @@ class DarkIntimationsEffect extends OneShotEffect { return false; } List perms = new ArrayList<>(); - filter.add(TargetController.YOU.getControllerPredicate()); for (UUID playerId : game.getOpponents(source.getControllerId())) { Player player = game.getPlayer(playerId); if (player != null) { - TargetPermanent target = new TargetPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(filter); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } diff --git a/Mage.Sets/src/mage/cards/d/DarkSupplicant.java b/Mage.Sets/src/mage/cards/d/DarkSupplicant.java index cd40dca3fa1..e88ea9d9d0c 100644 --- a/Mage.Sets/src/mage/cards/d/DarkSupplicant.java +++ b/Mage.Sets/src/mage/cards/d/DarkSupplicant.java @@ -43,7 +43,7 @@ public final class DarkSupplicant extends CardImpl { // {T}, Sacrifice three Clerics: Search your graveyard, hand, and/or library for a card named Scion of Darkness and put it onto the battlefield. If you search your library this way, shuffle it. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DarkSupplicantEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, true))); + ability.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DarthTyranusCountOfSerenno.java b/Mage.Sets/src/mage/cards/d/DarthTyranusCountOfSerenno.java index 0e3f9b3a566..6f57e89a6f0 100644 --- a/Mage.Sets/src/mage/cards/d/DarthTyranusCountOfSerenno.java +++ b/Mage.Sets/src/mage/cards/d/DarthTyranusCountOfSerenno.java @@ -17,6 +17,7 @@ import mage.constants.SuperType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.Game; @@ -26,6 +27,7 @@ import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -116,8 +118,8 @@ class TransmuteArtifactEffect extends SearchEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { boolean sacrifice = false; - TargetControlledPermanent targetArtifact = new TargetControlledPermanent(new FilterControlledArtifactPermanent()); - if (controller.chooseTarget(Outcome.Sacrifice, targetArtifact, source, game)) { + TargetSacrifice targetArtifact = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_ARTIFACT); + if (controller.choose(Outcome.Sacrifice, targetArtifact, source, game)) { Permanent permanent = game.getPermanent(targetArtifact.getFirstTarget()); if (permanent != null) { sacrifice = permanent.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/d/Deadapult.java b/Mage.Sets/src/mage/cards/d/Deadapult.java index 4ab59f45374..a084eb53a1e 100644 --- a/Mage.Sets/src/mage/cards/d/Deadapult.java +++ b/Mage.Sets/src/mage/cards/d/Deadapult.java @@ -34,7 +34,7 @@ public final class Deadapult extends CardImpl { // {R}, Sacrifice a Zombie: Deadapult deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DeathBomb.java b/Mage.Sets/src/mage/cards/d/DeathBomb.java index a4245cea51c..39a7f0abfd9 100644 --- a/Mage.Sets/src/mage/cards/d/DeathBomb.java +++ b/Mage.Sets/src/mage/cards/d/DeathBomb.java @@ -21,7 +21,7 @@ public final class DeathBomb extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{B}"); // As an additional cost to cast Death Bomb, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Destroy target nonblack creature. It can't be regenerated. Its controller loses 2 life. this.getSpellAbility().addEffect(new DestroyTargetEffect(true)); this.getSpellAbility().addEffect(new LoseLifeTargetControllerEffect(2)); diff --git a/Mage.Sets/src/mage/cards/d/DeathlessBehemoth.java b/Mage.Sets/src/mage/cards/d/DeathlessBehemoth.java index 82432bbcc87..c042e6ebbaa 100644 --- a/Mage.Sets/src/mage/cards/d/DeathlessBehemoth.java +++ b/Mage.Sets/src/mage/cards/d/DeathlessBehemoth.java @@ -12,6 +12,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -39,7 +40,7 @@ public final class DeathlessBehemoth extends CardImpl { // Sacrifice two Eldrazi Scions: Return Deathless Behemoth from your graveyard to your hand. Activate this ability only any time you could cast a sorcery. this.addAbility(new ActivateAsSorceryActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) )); } diff --git a/Mage.Sets/src/mage/cards/d/DeathmarkPrelate.java b/Mage.Sets/src/mage/cards/d/DeathmarkPrelate.java index e05531bfe8e..794f8afcd02 100644 --- a/Mage.Sets/src/mage/cards/d/DeathmarkPrelate.java +++ b/Mage.Sets/src/mage/cards/d/DeathmarkPrelate.java @@ -45,7 +45,7 @@ public final class DeathmarkPrelate extends CardImpl { // {2}{B}, {tap}, Sacrifice a Zombie: Destroy target non-Zombie creature. It can't be regenerated. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new ManaCostsImpl<>("{2}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter1))); + ability.addCost(new SacrificeTargetCost(filter1)); ability.addTarget(new TargetCreaturePermanent(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DeathsporeThallid.java b/Mage.Sets/src/mage/cards/d/DeathsporeThallid.java index 68330efa164..26602153cf5 100644 --- a/Mage.Sets/src/mage/cards/d/DeathsporeThallid.java +++ b/Mage.Sets/src/mage/cards/d/DeathsporeThallid.java @@ -47,7 +47,7 @@ public final class DeathsporeThallid extends CardImpl { // Sacrifice a Saproling: Target creature gets -1/-1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-1,-1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, false))); + new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DefilerOfSouls.java b/Mage.Sets/src/mage/cards/d/DefilerOfSouls.java index 07687af44da..ecf6f096ad3 100644 --- a/Mage.Sets/src/mage/cards/d/DefilerOfSouls.java +++ b/Mage.Sets/src/mage/cards/d/DefilerOfSouls.java @@ -1,26 +1,19 @@ - package mage.cards.d; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.MonocoloredPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; /** * @@ -28,12 +21,15 @@ import mage.target.common.TargetControlledPermanent; */ public final class DefilerOfSouls extends CardImpl { + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("monocolored creature"); + static { + filter.add(MonocoloredPredicate.instance); + } + public DefilerOfSouls(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}{R}"); this.subtype.add(SubType.DEMON); - - this.power = new MageInt(5); this.toughness = new MageInt(5); @@ -41,7 +37,8 @@ public final class DefilerOfSouls extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // At the beginning of each player's upkeep, that player sacrifices a monocolored creature. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DefilerOfSoulsEffect(), TargetController.ANY, false, true)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, + new SacrificeEffect(filter, 1, "that player"), TargetController.ANY, false)); } private DefilerOfSouls(final DefilerOfSouls card) { @@ -53,57 +50,3 @@ public final class DefilerOfSouls extends CardImpl { return new DefilerOfSouls(this); } } - -class DefilerOfSoulsEffect extends OneShotEffect { - - DefilerOfSoulsEffect() { - super(Outcome.Sacrifice); - staticText = "that player sacrifices a monocolored creature"; - } - - private DefilerOfSoulsEffect(final DefilerOfSoulsEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("monocolored creature"); - Player player = game.getPlayer(targetPointer.getFirst(game, source)); - if (player == null) { - return false; - } - filter.add(MonocoloredPredicate.instance); - - int amount; - int realCount = game.getBattlefield().countAll(filter, player.getId(), game); - amount = Math.min(1, realCount); - - Target target = new TargetControlledPermanent(amount, amount, filter, false); - target.withNotTarget(true); - - //A spell or ability could have removed the only legal target this player - //had, if thats the case this ability should fizzle. - if (amount > 0 && target.canChoose(player.getId(), source, game)) { - boolean abilityApplied = false; - while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) { - player.choose(Outcome.Sacrifice, target, source, game); - } - - for ( int idx = 0; idx < target.getTargets().size(); idx++) { - Permanent permanent = game.getPermanent(target.getTargets().get(idx)); - - if ( permanent != null ) { - abilityApplied |= permanent.sacrifice(source, game); - } - } - - return abilityApplied; - } - return false; - } - - @Override - public DefilerOfSoulsEffect copy() { - return new DefilerOfSoulsEffect(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/d/Delraich.java b/Mage.Sets/src/mage/cards/d/Delraich.java index 701576cf6d2..a4be32b47ac 100644 --- a/Mage.Sets/src/mage/cards/d/Delraich.java +++ b/Mage.Sets/src/mage/cards/d/Delraich.java @@ -36,9 +36,7 @@ public final class Delraich extends CardImpl { this.toughness = new MageInt(6); // You may sacrifice three black creatures rather than pay Delraich's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost( - new TargetControlledPermanent(3, 3, filter, false) - ))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(3, filter))); // Trample this.addAbility(TrampleAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/d/DemandingDragon.java b/Mage.Sets/src/mage/cards/d/DemandingDragon.java index 3a7bfb787f0..4b6dc5fd717 100644 --- a/Mage.Sets/src/mage/cards/d/DemandingDragon.java +++ b/Mage.Sets/src/mage/cards/d/DemandingDragon.java @@ -35,9 +35,7 @@ public final class DemandingDragon extends CardImpl { // When Demanding Dragon enters the battlefield, it deals 5 damage to target opponent unless that player sacrifices a creature. Ability ability = new EntersBattlefieldTriggeredAbility(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect( new DamageTargetEffect(5), - new SacrificeTargetCost(new TargetControlledCreaturePermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) ).setText("it deals 5 damage to target opponent unless that player sacrifices a creature")); ability.addTarget(new TargetOpponent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/d/DemonOfDeathsGate.java b/Mage.Sets/src/mage/cards/d/DemonOfDeathsGate.java index 9f9bdb4410b..a17669f5b01 100644 --- a/Mage.Sets/src/mage/cards/d/DemonOfDeathsGate.java +++ b/Mage.Sets/src/mage/cards/d/DemonOfDeathsGate.java @@ -39,7 +39,7 @@ public final class DemonOfDeathsGate extends CardImpl { // You may pay 6 life and sacrifice three black creatures rather than pay Demon of Death's Gate's mana cost AlternativeCostSourceAbility alternateCosts = new AlternativeCostSourceAbility(new PayLifeCost(6)); - alternateCosts.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter))); + alternateCosts.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(alternateCosts); this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/d/DemonlordOfAshmouth.java b/Mage.Sets/src/mage/cards/d/DemonlordOfAshmouth.java index 25d77f149cd..7178bdc667a 100644 --- a/Mage.Sets/src/mage/cards/d/DemonlordOfAshmouth.java +++ b/Mage.Sets/src/mage/cards/d/DemonlordOfAshmouth.java @@ -32,7 +32,7 @@ public final class DemonlordOfAshmouth extends CardImpl { // When Demonlord of Ashmouth enters the battlefield, exile it unless you sacrifice another creature. this.addAbility(new EntersBattlefieldTriggeredAbility( new ExileSourceUnlessPaysEffect( - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ) )); diff --git a/Mage.Sets/src/mage/cards/d/DemonsHerald.java b/Mage.Sets/src/mage/cards/d/DemonsHerald.java index bb916615602..39ae1823d24 100644 --- a/Mage.Sets/src/mage/cards/d/DemonsHerald.java +++ b/Mage.Sets/src/mage/cards/d/DemonsHerald.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetControlledCreatureEachColor; +import mage.target.common.TargetSacrificeCreatureEachColor; import java.util.UUID; @@ -43,7 +43,7 @@ public final class DemonsHerald extends CardImpl { new TargetCardInLibrary(filter)), new ManaCostsImpl<>("{2}{B}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreatureEachColor("UBR"))); + ability.addCost(new SacrificeTargetCost(new TargetSacrificeCreatureEachColor("UBR"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DerangedOutcast.java b/Mage.Sets/src/mage/cards/d/DerangedOutcast.java index aad6014c367..aa28c728d1d 100644 --- a/Mage.Sets/src/mage/cards/d/DerangedOutcast.java +++ b/Mage.Sets/src/mage/cards/d/DerangedOutcast.java @@ -36,7 +36,7 @@ public final class DerangedOutcast extends CardImpl { // {1}{G}, Sacrifice a Human: Put two +1/+1 counters on target creature. Ability ability = new SimpleActivatedAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent().withChooseHint("two +1/+1 counters")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DescendantsFury.java b/Mage.Sets/src/mage/cards/d/DescendantsFury.java index b2442d0845e..108cbf3295c 100644 --- a/Mage.Sets/src/mage/cards/d/DescendantsFury.java +++ b/Mage.Sets/src/mage/cards/d/DescendantsFury.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.TargetPointer; import mage.watchers.common.DamagedPlayerThisCombatWatcher; @@ -88,7 +89,7 @@ class DescendantsFurySacrificeCost extends CostImpl implements SacrificeCost { filter.add(new PermanentReferenceInCollectionPredicate( watcher.getPermanents(controller.getId(), damagedPlayer.getId()))); - TargetControlledPermanent target = new TargetControlledPermanent(0, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(0, 1, filter); if (!controller.choose(Outcome.Sacrifice, target, source, game)) { return false; @@ -176,4 +177,4 @@ class DescendantsFuryEffect extends OneShotEffect { controller.putCardsOnBottomOfLibrary(otherCards, game, source, false); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/Desolation.java b/Mage.Sets/src/mage/cards/d/Desolation.java index 274deadc4ab..6b2f1e77707 100644 --- a/Mage.Sets/src/mage/cards/d/Desolation.java +++ b/Mage.Sets/src/mage/cards/d/Desolation.java @@ -14,6 +14,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.watchers.Watcher; import java.util.*; @@ -67,8 +68,7 @@ class DesolationEffect extends OneShotEffect { if (player == null) { continue; } - TargetPermanent target = new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND); if (!target.canChoose(player.getId(), source, game)) { continue; } @@ -80,10 +80,7 @@ class DesolationEffect extends OneShotEffect { } for (Permanent permanent : permanents) { Player player = game.getPlayer(permanent.getControllerId()); - if (permanent != null - && permanent.sacrifice(source, game) - && permanent.hasSubtype(SubType.PLAINS, game) - && player != null) { + if (permanent.sacrifice(source, game) && permanent.hasSubtype(SubType.PLAINS, game) && player != null) { player.damage(2, source.getSourceId(), source, game); } } diff --git a/Mage.Sets/src/mage/cards/d/DestructiveDigger.java b/Mage.Sets/src/mage/cards/d/DestructiveDigger.java index 6e8a29e1943..86f664e77c4 100644 --- a/Mage.Sets/src/mage/cards/d/DestructiveDigger.java +++ b/Mage.Sets/src/mage/cards/d/DestructiveDigger.java @@ -43,7 +43,7 @@ public final class DestructiveDigger extends CardImpl { new DrawCardSourceControllerEffect(1), new GenericManaCost(3) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DevourFlesh.java b/Mage.Sets/src/mage/cards/d/DevourFlesh.java index aa782626131..e5a64bd03b7 100644 --- a/Mage.Sets/src/mage/cards/d/DevourFlesh.java +++ b/Mage.Sets/src/mage/cards/d/DevourFlesh.java @@ -1,20 +1,21 @@ package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.TargetPlayer; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; + +import java.util.UUID; /** * @@ -62,12 +63,10 @@ class DevourFleshSacrificeEffect extends OneShotEffect { if (player == null) { return false; } - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); - int realCount = game.getBattlefield().countAll(filter, player.getId(), game); - if (realCount > 0) { - Target target = new TargetControlledPermanent(1, 1, filter, true); + if (game.getBattlefield().count(TargetSacrifice.makeFilter(StaticFilters.FILTER_PERMANENT_CREATURE), player.getId(), source, game) > 0) { + Target target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); } Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { diff --git a/Mage.Sets/src/mage/cards/d/DevouringGreed.java b/Mage.Sets/src/mage/cards/d/DevouringGreed.java index 4a7edd8e730..6052e78a85d 100644 --- a/Mage.Sets/src/mage/cards/d/DevouringGreed.java +++ b/Mage.Sets/src/mage/cards/d/DevouringGreed.java @@ -16,6 +16,7 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -35,7 +36,7 @@ public final class DevouringGreed extends CardImpl { // As an additional cost to cast Devouring Greed, you may sacrifice any number of Spirits. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetSacrifice(0, Integer.MAX_VALUE, filter))); // Target player loses 2 life plus 2 life for each Spirit sacrificed this way. You gain that much life. this.getSpellAbility().addEffect(new DevouringGreedEffect()); diff --git a/Mage.Sets/src/mage/cards/d/DevouringRage.java b/Mage.Sets/src/mage/cards/d/DevouringRage.java index 23cdd2132ed..8f70e87a377 100644 --- a/Mage.Sets/src/mage/cards/d/DevouringRage.java +++ b/Mage.Sets/src/mage/cards/d/DevouringRage.java @@ -19,6 +19,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; /** @@ -39,7 +40,7 @@ public final class DevouringRage extends CardImpl { // As an additional cost to cast Devouring Rage, you may sacrifice any number of Spirits. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetSacrifice(0, Integer.MAX_VALUE, filter))); // Target creature gets +3/+0 until end of turn. For each Spirit sacrificed this way, that creature gets an additional +3/+0 until end of turn this.getSpellAbility().addEffect(new DevouringRageEffect()); diff --git a/Mage.Sets/src/mage/cards/d/DiamondKaleidoscope.java b/Mage.Sets/src/mage/cards/d/DiamondKaleidoscope.java index 15d8a7bec30..68e5b88e799 100644 --- a/Mage.Sets/src/mage/cards/d/DiamondKaleidoscope.java +++ b/Mage.Sets/src/mage/cards/d/DiamondKaleidoscope.java @@ -41,7 +41,7 @@ public final class DiamondKaleidoscope extends CardImpl { this.addAbility(ability); // Sacrifice a Prism token: Add one mana of any color. - ability = new AnyColorManaAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)), + ability = new AnyColorManaAbility(new SacrificeTargetCost(filter), new PermanentsOnBattlefieldCount(filter), false); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/d/DinaSoulSteeper.java b/Mage.Sets/src/mage/cards/d/DinaSoulSteeper.java index 13d39391de0..4dba0eed270 100644 --- a/Mage.Sets/src/mage/cards/d/DinaSoulSteeper.java +++ b/Mage.Sets/src/mage/cards/d/DinaSoulSteeper.java @@ -43,9 +43,7 @@ public final class DinaSoulSteeper extends CardImpl { SacrificeCostCreaturesPower.instance, StaticValue.get(0), Duration.EndOfTurn ), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DireFleetWarmonger.java b/Mage.Sets/src/mage/cards/d/DireFleetWarmonger.java index ccbfe082f83..c670f29a4e2 100644 --- a/Mage.Sets/src/mage/cards/d/DireFleetWarmonger.java +++ b/Mage.Sets/src/mage/cards/d/DireFleetWarmonger.java @@ -34,7 +34,7 @@ public final class DireFleetWarmonger extends CardImpl { // At the beginning of combat on your turn, you may sacrifice another creature. If you do, Dire Fleet Warmonger gets +2/+2 and gains trample until end of turn. this.addAbility(new BeginningOfCombatTriggeredAbility(new DoIfCostPaid( new BoostSourceEffect(2, 2, Duration.EndOfTurn).setText("{this} gets +2/+2"), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ).addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) .concatBy("and").setText("gains trample until end of turn")), TargetController.YOU, false)); diff --git a/Mage.Sets/src/mage/cards/d/DispersingOrb.java b/Mage.Sets/src/mage/cards/d/DispersingOrb.java index c573d11371f..d10b0691424 100644 --- a/Mage.Sets/src/mage/cards/d/DispersingOrb.java +++ b/Mage.Sets/src/mage/cards/d/DispersingOrb.java @@ -24,7 +24,7 @@ public final class DispersingOrb extends CardImpl { // {3}{U}, Sacrifice a permanent: Return target permanent to its owner's hand. Ability ability = new SimpleActivatedAbility(new ReturnToHandTargetEffect(), new ManaCostsImpl<>("{3}{U}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_SHORT_TEXT)); ability.addTarget(new TargetPermanent().withChooseHint("return to hand")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DoomCannon.java b/Mage.Sets/src/mage/cards/d/DoomCannon.java index 7fa1f41f685..396576bad3a 100644 --- a/Mage.Sets/src/mage/cards/d/DoomCannon.java +++ b/Mage.Sets/src/mage/cards/d/DoomCannon.java @@ -37,7 +37,7 @@ public final class DoomCannon extends CardImpl { // {3}, {T}, Sacrifice a creature of the chosen type: Doom Cannon deals 3 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new DoomCannonFilter()))); + ability.addCost(new SacrificeTargetCost(new DoomCannonFilter())); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DoomForetold.java b/Mage.Sets/src/mage/cards/d/DoomForetold.java index 05d74966188..4db07ecd344 100644 --- a/Mage.Sets/src/mage/cards/d/DoomForetold.java +++ b/Mage.Sets/src/mage/cards/d/DoomForetold.java @@ -13,6 +13,7 @@ import mage.constants.Outcome; import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.CanBeSacrificedPredicate; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; @@ -20,6 +21,7 @@ import mage.game.permanent.Permanent; import mage.game.permanent.token.KnightToken; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -53,6 +55,7 @@ class DoomForetoldEffect extends OneShotEffect { static { filter.add(TokenPredicate.FALSE); + filter.add(CanBeSacrificedPredicate.instance); } private static final Effect effect1 = new CreateTokenEffect(new KnightToken()); @@ -81,11 +84,8 @@ class DoomForetoldEffect extends OneShotEffect { if (controller == null || player == null) { return false; } - FilterPermanent filter2 = filter.copy(); - filter2.add(new ControllerIdPredicate(player.getId())); - if (game.getBattlefield().contains(filter2, source, game, 1)) { - TargetPermanent target = new TargetPermanent(filter2); - target.withNotTarget(true); + if (game.getBattlefield().countAll(filter, player.getId(), game) > 0) { + TargetSacrifice target = new TargetSacrifice(filter); if (player.choose(Outcome.Sacrifice, target, source, game)) { Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null && permanent.sacrifice(source, game)) { @@ -101,4 +101,4 @@ class DoomForetoldEffect extends OneShotEffect { effect2.apply(game, source); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/Doomgape.java b/Mage.Sets/src/mage/cards/d/Doomgape.java index 954e9a91f82..7dd332713c7 100644 --- a/Mage.Sets/src/mage/cards/d/Doomgape.java +++ b/Mage.Sets/src/mage/cards/d/Doomgape.java @@ -14,11 +14,13 @@ import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -72,8 +74,7 @@ class DoomgapeEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Target target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (controller.choose(Outcome.Sacrifice, target, source, game)) { Permanent creature = game.getPermanent(target.getFirstTarget()); if (creature != null) { diff --git a/Mage.Sets/src/mage/cards/d/DownhillCharge.java b/Mage.Sets/src/mage/cards/d/DownhillCharge.java index 699f5a22675..835d052e0b9 100644 --- a/Mage.Sets/src/mage/cards/d/DownhillCharge.java +++ b/Mage.Sets/src/mage/cards/d/DownhillCharge.java @@ -32,7 +32,7 @@ public final class DownhillCharge extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}"); // You may sacrifice a Mountain rather than pay Downhill Charge's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(filter))); // Target creature gets +X/+0 until end of turn, where X is the number of Mountains you control. this.getSpellAbility().addEffect(new BoostTargetEffect(xValue, StaticValue.get(0), Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/d/DragonsHerald.java b/Mage.Sets/src/mage/cards/d/DragonsHerald.java index d93f811c5ca..019f02102f5 100644 --- a/Mage.Sets/src/mage/cards/d/DragonsHerald.java +++ b/Mage.Sets/src/mage/cards/d/DragonsHerald.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetControlledCreatureEachColor; +import mage.target.common.TargetSacrificeCreatureEachColor; import java.util.UUID; @@ -43,7 +43,7 @@ public final class DragonsHerald extends CardImpl { new TargetCardInLibrary(filter)), new ManaCostsImpl<>("{2}{R}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreatureEachColor("BRG"))); + ability.addCost(new SacrificeTargetCost(new TargetSacrificeCreatureEachColor("BRG"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DreadReturn.java b/Mage.Sets/src/mage/cards/d/DreadReturn.java index 76d8a35e5cd..7c134e01376 100644 --- a/Mage.Sets/src/mage/cards/d/DreadReturn.java +++ b/Mage.Sets/src/mage/cards/d/DreadReturn.java @@ -30,7 +30,7 @@ public final class DreadReturn extends CardImpl { this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); // Flashback-Sacrifice three creatures. - this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost(new TargetControlledPermanent(3, filter)))); + this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost(3, filter))); } private DreadReturn(final DreadReturn card) { diff --git a/Mage.Sets/src/mage/cards/d/DreadfeastDemon.java b/Mage.Sets/src/mage/cards/d/DreadfeastDemon.java index df5ee28e867..c2de57041c0 100644 --- a/Mage.Sets/src/mage/cards/d/DreadfeastDemon.java +++ b/Mage.Sets/src/mage/cards/d/DreadfeastDemon.java @@ -43,9 +43,7 @@ public final class DreadfeastDemon extends CardImpl { // At the beginning of your end step, sacrifice a non-Demon creature. If you do, create a token that's a copy of Dreadfeast Demon. this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid( new CreateTokenCopySourceEffect(), - new SacrificeTargetCost( - new TargetControlledPermanent(filter) - ), null, false + new SacrificeTargetCost(filter), null, false ), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/d/Dreadmalkin.java b/Mage.Sets/src/mage/cards/d/Dreadmalkin.java index 4045a1e34cf..24e49793d58 100644 --- a/Mage.Sets/src/mage/cards/d/Dreadmalkin.java +++ b/Mage.Sets/src/mage/cards/d/Dreadmalkin.java @@ -50,7 +50,7 @@ public final class Dreadmalkin extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{2}{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java b/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java index 02b5d727823..f427c8d1758 100644 --- a/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java +++ b/Mage.Sets/src/mage/cards/d/DreamscapeArtist.java @@ -42,7 +42,7 @@ public final class DreamscapeArtist extends CardImpl { new ManaCostsImpl<>("{2}{U}")); ability.addCost(new TapSourceCost()); ability.addCost(new DiscardCardCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DreamshaperShaman.java b/Mage.Sets/src/mage/cards/d/DreamshaperShaman.java index fc37cee90bb..364468697a7 100644 --- a/Mage.Sets/src/mage/cards/d/DreamshaperShaman.java +++ b/Mage.Sets/src/mage/cards/d/DreamshaperShaman.java @@ -47,9 +47,7 @@ public final class DreamshaperShaman extends CardImpl { ), new CompositeCost( new ManaCostsImpl<>("{2}{R}"), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND - )), "pay {2}{R} and sacrifice a nonland permanent" + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND), "pay {2}{R} and sacrifice a nonland permanent" ) ), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/d/Dreamwinder.java b/Mage.Sets/src/mage/cards/d/Dreamwinder.java index aca9a1ecb15..ae72f2ac7b8 100644 --- a/Mage.Sets/src/mage/cards/d/Dreamwinder.java +++ b/Mage.Sets/src/mage/cards/d/Dreamwinder.java @@ -41,7 +41,7 @@ public final class Dreamwinder extends CardImpl { ability.addTarget(new TargetLandPermanent().withChooseHint("becomes an Island")); FilterControlledLandPermanent filter = new FilterControlledLandPermanent("an Island"); filter.add(SubType.ISLAND.getPredicate()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DroolingGroodion.java b/Mage.Sets/src/mage/cards/d/DroolingGroodion.java index a7156962d6a..ab42edb5885 100644 --- a/Mage.Sets/src/mage/cards/d/DroolingGroodion.java +++ b/Mage.Sets/src/mage/cards/d/DroolingGroodion.java @@ -32,7 +32,7 @@ public final class DroolingGroodion extends CardImpl { // {2}{B}{G}, Sacrifice a creature: Target creature gets +2/+2 until end of turn. Another target creature gets -2/-2 until end of turn. Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(2, 2), new ManaCostsImpl<>("{2}{B}{G}")); ability.addEffect(new BoostTargetEffect(-2, -2).setTargetPointer(new SecondTargetPointer())); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); TargetCreaturePermanent target = new TargetCreaturePermanent(); target.setTargetTag(1); diff --git a/Mage.Sets/src/mage/cards/d/Drought.java b/Mage.Sets/src/mage/cards/d/Drought.java index 613e5514619..0b569976a2f 100644 --- a/Mage.Sets/src/mage/cards/d/Drought.java +++ b/Mage.Sets/src/mage/cards/d/Drought.java @@ -74,9 +74,7 @@ class DroughtAdditionalCostEffect extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { int blackSymbols = abilityToModify.getManaCosts().getMana().getBlack(); - TargetControlledPermanent target = new TargetControlledPermanent(blackSymbols, blackSymbols, filter, true); - target.setRequired(false); - abilityToModify.addCost(new SacrificeTargetCost(target)); + abilityToModify.addCost(new SacrificeTargetCost(blackSymbols, filter)); return true; } diff --git a/Mage.Sets/src/mage/cards/d/DrownerOfHope.java b/Mage.Sets/src/mage/cards/d/DrownerOfHope.java index dddd7988322..d7b00e0c2c2 100644 --- a/Mage.Sets/src/mage/cards/d/DrownerOfHope.java +++ b/Mage.Sets/src/mage/cards/d/DrownerOfHope.java @@ -19,7 +19,6 @@ import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.game.permanent.token.EldraziScionToken; -import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; /** @@ -28,10 +27,10 @@ import mage.target.common.TargetCreaturePermanent; */ public final class DrownerOfHope extends CardImpl { - private static final FilterControlledPermanent FILTER = new FilterControlledPermanent("an Eldrazi Scion"); + private static final FilterControlledPermanent filter = new FilterControlledPermanent("an Eldrazi Scion"); static { - FILTER.add(Predicates.and( + filter.add(Predicates.and( SubType.ELDRAZI.getPredicate(), SubType.SCION.getPredicate())); } @@ -51,7 +50,7 @@ public final class DrownerOfHope extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false)); // Sacrifice an Eldrazi Scion: Tap target creature. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new SacrificeTargetCost(new TargetControlledPermanent(FILTER))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TapTargetEffect(), new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DuskRoseReliquary.java b/Mage.Sets/src/mage/cards/d/DuskRoseReliquary.java index ac723ca1005..6bbdf1dd67f 100644 --- a/Mage.Sets/src/mage/cards/d/DuskRoseReliquary.java +++ b/Mage.Sets/src/mage/cards/d/DuskRoseReliquary.java @@ -24,7 +24,7 @@ public final class DuskRoseReliquary extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{W}"); // As an additional cost to cast this spell, sacrifice an artifact or creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ARTIFACT_OR_CREATURE_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ARTIFACT_OR_CREATURE_SHORT_TEXT)); // Ward {2} this.addAbility(new WardAbility(new ManaCostsImpl<>("{2}"), false)); diff --git a/Mage.Sets/src/mage/cards/d/DustBowl.java b/Mage.Sets/src/mage/cards/d/DustBowl.java index 41497447255..770281467b0 100644 --- a/Mage.Sets/src/mage/cards/d/DustBowl.java +++ b/Mage.Sets/src/mage/cards/d/DustBowl.java @@ -11,6 +11,7 @@ import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetNonBasicLandPermanent; @@ -29,7 +30,7 @@ public final class DustBowl extends CardImpl { // {3}, {tap}, Sacrifice a land: Destroy target nonbasic land. Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetNonBasicLandPermanent().withChooseHint("to destroy")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DutifulGriffin.java b/Mage.Sets/src/mage/cards/d/DutifulGriffin.java index 1bcf9e5688a..dabfeda17aa 100644 --- a/Mage.Sets/src/mage/cards/d/DutifulGriffin.java +++ b/Mage.Sets/src/mage/cards/d/DutifulGriffin.java @@ -15,6 +15,7 @@ import mage.constants.Zone; import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -39,7 +40,7 @@ public final class DutifulGriffin extends CardImpl { Ability ability = new SimpleActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ManaCostsImpl<>("{2}{W}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DwarvenArmory.java b/Mage.Sets/src/mage/cards/d/DwarvenArmory.java index 1bba750ede4..028deab9dcb 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenArmory.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenArmory.java @@ -33,7 +33,7 @@ public final class DwarvenArmory extends CardImpl { new ManaCostsImpl<>("{2}"), new IsStepCondition(PhaseStep.UPKEEP, false), null); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java b/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java index 37cc9010cf1..02772ea7868 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenLandslide.java @@ -13,6 +13,7 @@ import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; @@ -31,7 +32,7 @@ public final class DwarvenLandslide extends CardImpl { // Kicker-{2}{R}, Sacrifice a land. Costs kickerCosts = new CostsImpl<>(); kickerCosts.add(new ManaCostsImpl<>("{2}{R}")); - kickerCosts.add(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + kickerCosts.add(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(new KickerAbility(kickerCosts)); // Destroy target land. If Dwarven Landslide was kicked, destroy another target land. diff --git a/Mage.Sets/src/mage/cards/d/DwarvenWeaponsmith.java b/Mage.Sets/src/mage/cards/d/DwarvenWeaponsmith.java index d3040352ba2..c511bc5951b 100644 --- a/Mage.Sets/src/mage/cards/d/DwarvenWeaponsmith.java +++ b/Mage.Sets/src/mage/cards/d/DwarvenWeaponsmith.java @@ -16,6 +16,7 @@ import mage.constants.SubType; import mage.constants.PhaseStep; import mage.constants.Zone; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; @@ -36,7 +37,7 @@ public final class DwarvenWeaponsmith extends CardImpl { // {tap}, Sacrifice an artifact: Put a +1/+1 counter on target creature. Activate this ability only during your upkeep. Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TapSourceCost(), new IsStepCondition(PhaseStep.UPKEEP)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/Earthblighter.java b/Mage.Sets/src/mage/cards/e/Earthblighter.java index 1ae466c0623..3eefed4ec21 100644 --- a/Mage.Sets/src/mage/cards/e/Earthblighter.java +++ b/Mage.Sets/src/mage/cards/e/Earthblighter.java @@ -39,7 +39,7 @@ public final class Earthblighter extends CardImpl { // {2}{B}, {tap}, Sacrifice a Goblin: Destroy target land. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl<>("{2}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EatenAlive.java b/Mage.Sets/src/mage/cards/e/EatenAlive.java index 36b0cee0670..070b39550d6 100644 --- a/Mage.Sets/src/mage/cards/e/EatenAlive.java +++ b/Mage.Sets/src/mage/cards/e/EatenAlive.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -22,7 +23,7 @@ public final class EatenAlive extends CardImpl { // As an additional cost to cast this spell, sacrifice a creature or pay {3}{B}. this.getSpellAbility().addCost(new OrCost( - "sacrifice a creature or pay {3}{B}", new SacrificeTargetCost(new TargetControlledCreaturePermanent()), + "sacrifice a creature or pay {3}{B}", new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE), new ManaCostsImpl<>("{3}{B}") )); diff --git a/Mage.Sets/src/mage/cards/e/EaterOfHope.java b/Mage.Sets/src/mage/cards/e/EaterOfHope.java index f410832f8de..8ead8f16247 100644 --- a/Mage.Sets/src/mage/cards/e/EaterOfHope.java +++ b/Mage.Sets/src/mage/cards/e/EaterOfHope.java @@ -45,12 +45,12 @@ public final class EaterOfHope extends CardImpl { // {B}, Sacrifice another creature: Regenerate Eater of Hope. Ability regenAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl<>("{B}")); - regenAbility.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true))); + regenAbility.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(regenAbility); // {2}{B}, Sacrifice two other creatures: Destroy target creature. Ability destroyAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl<>("{2}{B}")); - destroyAbility.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, destroyFilter, true))); + destroyAbility.addCost(new SacrificeTargetCost(2, destroyFilter)); destroyAbility.addTarget(new TargetCreaturePermanent()); this.addAbility(destroyAbility); } diff --git a/Mage.Sets/src/mage/cards/e/EcstaticAwakener.java b/Mage.Sets/src/mage/cards/e/EcstaticAwakener.java index 200f79689a2..6002799d4a1 100644 --- a/Mage.Sets/src/mage/cards/e/EcstaticAwakener.java +++ b/Mage.Sets/src/mage/cards/e/EcstaticAwakener.java @@ -38,7 +38,7 @@ public final class EcstaticAwakener extends CardImpl { Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{2}{B}") ); ability.addEffect(new TransformSourceEffect().concatBy(", then")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java b/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java index 6770ba3e97a..9333c191fdd 100644 --- a/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java +++ b/Mage.Sets/src/mage/cards/e/EdgeOfAutumn.java @@ -35,7 +35,7 @@ public final class EdgeOfAutumn extends CardImpl { "If you control four or fewer lands, search your library for a basic land card, put it onto the battlefield tapped, then shuffle.")); // Cycling-Sacrifice a land. - this.addAbility(new CyclingAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new CyclingAbility(new SacrificeTargetCost(filter))); } private EdgeOfAutumn(final EdgeOfAutumn card) { diff --git a/Mage.Sets/src/mage/cards/e/ElderSpawn.java b/Mage.Sets/src/mage/cards/e/ElderSpawn.java index 635a55970bd..4a01392d299 100644 --- a/Mage.Sets/src/mage/cards/e/ElderSpawn.java +++ b/Mage.Sets/src/mage/cards/e/ElderSpawn.java @@ -82,8 +82,7 @@ class ElderSpawnEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - SacrificeTargetCost cost = new SacrificeTargetCost(target); + SacrificeTargetCost cost = new SacrificeTargetCost(filter); if (!controller.chooseUse(Outcome.AIDontUseIt, "Sacrifice an Island?", source, game) || !cost.canPay(source, source, source.getControllerId(), game) || !cost.pay(source, game, source, source.getControllerId(), true)) { diff --git a/Mage.Sets/src/mage/cards/e/EldraziMonument.java b/Mage.Sets/src/mage/cards/e/EldraziMonument.java index 72c29f69cf2..27ae71d7e1c 100644 --- a/Mage.Sets/src/mage/cards/e/EldraziMonument.java +++ b/Mage.Sets/src/mage/cards/e/EldraziMonument.java @@ -44,9 +44,8 @@ public final class EldraziMonument extends CardImpl { // At the beginning of your upkeep, sacrifice a creature. If you can't, sacrifice Eldrazi Monument. this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )).setText("sacrifice a creature. If you can't, sacrifice {this}"), TargetController.YOU, false + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) + ).setText("sacrifice a creature. If you can't, sacrifice {this}"), TargetController.YOU, false )); } diff --git a/Mage.Sets/src/mage/cards/e/EldritchEvolution.java b/Mage.Sets/src/mage/cards/e/EldritchEvolution.java index 12eedc67dd7..af81f3d5b8f 100644 --- a/Mage.Sets/src/mage/cards/e/EldritchEvolution.java +++ b/Mage.Sets/src/mage/cards/e/EldritchEvolution.java @@ -33,7 +33,7 @@ public final class EldritchEvolution extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}{G}"); // As an additional cost to cast Eldritch Evolution, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Search your library for a creature card with converted mana cost X or less, where X is 2 plus the sacrificed creature's converted mana cost. // Put that card onto the battlefield, then shuffle your library. Exile Eldritch Evolution. diff --git a/Mage.Sets/src/mage/cards/e/EleshNorn.java b/Mage.Sets/src/mage/cards/e/EleshNorn.java index 601acc523b0..e1fe1dce1a4 100644 --- a/Mage.Sets/src/mage/cards/e/EleshNorn.java +++ b/Mage.Sets/src/mage/cards/e/EleshNorn.java @@ -58,7 +58,7 @@ public final class EleshNorn extends CardImpl { new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED), new ManaCostsImpl<>("{2}{W}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter))); + ability.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ElvenPalisade.java b/Mage.Sets/src/mage/cards/e/ElvenPalisade.java index a780c90632d..c73651602cc 100644 --- a/Mage.Sets/src/mage/cards/e/ElvenPalisade.java +++ b/Mage.Sets/src/mage/cards/e/ElvenPalisade.java @@ -31,7 +31,7 @@ public final class ElvenPalisade extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{G}"); // Sacrifice a Forest: Target attacking creature gets -3/-0 until end of turn. - Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-3, 0, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Ability ability = new SimpleActivatedAbility(new BoostTargetEffect(-3, 0, Duration.EndOfTurn), new SacrificeTargetCost(filter)); ability.addTarget(new TargetAttackingCreature()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ElvishFarmer.java b/Mage.Sets/src/mage/cards/e/ElvishFarmer.java index 507d29e8475..bfd0b1ff94c 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishFarmer.java +++ b/Mage.Sets/src/mage/cards/e/ElvishFarmer.java @@ -45,7 +45,7 @@ public final class ElvishFarmer extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken()), new RemoveCountersSourceCost(CounterType.SPORE.createInstance(3)))); // Sacrifice a Saproling: You gain 2 life. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), - new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false)))); + new SacrificeTargetCost(filter))); } private ElvishFarmer(final ElvishFarmer card) { diff --git a/Mage.Sets/src/mage/cards/e/ElvishReclaimer.java b/Mage.Sets/src/mage/cards/e/ElvishReclaimer.java index 9e00d777925..181f550e44b 100644 --- a/Mage.Sets/src/mage/cards/e/ElvishReclaimer.java +++ b/Mage.Sets/src/mage/cards/e/ElvishReclaimer.java @@ -50,9 +50,7 @@ public final class ElvishReclaimer extends CardImpl { new TargetCardInLibrary(StaticFilters.FILTER_CARD_LAND_A), true ), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EmbraalGearSmasher.java b/Mage.Sets/src/mage/cards/e/EmbraalGearSmasher.java index d5d9c30a1a6..0e42ef78225 100644 --- a/Mage.Sets/src/mage/cards/e/EmbraalGearSmasher.java +++ b/Mage.Sets/src/mage/cards/e/EmbraalGearSmasher.java @@ -14,6 +14,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,7 +34,7 @@ public final class EmbraalGearSmasher extends CardImpl { // {T}, Sacrifice an artifact: Embraal Gear-Smasher deals 2 damage to each opponent. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamagePlayersEffect(2, TargetController.OPPONENT), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EmptyTheLaboratory.java b/Mage.Sets/src/mage/cards/e/EmptyTheLaboratory.java index bbee1c5c643..729df9beb42 100644 --- a/Mage.Sets/src/mage/cards/e/EmptyTheLaboratory.java +++ b/Mage.Sets/src/mage/cards/e/EmptyTheLaboratory.java @@ -15,6 +15,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -80,8 +81,7 @@ class EmptyTheLaboratoryEffect extends OneShotEffect { if (toSacrifice < 1) { return false; } - TargetPermanent target = new TargetPermanent(toSacrifice, filter); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(toSacrifice, filter); player.choose(Outcome.Sacrifice, target, source, game); int sacrificed = 0; for (UUID permanentId : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/e/EmrakulsEvangel.java b/Mage.Sets/src/mage/cards/e/EmrakulsEvangel.java index 7ee60ca12f6..9c783cb7a02 100644 --- a/Mage.Sets/src/mage/cards/e/EmrakulsEvangel.java +++ b/Mage.Sets/src/mage/cards/e/EmrakulsEvangel.java @@ -24,6 +24,7 @@ import mage.game.permanent.token.EldraziHorrorToken; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -81,14 +82,12 @@ class EmrakulsEvangelCost extends CostImpl { Player player = game.getPlayer(controllerId); if (selfPermanent != null && player != null) { paid = selfPermanent.sacrifice(source, game); // sacrifice self - Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true); - player.chooseTarget(Outcome.Sacrifice, target, ability, game); + Target target = new TargetSacrifice(0, Integer.MAX_VALUE, filter); + player.choose(Outcome.Sacrifice, target, ability, game); for (UUID permanentId : target.getTargets()) { Permanent otherPermanent = game.getPermanent(permanentId); - if (otherPermanent != null) { - if (otherPermanent.sacrifice(source, game)) { - numSacrificed++; - } + if (otherPermanent != null && otherPermanent.sacrifice(source, game)) { + numSacrificed++; } } } diff --git a/Mage.Sets/src/mage/cards/e/EntrapmentManeuver.java b/Mage.Sets/src/mage/cards/e/EntrapmentManeuver.java index 0584b48634f..b76845c27b0 100644 --- a/Mage.Sets/src/mage/cards/e/EntrapmentManeuver.java +++ b/Mage.Sets/src/mage/cards/e/EntrapmentManeuver.java @@ -1,7 +1,6 @@ package mage.cards.e; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; @@ -9,15 +8,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.SoldierToken; import mage.players.Player; import mage.target.Target; import mage.target.TargetPlayer; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; + +import java.util.UUID; /** * @@ -65,20 +65,17 @@ class EntrapmentManeuverSacrificeEffect extends OneShotEffect { if (player == null) { return false; } - FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); - filter.add(AttackingPredicate.instance); - int realCount = game.getBattlefield().countAll(filter, player.getId(), game); - if (realCount > 0) { - Target target = new TargetControlledPermanent(1, 1, filter, true); + if (game.getBattlefield().count(TargetSacrifice.makeFilter(StaticFilters.FILTER_ATTACKING_CREATURE), player.getId(), source, game) > 0) { + Target target = new TargetSacrifice(StaticFilters.FILTER_ATTACKING_CREATURE); while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); } Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { int amount = permanent.getToughness().getValue(); permanent.sacrifice(source, game); new CreateTokenEffect(new SoldierToken(), amount).apply(game, source); - } else{ + } else { return false; } } diff --git a/Mage.Sets/src/mage/cards/e/EradicatorValkyrie.java b/Mage.Sets/src/mage/cards/e/EradicatorValkyrie.java index 25529e6cb1a..32e941355eb 100644 --- a/Mage.Sets/src/mage/cards/e/EradicatorValkyrie.java +++ b/Mage.Sets/src/mage/cards/e/EradicatorValkyrie.java @@ -44,7 +44,7 @@ public final class EradicatorValkyrie extends CardImpl { Ability ability = new BoastAbility(new SacrificeOpponentsEffect( StaticFilters.FILTER_PERMANENT_CREATURE_OR_PLANESWALKER ), "{1}{B}"); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java b/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java index 6a570ab1cf8..17b0fa53c94 100644 --- a/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java +++ b/Mage.Sets/src/mage/cards/e/ErebosBleakHearted.java @@ -54,9 +54,7 @@ public final class ErebosBleakHearted extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostTargetEffect(-2, -1), new ManaCostsImpl<>("{1}{B}") ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java b/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java index 9a8e054e834..0ce93a09d58 100644 --- a/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java +++ b/Mage.Sets/src/mage/cards/e/ErtaiTheCorrupted.java @@ -44,7 +44,7 @@ public final class ErtaiTheCorrupted extends CardImpl { // {U}, {tap}, Sacrifice a creature or enchantment: Counter target spell. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl<>("{U}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetSpell()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EtchingsOfTheChosen.java b/Mage.Sets/src/mage/cards/e/EtchingsOfTheChosen.java index 11db8005cdf..f0663dd74a5 100644 --- a/Mage.Sets/src/mage/cards/e/EtchingsOfTheChosen.java +++ b/Mage.Sets/src/mage/cards/e/EtchingsOfTheChosen.java @@ -56,7 +56,7 @@ public final class EtchingsOfTheChosen extends CardImpl { Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); ability.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EtheriumAstrolabe.java b/Mage.Sets/src/mage/cards/e/EtheriumAstrolabe.java index 57445e0cfd6..4da1caf4e42 100644 --- a/Mage.Sets/src/mage/cards/e/EtheriumAstrolabe.java +++ b/Mage.Sets/src/mage/cards/e/EtheriumAstrolabe.java @@ -36,7 +36,7 @@ public final class EtheriumAstrolabe extends CardImpl { // {B}, {tap}, Sacrifice an artifact: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EverythingamajigE.java b/Mage.Sets/src/mage/cards/e/EverythingamajigE.java index 55ca83ad5f8..a180756b9ba 100644 --- a/Mage.Sets/src/mage/cards/e/EverythingamajigE.java +++ b/Mage.Sets/src/mage/cards/e/EverythingamajigE.java @@ -41,11 +41,11 @@ public final class EverythingamajigE extends CardImpl { // Zuran Orb // Sacrifice a land: You gain 2 life. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); // Ashnod's Altar // Sacrifice a creature: Add {C}{C} to your mana pool. - SacrificeTargetCost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); + SacrificeTargetCost cost = new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT); this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new BasicManaEffect(Mana.ColorlessMana(2), CreaturesYouControlCount.instance), cost)); diff --git a/Mage.Sets/src/mage/cards/e/EvolvingDoor.java b/Mage.Sets/src/mage/cards/e/EvolvingDoor.java index 0d2a8ed701b..fce77bf17b5 100644 --- a/Mage.Sets/src/mage/cards/e/EvolvingDoor.java +++ b/Mage.Sets/src/mage/cards/e/EvolvingDoor.java @@ -37,7 +37,7 @@ public final class EvolvingDoor extends CardImpl { // {1}, {T}, Sacrifice a creature: Count the colors of the sacrificed creature, then search your library for a creature card that's exactly that many colors plus one. Exile that card, then shuffle. You may cast the exiled card. Activate only as a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(new EvolvingDoorEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ExaltedDragon.java b/Mage.Sets/src/mage/cards/e/ExaltedDragon.java index 76feb44122c..fea3c6f2219 100644 --- a/Mage.Sets/src/mage/cards/e/ExaltedDragon.java +++ b/Mage.Sets/src/mage/cards/e/ExaltedDragon.java @@ -15,6 +15,7 @@ import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -53,7 +54,7 @@ class ExaltedDragonCostToAttackBlockEffect extends PayCostToAttackBlockEffectImp ExaltedDragonCostToAttackBlockEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK, - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); staticText = "{this} can't attack unless you sacrifice a land. (This cost is paid as attackers are declared.)"; } diff --git a/Mage.Sets/src/mage/cards/e/ExcavatingAnurid.java b/Mage.Sets/src/mage/cards/e/ExcavatingAnurid.java index 7795e33cf82..1336cee7fe3 100644 --- a/Mage.Sets/src/mage/cards/e/ExcavatingAnurid.java +++ b/Mage.Sets/src/mage/cards/e/ExcavatingAnurid.java @@ -42,9 +42,7 @@ public final class ExcavatingAnurid extends CardImpl { // When Excavating Anurid enters the battlefield, you may sacrifice a land. If you do, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT - )) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT) ))); // Threshold — As long as seven or more cards are in your graveyard, Excavating Anurid gets +1/+1 and has vigilance. diff --git a/Mage.Sets/src/mage/cards/e/Excavation.java b/Mage.Sets/src/mage/cards/e/Excavation.java index 65da1e504fa..fa6df69590c 100644 --- a/Mage.Sets/src/mage/cards/e/Excavation.java +++ b/Mage.Sets/src/mage/cards/e/Excavation.java @@ -15,6 +15,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.players.Player; @@ -31,7 +32,7 @@ public final class Excavation extends CardImpl { // {1}, Sacrifice a land: Draw a card. Any player may activate this ability. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.setMayActivate(TargetController.ANY); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/Excavator.java b/Mage.Sets/src/mage/cards/e/Excavator.java index 018d49a22fa..c715817f6d2 100644 --- a/Mage.Sets/src/mage/cards/e/Excavator.java +++ b/Mage.Sets/src/mage/cards/e/Excavator.java @@ -37,7 +37,7 @@ public final class Excavator extends CardImpl { // {tap}, Sacrifice a basic land: Target creature gains landwalk of each of the land types of the sacrificed land until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExcavatorEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/ExtricatorOfSin.java b/Mage.Sets/src/mage/cards/e/ExtricatorOfSin.java index 16fda600999..84f1df3d590 100644 --- a/Mage.Sets/src/mage/cards/e/ExtricatorOfSin.java +++ b/Mage.Sets/src/mage/cards/e/ExtricatorOfSin.java @@ -46,7 +46,7 @@ public final class ExtricatorOfSin extends CardImpl { // When Extricator of Sin enters the battlefield, you may sacrifice another permanent. If you do, create a 3/2 colorless Eldrazi Horror creature token. this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new EldraziHorrorToken()), - new SacrificeTargetCost(new TargetControlledPermanent(filter))), false)); + new SacrificeTargetCost(filter)), false)); // Delirium — At the beginning of your upkeep, if there are four or more card types among cards in your graveyard, transform Extricator of Sin. this.addAbility(new TransformAbility()); diff --git a/Mage.Sets/src/mage/cards/e/Extruder.java b/Mage.Sets/src/mage/cards/e/Extruder.java index c75c39286a0..a4bef32a98c 100644 --- a/Mage.Sets/src/mage/cards/e/Extruder.java +++ b/Mage.Sets/src/mage/cards/e/Extruder.java @@ -38,7 +38,7 @@ public final class Extruder extends CardImpl { this.addAbility(new EchoAbility("{4}")); // Sacrifice an artifact: Put a +1/+1 counter on target creature. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/Facevaulter.java b/Mage.Sets/src/mage/cards/f/Facevaulter.java index bf912b7d635..b1b3f19eeaa 100644 --- a/Mage.Sets/src/mage/cards/f/Facevaulter.java +++ b/Mage.Sets/src/mage/cards/f/Facevaulter.java @@ -34,7 +34,7 @@ public final class Facevaulter extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FadeAway.java b/Mage.Sets/src/mage/cards/f/FadeAway.java index 937bb374bd3..c8fe2971b65 100644 --- a/Mage.Sets/src/mage/cards/f/FadeAway.java +++ b/Mage.Sets/src/mage/cards/f/FadeAway.java @@ -9,11 +9,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -78,8 +80,8 @@ class FadeAwayEffect extends OneShotEffect { if (sacrificeNumber > 0) { int permanentsNumber = game.getBattlefield().getAllActivePermanents(playerId).size(); int targetsNumber = Math.min(sacrificeNumber, permanentsNumber); - TargetControlledPermanent target = new TargetControlledPermanent(targetsNumber); - player.chooseTarget(Outcome.Sacrifice, target, source, game); + TargetSacrifice target = new TargetSacrifice(targetsNumber, targetsNumber == 1 ? StaticFilters.FILTER_PERMANENT : StaticFilters.FILTER_PERMANENTS); + player.choose(Outcome.Sacrifice, target, source, game); for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); if (permanent != null) { diff --git a/Mage.Sets/src/mage/cards/f/FainTheBroker.java b/Mage.Sets/src/mage/cards/f/FainTheBroker.java index f142c0a7907..0b36a02111c 100644 --- a/Mage.Sets/src/mage/cards/f/FainTheBroker.java +++ b/Mage.Sets/src/mage/cards/f/FainTheBroker.java @@ -44,9 +44,7 @@ public final class FainTheBroker extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), new TapSourceCost() ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -57,9 +55,7 @@ public final class FainTheBroker extends CardImpl { // {T}, Sacrifice an artifact: Create a 2/1 white and black Inkling creature token with flying. ability = new SimpleActivatedAbility(new CreateTokenEffect(new InklingToken()), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability); // {3}{B}: Untap Fain, the Broker. diff --git a/Mage.Sets/src/mage/cards/f/FaithHealer.java b/Mage.Sets/src/mage/cards/f/FaithHealer.java index 132cb1d6d82..eb2c17821ee 100644 --- a/Mage.Sets/src/mage/cards/f/FaithHealer.java +++ b/Mage.Sets/src/mage/cards/f/FaithHealer.java @@ -11,6 +11,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.target.common.TargetControlledPermanent; @@ -30,7 +31,7 @@ public final class FaithHealer extends CardImpl { // Sacrifice an enchantment: You gain life equal to the sacrificed enchantment's converted mana cost. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(SacrificeCostManaValue.ENCHANTMENT), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledEnchantmentPermanent())))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ENCHANTMENT))); } private FaithHealer(final FaithHealer card) { diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathForebear.java b/Mage.Sets/src/mage/cards/f/FalkenrathForebear.java index c42044a4ecf..97f8fa47b09 100644 --- a/Mage.Sets/src/mage/cards/f/FalkenrathForebear.java +++ b/Mage.Sets/src/mage/cards/f/FalkenrathForebear.java @@ -20,6 +20,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.BloodToken; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -52,7 +53,7 @@ public final class FalkenrathForebear extends CardImpl { // {B}, Sacrifice two Blood tokens: Return Falkenrath Forebear from your graveyard to the battlefield. Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, false), new ManaCostsImpl<>("{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FalkenrathPitFighter.java b/Mage.Sets/src/mage/cards/f/FalkenrathPitFighter.java index 48587739a13..00b329f6310 100644 --- a/Mage.Sets/src/mage/cards/f/FalkenrathPitFighter.java +++ b/Mage.Sets/src/mage/cards/f/FalkenrathPitFighter.java @@ -40,7 +40,7 @@ public final class FalkenrathPitFighter extends CardImpl { new ManaCostsImpl<>("{1}{R}"), OpponentsLostLifeCondition.instance ); ability.addCost(new DiscardCardCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability.addHint(OpponentsLostLifeHint.instance)); } diff --git a/Mage.Sets/src/mage/cards/f/FallingTimber.java b/Mage.Sets/src/mage/cards/f/FallingTimber.java index 66c03d624e0..0711041ef61 100644 --- a/Mage.Sets/src/mage/cards/f/FallingTimber.java +++ b/Mage.Sets/src/mage/cards/f/FallingTimber.java @@ -10,6 +10,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; @@ -27,8 +28,7 @@ public final class FallingTimber extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); // Kicker-Sacrifice a land. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, - new FilterControlledLandPermanent("a land"), true)))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // Prevent all combat damage target creature would deal this turn. If Falling Timber was kicked, // prevent all combat damage another target creature would deal this turn. diff --git a/Mage.Sets/src/mage/cards/f/FatalGrudge.java b/Mage.Sets/src/mage/cards/f/FatalGrudge.java index 7b4b3b05246..5dc8827932d 100644 --- a/Mage.Sets/src/mage/cards/f/FatalGrudge.java +++ b/Mage.Sets/src/mage/cards/f/FatalGrudge.java @@ -21,6 +21,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -82,8 +83,8 @@ class FatalGrudgeEffect extends OneShotEffect { for (UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); if (opponent != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - opponent.chooseTarget(Outcome.Sacrifice, target, source, game); + TargetSacrifice target = new TargetSacrifice(filter); + opponent.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { permanent.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/f/FaultRiders.java b/Mage.Sets/src/mage/cards/f/FaultRiders.java index 8ec58194fea..fdece0ddc65 100644 --- a/Mage.Sets/src/mage/cards/f/FaultRiders.java +++ b/Mage.Sets/src/mage/cards/f/FaultRiders.java @@ -16,6 +16,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -37,7 +38,7 @@ public final class FaultRiders extends CardImpl { effect.setText("{this} gets +2/+0"); Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, effect, - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); effect = new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); effect.setText("and gains first strike until end of turn"); ability.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/f/FeastOfWorms.java b/Mage.Sets/src/mage/cards/f/FeastOfWorms.java index 11799ff7c50..06f07b76567 100644 --- a/Mage.Sets/src/mage/cards/f/FeastOfWorms.java +++ b/Mage.Sets/src/mage/cards/f/FeastOfWorms.java @@ -10,6 +10,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; @@ -18,6 +19,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetLandPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -72,13 +74,10 @@ class FeastOfWormsEffect extends OneShotEffect { if (permanent != null) { targetPlayer = game.getPlayer(permanent.getControllerId()); } - if (targetPlayer != null && permanent != null && (permanent.isLegendary(game))) { - FilterControlledPermanent filter = new FilterControlledLandPermanent("land to sacrifice"); - filter.add(new ControllerIdPredicate(targetPlayer.getId())); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, false); - + if (targetPlayer != null && permanent.isLegendary(game)) { + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_LAND); if (target.canChoose(targetPlayer.getId(), source, game)) { - targetPlayer.chooseTarget(Outcome.Sacrifice, target, source, game); + targetPlayer.choose(Outcome.Sacrifice, target, source, game); Permanent land = game.getPermanent(target.getFirstTarget()); if (land != null) { land.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java b/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java index a37e9cf8810..d403879eba8 100644 --- a/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java +++ b/Mage.Sets/src/mage/cards/f/FeastingTrollKing.java @@ -56,7 +56,7 @@ public final class FeastingTrollKing extends CardImpl { this.addAbility(new ActivateIfConditionActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, false), - new SacrificeTargetCost(new TargetControlledPermanent(3, filter)), + new SacrificeTargetCost(3, filter), MyTurnCondition.instance ).addHint(MyTurnHint.instance)); } diff --git a/Mage.Sets/src/mage/cards/f/FellShepherd.java b/Mage.Sets/src/mage/cards/f/FellShepherd.java index 05e8b7bb600..7a4ecccca65 100644 --- a/Mage.Sets/src/mage/cards/f/FellShepherd.java +++ b/Mage.Sets/src/mage/cards/f/FellShepherd.java @@ -54,7 +54,7 @@ public final class FellShepherd extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl<>("{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/Ferrovore.java b/Mage.Sets/src/mage/cards/f/Ferrovore.java index 8f0fe95e382..03cc4672c9f 100644 --- a/Mage.Sets/src/mage/cards/f/Ferrovore.java +++ b/Mage.Sets/src/mage/cards/f/Ferrovore.java @@ -36,7 +36,7 @@ public final class Ferrovore extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(3, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FiendArtisan.java b/Mage.Sets/src/mage/cards/f/FiendArtisan.java index 9be419edc36..74ea4067346 100644 --- a/Mage.Sets/src/mage/cards/f/FiendArtisan.java +++ b/Mage.Sets/src/mage/cards/f/FiendArtisan.java @@ -50,7 +50,7 @@ public final class FiendArtisan extends CardImpl { Zone.BATTLEFIELD, new FiendArtisanEffect(), new ManaCostsImpl<>("{X}{B/G}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } @@ -88,4 +88,4 @@ class FiendArtisanEffect extends OneShotEffect { filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, xValue + 1)); return new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)).apply(game, source); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/FiendOfTheShadows.java b/Mage.Sets/src/mage/cards/f/FiendOfTheShadows.java index ac2b9cd96c9..9a5bf20e7e9 100644 --- a/Mage.Sets/src/mage/cards/f/FiendOfTheShadows.java +++ b/Mage.Sets/src/mage/cards/f/FiendOfTheShadows.java @@ -43,7 +43,7 @@ public final class FiendOfTheShadows extends CardImpl { this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new FiendOfTheShadowsEffect(), false, true)); // Sacrifice a Human: Regenerate Fiend of the Shadows. - this.addAbility(new SimpleActivatedAbility(new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(new RegenerateSourceEffect(), new SacrificeTargetCost(filter))); } private FiendOfTheShadows(final FiendOfTheShadows card) { diff --git a/Mage.Sets/src/mage/cards/f/FinalFlare.java b/Mage.Sets/src/mage/cards/f/FinalFlare.java index ae5632e4bc1..7471da692d3 100644 --- a/Mage.Sets/src/mage/cards/f/FinalFlare.java +++ b/Mage.Sets/src/mage/cards/f/FinalFlare.java @@ -31,7 +31,7 @@ public final class FinalFlare extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // As an additional cost to cast this spell, sacrifice a creature or enchantment. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Final Flare deals 5 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/f/FinalPayment.java b/Mage.Sets/src/mage/cards/f/FinalPayment.java index d7e7313162c..f046e19db01 100644 --- a/Mage.Sets/src/mage/cards/f/FinalPayment.java +++ b/Mage.Sets/src/mage/cards/f/FinalPayment.java @@ -31,7 +31,7 @@ public final class FinalPayment extends CardImpl { // As an additional cost to cast this spell, pay 5 life or sacrifice a creature or enchantment. final Cost lifeCost = new PayLifeCost(5); - final Cost sacrificeCost = new SacrificeTargetCost(new TargetControlledPermanent(filter)); + final Cost sacrificeCost = new SacrificeTargetCost(filter); this.getSpellAbility().addCost(new OrCost("pay 5 life or sacrifice a creature or enchantment", lifeCost, sacrificeCost )); diff --git a/Mage.Sets/src/mage/cards/f/FirebladeArtist.java b/Mage.Sets/src/mage/cards/f/FirebladeArtist.java index 5568d06ee3b..ff13aa1c1e5 100644 --- a/Mage.Sets/src/mage/cards/f/FirebladeArtist.java +++ b/Mage.Sets/src/mage/cards/f/FirebladeArtist.java @@ -41,8 +41,7 @@ public final class FirebladeArtist extends CardImpl { ); ability.addTarget(new TargetOpponentOrPlaneswalker()); this.addAbility(new BeginningOfUpkeepTriggeredAbility( - new DoWhenCostPaid(ability, new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) + new DoWhenCostPaid(ability, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT ), "Sacrifice a creature?"), TargetController.YOU, false )); } diff --git a/Mage.Sets/src/mage/cards/f/Fireblast.java b/Mage.Sets/src/mage/cards/f/Fireblast.java index 7ea4b1a95e7..91b00bdff8e 100644 --- a/Mage.Sets/src/mage/cards/f/Fireblast.java +++ b/Mage.Sets/src/mage/cards/f/Fireblast.java @@ -30,7 +30,7 @@ public final class Fireblast extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{4}{R}{R}"); // You may sacrifice two Mountains rather than pay Fireblast's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(2, filter))); // Fireblast deals 4 damage to any target. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); diff --git a/Mage.Sets/src/mage/cards/f/Flamewright.java b/Mage.Sets/src/mage/cards/f/Flamewright.java index 7053998e8e9..122cf5d70f0 100644 --- a/Mage.Sets/src/mage/cards/f/Flamewright.java +++ b/Mage.Sets/src/mage/cards/f/Flamewright.java @@ -48,7 +48,7 @@ public final class Flamewright extends CardImpl { // {tap}, Sacrifice a creature with defender: Flamewright deals 1 damage to any target. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FleshCarver.java b/Mage.Sets/src/mage/cards/f/FleshCarver.java index 161cb7fd605..e3d058b9695 100644 --- a/Mage.Sets/src/mage/cards/f/FleshCarver.java +++ b/Mage.Sets/src/mage/cards/f/FleshCarver.java @@ -46,7 +46,7 @@ public final class FleshCarver extends CardImpl { this.addAbility(IntimidateAbility.getInstance()); // {1}{B}, Sacrifice another creature: Put two +1/+1 counters on Flesh Carver. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); // When Flesh Carver dies, create an X/X black Horror creature token, where X is Flesh Carver's power. diff --git a/Mage.Sets/src/mage/cards/f/Fleshtaker.java b/Mage.Sets/src/mage/cards/f/Fleshtaker.java index 96560f84338..95aad3c24a0 100644 --- a/Mage.Sets/src/mage/cards/f/Fleshtaker.java +++ b/Mage.Sets/src/mage/cards/f/Fleshtaker.java @@ -43,9 +43,7 @@ public final class Fleshtaker extends CardImpl { ability = new SimpleActivatedAbility( new BoostSourceEffect(2, 2, Duration.EndOfTurn), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java b/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java index d2f3553b32a..347276f455c 100644 --- a/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java +++ b/Mage.Sets/src/mage/cards/f/FloodedWoodlands.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -47,7 +48,7 @@ class FloodedWoodlandsCostToAttackBlockEffect extends PayCostToAttackBlockEffect FloodedWoodlandsCostToAttackBlockEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK, - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); staticText = "Green creatures can't attack unless their controller sacrifices a land (This cost is paid as attackers are declared.)"; } diff --git a/Mage.Sets/src/mage/cards/f/FodderLaunch.java b/Mage.Sets/src/mage/cards/f/FodderLaunch.java index 211152d0598..acc11a30d8b 100644 --- a/Mage.Sets/src/mage/cards/f/FodderLaunch.java +++ b/Mage.Sets/src/mage/cards/f/FodderLaunch.java @@ -10,6 +10,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; @@ -19,12 +20,14 @@ import mage.target.common.TargetCreaturePermanent; */ public final class FodderLaunch extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent(SubType.GOBLIN, "a Goblin"); + public FodderLaunch(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.SORCERY},"{3}{B}"); this.subtype.add(SubType.GOBLIN); //As an additional cost to cast Fodder Launch, sacrifice a Goblin. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(SubType.GOBLIN, "a Goblin"), true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); //Target creature gets -5/-5 until end of turn. Fodder Launch deals 5 damage to that creature's controller. this.getSpellAbility().addEffect(new BoostTargetEffect(-5, -5, Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/f/Foratog.java b/Mage.Sets/src/mage/cards/f/Foratog.java index 0405e5be84a..7fd724421ec 100644 --- a/Mage.Sets/src/mage/cards/f/Foratog.java +++ b/Mage.Sets/src/mage/cards/f/Foratog.java @@ -36,7 +36,7 @@ public final class Foratog extends CardImpl { // {G}, Sacrifice a Forest: Foratog gets +2/+2 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/ForgeArmor.java b/Mage.Sets/src/mage/cards/f/ForgeArmor.java index c383c32f672..f0cb1177d6a 100644 --- a/Mage.Sets/src/mage/cards/f/ForgeArmor.java +++ b/Mage.Sets/src/mage/cards/f/ForgeArmor.java @@ -23,7 +23,7 @@ public final class ForgeArmor extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}"); // As an additional cost to cast Forge Armor, sacrifice an artifact. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); // Put X +1/+1 counters on target creature, where X is the sacrificed artifact's converted mana cost. this.getSpellAbility().addEffect(new AddCountersTargetEffect( CounterType.P1P1.createInstance(), SacrificeCostManaValue.ARTIFACT)); diff --git a/Mage.Sets/src/mage/cards/f/Fortitude.java b/Mage.Sets/src/mage/cards/f/Fortitude.java index a01339a8e08..92bfcf3400d 100644 --- a/Mage.Sets/src/mage/cards/f/Fortitude.java +++ b/Mage.Sets/src/mage/cards/f/Fortitude.java @@ -42,7 +42,7 @@ public final class Fortitude extends CardImpl { this.addAbility(ability); // Sacrifice a Forest: Regenerate enchanted creature. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateAttachedEffect(AttachmentType.AURA), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateAttachedEffect(AttachmentType.AURA), new SacrificeTargetCost(filter))); // When Fortitude is put into a graveyard from the battlefield, return Fortitude to its owner's hand. this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(new ReturnToHandSourceEffect())); diff --git a/Mage.Sets/src/mage/cards/f/FoundryHelix.java b/Mage.Sets/src/mage/cards/f/FoundryHelix.java index a8091b6bffd..f03060d83f2 100644 --- a/Mage.Sets/src/mage/cards/f/FoundryHelix.java +++ b/Mage.Sets/src/mage/cards/f/FoundryHelix.java @@ -27,7 +27,7 @@ public final class FoundryHelix extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}{W}"); // As an additional cost to cast this spell, sacrifice a permanent. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_SHORT_TEXT)); // Foundry Helix deals 4 damage to any target. If the sacrificed permanent was an artifact, you gain 4 life. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); diff --git a/Mage.Sets/src/mage/cards/f/FrayingOmnipotence.java b/Mage.Sets/src/mage/cards/f/FrayingOmnipotence.java index 1c0d7368b17..a7f0be4b6ae 100644 --- a/Mage.Sets/src/mage/cards/f/FrayingOmnipotence.java +++ b/Mage.Sets/src/mage/cards/f/FrayingOmnipotence.java @@ -13,6 +13,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -93,7 +94,7 @@ class FrayingOmnipotenceEffect extends OneShotEffect { if (creaturesToSacrifice == 0) { continue; } - Target target = new TargetControlledCreaturePermanent(creaturesToSacrifice, creaturesToSacrifice, filter, true); + Target target = new TargetSacrifice(creaturesToSacrifice, filter); target.chooseTarget(Outcome.Sacrifice, playerId, source, game); for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); diff --git a/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java b/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java index 92d53fad916..9dc1229a95b 100644 --- a/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java +++ b/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java @@ -44,7 +44,7 @@ public final class FreyaliseSupplicant extends CardImpl { // {tap}, Sacrifice a red or white creature: Freyalise Supplicant deals damage to any target equal to half the sacrificed creature's power, rounded down. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new HalfValue(SacrificeCostCreaturesPower.instance, false)), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/FungalPlots.java b/Mage.Sets/src/mage/cards/f/FungalPlots.java index b92edf5187e..be19aff9cfa 100644 --- a/Mage.Sets/src/mage/cards/f/FungalPlots.java +++ b/Mage.Sets/src/mage/cards/f/FungalPlots.java @@ -47,7 +47,7 @@ public final class FungalPlots extends CardImpl { SimpleActivatedAbility ability2 = new SimpleActivatedAbility( Zone.BATTLEFIELD, new GainLifeEffect(2), - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter2, false)) + new SacrificeTargetCost(2, filter2) ); ability2.addEffect(new DrawCardSourceControllerEffect(1).setText("and draw a card")); this.addAbility(ability2); diff --git a/Mage.Sets/src/mage/cards/f/FungusElemental.java b/Mage.Sets/src/mage/cards/f/FungusElemental.java index 5341c2bf809..2267ade74cc 100644 --- a/Mage.Sets/src/mage/cards/f/FungusElemental.java +++ b/Mage.Sets/src/mage/cards/f/FungusElemental.java @@ -44,7 +44,7 @@ public final class FungusElemental extends CardImpl { new ManaCostsImpl<>("{G}"), SourceEnteredThisTurnCondition.instance ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GaeasBalance.java b/Mage.Sets/src/mage/cards/g/GaeasBalance.java index 4a9939805aa..917d5378174 100644 --- a/Mage.Sets/src/mage/cards/g/GaeasBalance.java +++ b/Mage.Sets/src/mage/cards/g/GaeasBalance.java @@ -8,6 +8,7 @@ import mage.cards.*; import mage.constants.CardType; import mage.constants.SubType; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterLandCard; @@ -23,16 +24,11 @@ import java.util.UUID; */ public final class GaeasBalance extends CardImpl { - private static final FilterControlledPermanent filter - = new FilterControlledLandPermanent("lands"); - public GaeasBalance(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}"); // As an additional cost to cast Gaea's Balance, sacrifice five lands. - this.getSpellAbility().addCost(new SacrificeTargetCost( - new TargetControlledPermanent(5, filter) - )); + this.getSpellAbility().addCost(new SacrificeTargetCost(5, StaticFilters.FILTER_LANDS)); // Search your library for a land card of each basic land type and put them onto the battlefield. Then shuffle your library. String ruleText = "Search your library for a land card of each basic land type, put those cards onto the battlefield, then shuffle."; diff --git a/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java b/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java index 2f71079dc0b..bbf4627e9a4 100644 --- a/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java +++ b/Mage.Sets/src/mage/cards/g/GargantuanGorilla.java @@ -86,8 +86,7 @@ class GargantuanGorillaSacrificeEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - SacrificeTargetCost cost = new SacrificeTargetCost(target); + SacrificeTargetCost cost = new SacrificeTargetCost(1, filter); if (!controller.chooseUse(Outcome.Benefit, "Sacrifice a Forest?", source, game) || !cost.canPay(source, source, source.getControllerId(), game) || !cost.pay(source, game, source, source.getControllerId(), true)) { diff --git a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java b/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java index 4a7300c6f36..3d63d1a98e8 100644 --- a/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java +++ b/Mage.Sets/src/mage/cards/g/GarrukTheVeilCursed.java @@ -51,9 +51,7 @@ public final class GarrukTheVeilCursed extends CardImpl { StaticFilters.FILTER_CARD_CREATURE_A ), true), null, - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), false ), -1)); diff --git a/Mage.Sets/src/mage/cards/g/GathererOfGraces.java b/Mage.Sets/src/mage/cards/g/GathererOfGraces.java index 23a7ad9dc0c..7d1a1890ada 100644 --- a/Mage.Sets/src/mage/cards/g/GathererOfGraces.java +++ b/Mage.Sets/src/mage/cards/g/GathererOfGraces.java @@ -42,7 +42,7 @@ public final class GathererOfGraces extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(count, count, Duration.WhileOnBattlefield))); // Sacrifice an Aura: Regenerate Gatherer of Graces - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(filter))); } private GathererOfGraces(final GathererOfGraces gathererOfGraces) { diff --git a/Mage.Sets/src/mage/cards/g/GeneralKudroOfDrannith.java b/Mage.Sets/src/mage/cards/g/GeneralKudroOfDrannith.java index 0fc935ce81f..284f9b90cc4 100644 --- a/Mage.Sets/src/mage/cards/g/GeneralKudroOfDrannith.java +++ b/Mage.Sets/src/mage/cards/g/GeneralKudroOfDrannith.java @@ -65,7 +65,7 @@ public final class GeneralKudroOfDrannith extends CardImpl { // {2}, Sacrifice two Humans: Destroy target creature with power 4 or greater. ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter4))); + ability.addCost(new SacrificeTargetCost(2, filter4)); ability.addTarget(new TargetPermanent(filter5)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GhenArcanumWeaver.java b/Mage.Sets/src/mage/cards/g/GhenArcanumWeaver.java index a32319f9ba1..90b602c0388 100644 --- a/Mage.Sets/src/mage/cards/g/GhenArcanumWeaver.java +++ b/Mage.Sets/src/mage/cards/g/GhenArcanumWeaver.java @@ -45,7 +45,7 @@ public final class GhenArcanumWeaver extends CardImpl { new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{R}{W}{B}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCardInYourGraveyard(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java b/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java index 6f4efc0af9e..e250042e145 100644 --- a/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java +++ b/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java @@ -41,7 +41,7 @@ public final class GhoulcallerGisa extends CardImpl { effect.setText("create X 2/2 black Zombie creature tokens, where X is the sacrificed creature's power"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GiantOpportunity.java b/Mage.Sets/src/mage/cards/g/GiantOpportunity.java index 0baf6ebb8b3..7307b6291ef 100644 --- a/Mage.Sets/src/mage/cards/g/GiantOpportunity.java +++ b/Mage.Sets/src/mage/cards/g/GiantOpportunity.java @@ -11,6 +11,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.FoodToken; import mage.game.permanent.token.GiantOpportunityToken; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -28,7 +29,7 @@ public final class GiantOpportunity extends CardImpl { this.getSpellAbility().addEffect(new DoIfCostPaid( new CreateTokenEffect(new GiantOpportunityToken()), new CreateTokenEffect(new FoodToken(), 3), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) ).setText("You may sacrifice two Foods. If you do, create a 7/7 green Giant creature token. " + "Otherwise, create three Food tokens.")); } diff --git a/Mage.Sets/src/mage/cards/g/GiftOfDoom.java b/Mage.Sets/src/mage/cards/g/GiftOfDoom.java index 88cbb8d7304..521ee336c6c 100644 --- a/Mage.Sets/src/mage/cards/g/GiftOfDoom.java +++ b/Mage.Sets/src/mage/cards/g/GiftOfDoom.java @@ -54,9 +54,7 @@ public final class GiftOfDoom extends CardImpl { this.addAbility(ability2); // Morph—Sacrifice another creature. - this.addAbility(new MorphAbility(this, new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - ))); + this.addAbility(new MorphAbility(this, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); // As Gift of Doom is turned face up, you may attach it to a creature. Effect effect = new AsTurnedFaceUpEffect(new GiftOfDoomEffect(), true); diff --git a/Mage.Sets/src/mage/cards/g/GildedAssaultCart.java b/Mage.Sets/src/mage/cards/g/GildedAssaultCart.java index b0307cb9d58..530e08cdb4d 100644 --- a/Mage.Sets/src/mage/cards/g/GildedAssaultCart.java +++ b/Mage.Sets/src/mage/cards/g/GildedAssaultCart.java @@ -13,6 +13,7 @@ import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -41,7 +42,7 @@ public final class GildedAssaultCart extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) )); } diff --git a/Mage.Sets/src/mage/cards/g/GildedGoose.java b/Mage.Sets/src/mage/cards/g/GildedGoose.java index 86af432a7e1..f98d8c8c057 100644 --- a/Mage.Sets/src/mage/cards/g/GildedGoose.java +++ b/Mage.Sets/src/mage/cards/g/GildedGoose.java @@ -48,7 +48,7 @@ public final class GildedGoose extends CardImpl { // {T}, Sacrifice a Food: Add one mana of any color. ActivatedManaAbilityImpl ability1 = new AnyColorManaAbility(new TapSourceCost()); - ability1.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability1.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); this.addAbility(ability1); } diff --git a/Mage.Sets/src/mage/cards/g/GlacialCrevasses.java b/Mage.Sets/src/mage/cards/g/GlacialCrevasses.java index 65e793b2a40..2a2839e1ef3 100644 --- a/Mage.Sets/src/mage/cards/g/GlacialCrevasses.java +++ b/Mage.Sets/src/mage/cards/g/GlacialCrevasses.java @@ -32,7 +32,7 @@ public final class GlacialCrevasses extends CardImpl { // Sacrifice a snow Mountain: Prevent all combat damage that would be dealt this turn. Effect effect = new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true); effect.setText("Prevent all combat damage that would be dealt this turn"); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GlassCastHeart.java b/Mage.Sets/src/mage/cards/g/GlassCastHeart.java index 5feed114e69..89f881447ad 100644 --- a/Mage.Sets/src/mage/cards/g/GlassCastHeart.java +++ b/Mage.Sets/src/mage/cards/g/GlassCastHeart.java @@ -60,8 +60,7 @@ public final class GlassCastHeart extends CardImpl { ability.addCost(new TapSourceCost()); ability.addCost(new CompositeCost( new SacrificeSourceCost(), - new SacrificeTargetCost( - new TargetControlledPermanent(13, filter2) + new SacrificeTargetCost(13, filter2 ), "sacrifice {this} and thirteen Blood tokens" )); ability.addEffect(new GainLifeEffect(13).concatBy("and")); diff --git a/Mage.Sets/src/mage/cards/g/GlimmerBairn.java b/Mage.Sets/src/mage/cards/g/GlimmerBairn.java index 498d793ca66..c09e7c8ebcf 100644 --- a/Mage.Sets/src/mage/cards/g/GlimmerBairn.java +++ b/Mage.Sets/src/mage/cards/g/GlimmerBairn.java @@ -36,7 +36,7 @@ public final class GlimmerBairn extends CardImpl { // Sacrifice a token: Glimmer Bairn gets +2/+2 until end of turn. this.addAbility(new SimpleActivatedAbility( new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) )); } diff --git a/Mage.Sets/src/mage/cards/g/GluttonousTroll.java b/Mage.Sets/src/mage/cards/g/GluttonousTroll.java index bad7ed4ac3c..4b026adb9fd 100644 --- a/Mage.Sets/src/mage/cards/g/GluttonousTroll.java +++ b/Mage.Sets/src/mage/cards/g/GluttonousTroll.java @@ -55,7 +55,7 @@ public final class GluttonousTroll extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{G}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Gnathosaur.java b/Mage.Sets/src/mage/cards/g/Gnathosaur.java index b465e33b296..fb1d6bcc547 100644 --- a/Mage.Sets/src/mage/cards/g/Gnathosaur.java +++ b/Mage.Sets/src/mage/cards/g/Gnathosaur.java @@ -38,7 +38,7 @@ public final class Gnathosaur extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + new SacrificeTargetCost(filter))); } private Gnathosaur(final Gnathosaur card) { diff --git a/Mage.Sets/src/mage/cards/g/GobblingOoze.java b/Mage.Sets/src/mage/cards/g/GobblingOoze.java index 97494b2c859..747766ebd15 100644 --- a/Mage.Sets/src/mage/cards/g/GobblingOoze.java +++ b/Mage.Sets/src/mage/cards/g/GobblingOoze.java @@ -32,7 +32,7 @@ public final class GobblingOoze extends CardImpl { // {G}, Sacrifice another creature: Put a +1/+1 counter on Gobbling Ooze. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl<>("{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java index 15577a263f3..24c2febb2c8 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java +++ b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java @@ -10,10 +10,12 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.ArrayList; import java.util.List; @@ -67,10 +69,9 @@ class GoblinAssassinTriggeredEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !player.flipCoin(source, game, false)) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } diff --git a/Mage.Sets/src/mage/cards/g/GoblinBarrage.java b/Mage.Sets/src/mage/cards/g/GoblinBarrage.java index d5a07099781..ccc033c7b33 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinBarrage.java +++ b/Mage.Sets/src/mage/cards/g/GoblinBarrage.java @@ -38,7 +38,7 @@ public final class GoblinBarrage extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}"); // Kicker—Sacrifice an artifact or Goblin. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(filter))); // Goblin Barrage deals 4 damage to target creature. If this spell was kicked, it also deals 4 damage to target player or planeswalker. this.getSpellAbility().addEffect(new DamageTargetEffect(4) @@ -68,4 +68,4 @@ enum GoblinBarrageAdjuster implements TargetAdjuster { ability.addTarget(new TargetPlayerOrPlaneswalker()); } } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GoblinBombardment.java b/Mage.Sets/src/mage/cards/g/GoblinBombardment.java index ff7c02320df..de203746ae0 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinBombardment.java +++ b/Mage.Sets/src/mage/cards/g/GoblinBombardment.java @@ -23,7 +23,7 @@ public final class GoblinBombardment extends CardImpl { public GoblinBombardment(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinChirurgeon.java b/Mage.Sets/src/mage/cards/g/GoblinChirurgeon.java index 33963199641..6e31d024bc9 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinChirurgeon.java +++ b/Mage.Sets/src/mage/cards/g/GoblinChirurgeon.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; @@ -22,6 +23,8 @@ import mage.target.common.TargetCreaturePermanent; */ public final class GoblinChirurgeon extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent(SubType.GOBLIN, "a Goblin"); + public GoblinChirurgeon(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}"); this.subtype.add(SubType.GOBLIN); @@ -32,7 +35,7 @@ public final class GoblinChirurgeon extends CardImpl { // Sacrifice a Goblin: Regenerate target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent(SubType.GOBLIN,"a Goblin")))); + new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java b/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java index d36df84290b..ac4c4a7f3ed 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java +++ b/Mage.Sets/src/mage/cards/g/GoblinClearcutter.java @@ -42,7 +42,7 @@ public final class GoblinClearcutter extends CardImpl { // {T}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new GoblinClearCutterManaEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinEngineer.java b/Mage.Sets/src/mage/cards/g/GoblinEngineer.java index da26604d60d..c9adbe94677 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinEngineer.java +++ b/Mage.Sets/src/mage/cards/g/GoblinEngineer.java @@ -56,7 +56,7 @@ public final class GoblinEngineer extends CardImpl { new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{R}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCardInYourGraveyard(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinGrenade.java b/Mage.Sets/src/mage/cards/g/GoblinGrenade.java index 92bacac16aa..561d687d1ba 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinGrenade.java +++ b/Mage.Sets/src/mage/cards/g/GoblinGrenade.java @@ -26,7 +26,7 @@ public final class GoblinGrenade extends CardImpl { public GoblinGrenade(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); this.getSpellAbility().addEffect(new DamageTargetEffect(5)); this.getSpellAbility().addTarget(new TargetAnyTarget()); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinLookout.java b/Mage.Sets/src/mage/cards/g/GoblinLookout.java index bf9291123ba..9a4869e4f84 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinLookout.java +++ b/Mage.Sets/src/mage/cards/g/GoblinLookout.java @@ -38,7 +38,7 @@ public final class GoblinLookout extends CardImpl { // {T}, Sacrifice a Goblin: Goblin creatures get +2/+0 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(2, 0, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE_GOBLINS, false), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterPermanent))); + ability.addCost(new SacrificeTargetCost(filterPermanent)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinRazerunners.java b/Mage.Sets/src/mage/cards/g/GoblinRazerunners.java index a14077578b7..3ef1ace9a9d 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinRazerunners.java +++ b/Mage.Sets/src/mage/cards/g/GoblinRazerunners.java @@ -40,7 +40,7 @@ public final class GoblinRazerunners extends CardImpl { // {1}{R}, Sacrifice a land: Put a +1/+1 counter on Goblin Razerunners. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // At the beginning of your end step, you may have Goblin Razerunners deal damage equal to the number of +1/+1 counters on it to target player. diff --git a/Mage.Sets/src/mage/cards/g/GoblinSledder.java b/Mage.Sets/src/mage/cards/g/GoblinSledder.java index fa89abd60f4..556927858e5 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinSledder.java +++ b/Mage.Sets/src/mage/cards/g/GoblinSledder.java @@ -38,7 +38,7 @@ public final class GoblinSledder extends CardImpl { // Sacrifice a Goblin: Target creature gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1,1,Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, true))); + new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GoblinSoothsayer.java b/Mage.Sets/src/mage/cards/g/GoblinSoothsayer.java index b29111b05f5..a27e6595bd5 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinSoothsayer.java +++ b/Mage.Sets/src/mage/cards/g/GoblinSoothsayer.java @@ -44,7 +44,7 @@ public final class GoblinSoothsayer extends CardImpl { // {R}, {T}, Sacrifice a Goblin: Red creatures get +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1,Duration.EndOfTurn, filter, false), new ManaCostsImpl<>("{R}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinTrashmaster.java b/Mage.Sets/src/mage/cards/g/GoblinTrashmaster.java index cb525385e2a..433e8abd4ae 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinTrashmaster.java +++ b/Mage.Sets/src/mage/cards/g/GoblinTrashmaster.java @@ -50,9 +50,7 @@ public final class GoblinTrashmaster extends CardImpl { // Sacrifice a Goblin: Destroy target artifact. Ability ability = new SimpleActivatedAbility( new DestroyTargetEffect(), - new SacrificeTargetCost( - new TargetControlledPermanent(filter2) - ) + new SacrificeTargetCost(filter2) ); ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GoblinTrenches.java b/Mage.Sets/src/mage/cards/g/GoblinTrenches.java index 67a40caddde..2f7cc189d8a 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinTrenches.java +++ b/Mage.Sets/src/mage/cards/g/GoblinTrenches.java @@ -24,7 +24,7 @@ public final class GoblinTrenches extends CardImpl { // {2}, Sacrifice a land: Create two 1/1 red and white Goblin Soldier creature tokens. Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new GoblinSoldierToken(), 2), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GoblinTurncoat.java b/Mage.Sets/src/mage/cards/g/GoblinTurncoat.java index 3d5d88c4b8c..f995d021be6 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinTurncoat.java +++ b/Mage.Sets/src/mage/cards/g/GoblinTurncoat.java @@ -37,7 +37,7 @@ public final class GoblinTurncoat extends CardImpl { // Sacrifice a Goblin: Regenerate Goblin Turncoat. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false))); + new SacrificeTargetCost(filter)); this.addAbility(ability); } @@ -49,4 +49,4 @@ public final class GoblinTurncoat extends CardImpl { public GoblinTurncoat copy() { return new GoblinTurncoat(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/g/GoblinWarrens.java b/Mage.Sets/src/mage/cards/g/GoblinWarrens.java index 8e16f184718..5362c0b54da 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinWarrens.java +++ b/Mage.Sets/src/mage/cards/g/GoblinWarrens.java @@ -30,7 +30,7 @@ public final class GoblinWarrens extends CardImpl { // {2}{R}, Sacrifice two Goblins: Create three 1/1 red Goblin creature tokens. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new GoblinToken(), 3), new ManaCostsImpl<>("{2}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, filter, true))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/Goremand.java b/Mage.Sets/src/mage/cards/g/Goremand.java index 89a708bb09d..a3c9aca0439 100644 --- a/Mage.Sets/src/mage/cards/g/Goremand.java +++ b/Mage.Sets/src/mage/cards/g/Goremand.java @@ -28,9 +28,7 @@ public final class Goremand extends CardImpl { this.toughness = new MageInt(5); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Flying this.addAbility(FlyingAbility.getInstance()); diff --git a/Mage.Sets/src/mage/cards/g/GrabTheReins.java b/Mage.Sets/src/mage/cards/g/GrabTheReins.java index 55abd488b57..675efb1c0a0 100644 --- a/Mage.Sets/src/mage/cards/g/GrabTheReins.java +++ b/Mage.Sets/src/mage/cards/g/GrabTheReins.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -20,6 +21,7 @@ import mage.target.Target; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -79,15 +81,13 @@ class GrabTheReinsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { UUID controllerId = source.getControllerId(); - Target target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); - target.setTargetName("a creature to sacrifice"); + Target target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE); if (!target.canChoose(controllerId, source, game)) { return false; } Player player = game.getPlayer(controllerId); if (player != null) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); Permanent creatureToSacrifice = game.getPermanent(target.getTargets().get(0)); int amount = creatureToSacrifice.getPower().getValue(); if (!creatureToSacrifice.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/g/GraftedIdentity.java b/Mage.Sets/src/mage/cards/g/GraftedIdentity.java index 1347d0ffd27..047efa7d686 100644 --- a/Mage.Sets/src/mage/cards/g/GraftedIdentity.java +++ b/Mage.Sets/src/mage/cards/g/GraftedIdentity.java @@ -30,9 +30,7 @@ public final class GraftedIdentity extends CardImpl { this.subtype.add(SubType.AURA); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); diff --git a/Mage.Sets/src/mage/cards/g/GraveExchange.java b/Mage.Sets/src/mage/cards/g/GraveExchange.java index 991a8199b07..0761b22c110 100644 --- a/Mage.Sets/src/mage/cards/g/GraveExchange.java +++ b/Mage.Sets/src/mage/cards/g/GraveExchange.java @@ -1,20 +1,14 @@ package mage.cards.g; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.abilities.effects.common.SacrificeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; import mage.target.TargetPlayer; import mage.target.common.TargetCardInYourGraveyard; -import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.targetpointer.SecondTargetPointer; import java.util.UUID; @@ -31,7 +25,8 @@ public final class GraveExchange extends CardImpl { this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); // Target player sacrifices a creature. - this.getSpellAbility().addEffect(new GraveExchangeEffect()); + this.getSpellAbility().addEffect(new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "Target player") + .setTargetPointer(new SecondTargetPointer())); this.getSpellAbility().addTarget(new TargetPlayer()); } @@ -44,39 +39,3 @@ public final class GraveExchange extends CardImpl { return new GraveExchange(this); } } - -class GraveExchangeEffect extends OneShotEffect { - - public GraveExchangeEffect() { - super(Outcome.Sacrifice); - this.staticText = "Target player sacrifices a creature"; - } - - private GraveExchangeEffect(final GraveExchangeEffect effect) { - super(effect); - } - - @Override - public GraveExchangeEffect copy() { - return new GraveExchangeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getTargets().get(1).getFirstTarget()); - if (player == null) { - return false; - } - - Target target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); - if (target.canChoose(player.getId(), source, game) - && player.choose(Outcome.Sacrifice, target, source, game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - return permanent.sacrifice(source, game); - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GravePact.java b/Mage.Sets/src/mage/cards/g/GravePact.java index dbbc9d9a7d6..7fbfd83f3b4 100644 --- a/Mage.Sets/src/mage/cards/g/GravePact.java +++ b/Mage.Sets/src/mage/cards/g/GravePact.java @@ -8,12 +8,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.ArrayList; import java.util.List; @@ -98,10 +100,9 @@ class GravePactEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !playerId.equals(source.getControllerId())) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } diff --git a/Mage.Sets/src/mage/cards/g/GreatHallOfStarnheim.java b/Mage.Sets/src/mage/cards/g/GreatHallOfStarnheim.java index 5664bd536bc..a06b73bc036 100644 --- a/Mage.Sets/src/mage/cards/g/GreatHallOfStarnheim.java +++ b/Mage.Sets/src/mage/cards/g/GreatHallOfStarnheim.java @@ -16,6 +16,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.permanent.token.AngelWarriorVigilanceToken; import mage.target.common.TargetControlledCreaturePermanent; @@ -44,7 +45,7 @@ public final class GreatHallOfStarnheim extends CardImpl { ); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); - Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE); cost.setText("and a creature you control"); ability.addCost(cost); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GreaterGargadon.java b/Mage.Sets/src/mage/cards/g/GreaterGargadon.java index 7ae4f9fcc4f..73ea8940947 100644 --- a/Mage.Sets/src/mage/cards/g/GreaterGargadon.java +++ b/Mage.Sets/src/mage/cards/g/GreaterGargadon.java @@ -58,7 +58,7 @@ class GreaterGargadonAbility extends ActivatedAbilityImpl { } public GreaterGargadonAbility() { - super(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + super(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), new SacrificeTargetCost(filter)); } private GreaterGargadonAbility(final GreaterGargadonAbility ability) { diff --git a/Mage.Sets/src/mage/cards/g/GretaSweettoothScourge.java b/Mage.Sets/src/mage/cards/g/GretaSweettoothScourge.java index 78c308f8276..16697b92e6a 100644 --- a/Mage.Sets/src/mage/cards/g/GretaSweettoothScourge.java +++ b/Mage.Sets/src/mage/cards/g/GretaSweettoothScourge.java @@ -46,7 +46,7 @@ public final class GretaSweettoothScourge extends CardImpl { new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl<>("{G}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -55,7 +55,7 @@ public final class GretaSweettoothScourge extends CardImpl { new DrawCardSourceControllerEffect(1, "you"), new ManaCostsImpl<>("{1}{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); ability.addEffect(new LoseLifeSourceControllerEffect(1).concatBy("and")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GrimgrinCorpseBorn.java b/Mage.Sets/src/mage/cards/g/GrimgrinCorpseBorn.java index 1f51b83fe1a..ac07ed915ec 100644 --- a/Mage.Sets/src/mage/cards/g/GrimgrinCorpseBorn.java +++ b/Mage.Sets/src/mage/cards/g/GrimgrinCorpseBorn.java @@ -53,7 +53,7 @@ public final class GrimgrinCorpseBorn extends CardImpl { // Sacrifice another creature: Untap Grimgrin and put a +1/+1 counter on it. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapSourceEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addEffect(new AddCountersSourceEffect(CounterType.P1P1.createInstance()).setText("and put a +1/+1 counter on it")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GrindingStation.java b/Mage.Sets/src/mage/cards/g/GrindingStation.java index 7db37b14b02..5348d28dba6 100644 --- a/Mage.Sets/src/mage/cards/g/GrindingStation.java +++ b/Mage.Sets/src/mage/cards/g/GrindingStation.java @@ -34,7 +34,7 @@ public final class GrindingStation extends CardImpl { // {T}, Sacrifice an artifact: Target player puts the top three cards of their library into their graveyard. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MillCardsTargetEffect(3), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/g/GristTheHungerTide.java b/Mage.Sets/src/mage/cards/g/GristTheHungerTide.java index d2de2a6a6d2..5a30c6656bd 100644 --- a/Mage.Sets/src/mage/cards/g/GristTheHungerTide.java +++ b/Mage.Sets/src/mage/cards/g/GristTheHungerTide.java @@ -58,9 +58,7 @@ public final class GristTheHungerTide extends CardImpl { ability.addTarget(new TargetCreatureOrPlaneswalker()); this.addAbility(new LoyaltyAbility(new DoWhenCostPaid( ability, - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )), "Sacrifice a creature?" + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), "Sacrifice a creature?" ), -2)); // −5: Each opponent loses life equal to the number of creature cards in your graveyard. diff --git a/Mage.Sets/src/mage/cards/g/GruulGuildmage.java b/Mage.Sets/src/mage/cards/g/GruulGuildmage.java index fdec5210dce..3069b48b543 100644 --- a/Mage.Sets/src/mage/cards/g/GruulGuildmage.java +++ b/Mage.Sets/src/mage/cards/g/GruulGuildmage.java @@ -38,7 +38,7 @@ public final class GruulGuildmage extends CardImpl { // {3}{R}, Sacrifice a land: Gruul Guildmage deals 2 damage to target player. Ability firstAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{3}{R}")); - firstAbility.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + firstAbility.addCost(new SacrificeTargetCost(filter)); firstAbility.addTarget(new TargetPlayerOrPlaneswalker(1)); this.addAbility(firstAbility); // {3}{G}: Target creature gets +2/+2 until end of turn. diff --git a/Mage.Sets/src/mage/cards/g/GuardianOfCloverdell.java b/Mage.Sets/src/mage/cards/g/GuardianOfCloverdell.java index 8430234bb10..cca4f6ed1a8 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianOfCloverdell.java +++ b/Mage.Sets/src/mage/cards/g/GuardianOfCloverdell.java @@ -40,7 +40,7 @@ public final class GuardianOfCloverdell extends CardImpl { this.toughness = new MageInt(5); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new KithkinSoldierToken(), 3), false)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(1), new ColoredManaCost(ColoredManaSymbol.G)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GyomeMasterChef.java b/Mage.Sets/src/mage/cards/g/GyomeMasterChef.java index 061d232a1dc..bd2ffe7ff2d 100644 --- a/Mage.Sets/src/mage/cards/g/GyomeMasterChef.java +++ b/Mage.Sets/src/mage/cards/g/GyomeMasterChef.java @@ -66,7 +66,7 @@ public final class GyomeMasterChef extends CardImpl { Ability ability = new SimpleActivatedAbility(new GainAbilityTargetEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); ability.addEffect(new TapTargetEffect("tap it")); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/h/HammerOfPurphoros.java b/Mage.Sets/src/mage/cards/h/HammerOfPurphoros.java index 289b8e0f35d..b0f0604b24f 100644 --- a/Mage.Sets/src/mage/cards/h/HammerOfPurphoros.java +++ b/Mage.Sets/src/mage/cards/h/HammerOfPurphoros.java @@ -39,7 +39,7 @@ public final class HammerOfPurphoros extends CardImpl { // {2}{R}, {tap}, Sacrifice a land: Create a 3/3 colorless Golem enchantment artifact creature token. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new HammerOfPurphorosGolemToken()), new ManaCostsImpl<>("{2}{R}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HandOfEmrakul.java b/Mage.Sets/src/mage/cards/h/HandOfEmrakul.java index b4078028fc0..e2fcf60c02e 100644 --- a/Mage.Sets/src/mage/cards/h/HandOfEmrakul.java +++ b/Mage.Sets/src/mage/cards/h/HandOfEmrakul.java @@ -34,7 +34,7 @@ public final class HandOfEmrakul extends CardImpl { this.toughness = new MageInt(7); // You may sacrifice four Eldrazi Spawn rather than pay Hand of Emrakul's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(4, 4, filter, true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(4, filter))); // Annihilator 1 this.addAbility(new AnnihilatorAbility(1)); } diff --git a/Mage.Sets/src/mage/cards/h/Harrow.java b/Mage.Sets/src/mage/cards/h/Harrow.java index c6416efd6c4..baa7287c8de 100644 --- a/Mage.Sets/src/mage/cards/h/Harrow.java +++ b/Mage.Sets/src/mage/cards/h/Harrow.java @@ -21,7 +21,7 @@ public final class Harrow extends CardImpl { this.color.setGreen(true); // As an additional cost to cast Harrow, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); // Search your library for up to two basic land cards and put them onto the battlefield. Then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(0, 2, StaticFilters.FILTER_CARD_BASIC_LANDS); diff --git a/Mage.Sets/src/mage/cards/h/HarvesterTroll.java b/Mage.Sets/src/mage/cards/h/HarvesterTroll.java index 3e726f98426..9f3fbc5bd50 100644 --- a/Mage.Sets/src/mage/cards/h/HarvesterTroll.java +++ b/Mage.Sets/src/mage/cards/h/HarvesterTroll.java @@ -37,7 +37,7 @@ public final class HarvesterTroll extends CardImpl { // When Harvester Troll enters the battlefield, you may sacrifice a creature or land. If you do, put two +1/+1 counters on Harvester Troll. EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new SacrificeTargetCost(new TargetControlledPermanent(filter))), false); + new SacrificeTargetCost(filter)), false); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HashepOasis.java b/Mage.Sets/src/mage/cards/h/HashepOasis.java index 56ed2d97944..3ac4d1e9dc6 100644 --- a/Mage.Sets/src/mage/cards/h/HashepOasis.java +++ b/Mage.Sets/src/mage/cards/h/HashepOasis.java @@ -49,7 +49,7 @@ public final class HashepOasis extends CardImpl { ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(3,3,Duration.EndOfTurn), new ManaCostsImpl<>("{1}{G}{G}")); ability.addTarget(new TargetCreaturePermanent()); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HeWhoHungers.java b/Mage.Sets/src/mage/cards/h/HeWhoHungers.java index c630b4c1e5c..5b7e288b80e 100644 --- a/Mage.Sets/src/mage/cards/h/HeWhoHungers.java +++ b/Mage.Sets/src/mage/cards/h/HeWhoHungers.java @@ -52,7 +52,7 @@ public final class HeWhoHungers extends CardImpl { * That player discards that card. Activate this ability only any time you could cast a sorcery. */ Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardCardYouChooseTargetEffect(), new ManaCostsImpl<>("{1}")); ability.addTarget(new TargetOpponent()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); //Soulshift 4 (When this creature dies, you may return target Spirit card with converted mana cost 4 or less from your graveyard to your hand.) @@ -68,4 +68,4 @@ public final class HeWhoHungers extends CardImpl { return new HeWhoHungers(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/h/HeartOfYavimaya.java b/Mage.Sets/src/mage/cards/h/HeartOfYavimaya.java index 0f36c55f7db..bc5ff9b0df6 100644 --- a/Mage.Sets/src/mage/cards/h/HeartOfYavimaya.java +++ b/Mage.Sets/src/mage/cards/h/HeartOfYavimaya.java @@ -36,7 +36,7 @@ public final class HeartOfYavimaya extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},""); // If Heart of Yavimaya would enter the battlefield, sacrifice a Forest instead. If you do, put Heart of Yavimaya onto the battlefield. If you don't, put it into its owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(filter)))); // {tap}: Add {G}. this.addAbility(new GreenManaAbility()); diff --git a/Mage.Sets/src/mage/cards/h/Heartfire.java b/Mage.Sets/src/mage/cards/h/Heartfire.java index d377f9a7a89..37001288025 100644 --- a/Mage.Sets/src/mage/cards/h/Heartfire.java +++ b/Mage.Sets/src/mage/cards/h/Heartfire.java @@ -31,7 +31,7 @@ public final class Heartfire extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); // As an additional cost to cast this spell, sacrifice a creature or planeswalker. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Heartfire deals 4 damage to any target. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); diff --git a/Mage.Sets/src/mage/cards/h/HearthcageGiant.java b/Mage.Sets/src/mage/cards/h/HearthcageGiant.java index 1d206d68b2f..251ed7f5505 100644 --- a/Mage.Sets/src/mage/cards/h/HearthcageGiant.java +++ b/Mage.Sets/src/mage/cards/h/HearthcageGiant.java @@ -47,7 +47,7 @@ public final class HearthcageGiant extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ElementalShamanToken(), 2), false)); //Sacrifice an Elemental: Target Giant creature gets +3/+1 until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(3, 1, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filterElemental))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(3, 1, Duration.EndOfTurn), new SacrificeTargetCost(filterElemental)); ability.addTarget(new TargetCreaturePermanent(filterGiant)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HeartwoodGiant.java b/Mage.Sets/src/mage/cards/h/HeartwoodGiant.java index 62f0180d1fa..4e7ff0ba23e 100644 --- a/Mage.Sets/src/mage/cards/h/HeartwoodGiant.java +++ b/Mage.Sets/src/mage/cards/h/HeartwoodGiant.java @@ -36,7 +36,7 @@ public final class HeartwoodGiant extends CardImpl { this.power = new MageInt(4); this.toughness = new MageInt(4); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/Hecatomb.java b/Mage.Sets/src/mage/cards/h/Hecatomb.java index 35ad002bf04..ae7cdcbbcef 100644 --- a/Mage.Sets/src/mage/cards/h/Hecatomb.java +++ b/Mage.Sets/src/mage/cards/h/Hecatomb.java @@ -42,7 +42,7 @@ public final class Hecatomb extends CardImpl { // When Hecatomb enters the battlefield, sacrifice Hecatomb unless you sacrifice four creatures. this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect( - new SacrificeTargetCost(new TargetControlledPermanent(4, filter2)))) + new SacrificeTargetCost(4, filter2))) .withRuleTextReplacement(false)); // Tap an untapped Swamp you control: Hecatomb deals 1 damage to any target. diff --git a/Mage.Sets/src/mage/cards/h/HedronDetonator.java b/Mage.Sets/src/mage/cards/h/HedronDetonator.java index 9216c8054d9..ff6c2fba873 100644 --- a/Mage.Sets/src/mage/cards/h/HedronDetonator.java +++ b/Mage.Sets/src/mage/cards/h/HedronDetonator.java @@ -17,6 +17,7 @@ import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -44,7 +45,7 @@ public final class HedronDetonator extends CardImpl { // {T}, Sacrifice two artifacts: Exile the top card of your library. You may play that card this turn. ability = new SimpleActivatedAbility(new ExileTopXMayPlayUntilEndOfTurnEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HeraldOfAnguish.java b/Mage.Sets/src/mage/cards/h/HeraldOfAnguish.java index 1e49090a119..c508a516306 100644 --- a/Mage.Sets/src/mage/cards/h/HeraldOfAnguish.java +++ b/Mage.Sets/src/mage/cards/h/HeraldOfAnguish.java @@ -42,7 +42,7 @@ public final class HeraldOfAnguish extends CardImpl { // {1}{B}, Sacrifice an artifact: Target creature gets -2/-2 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(-2, -2, Duration.EndOfTurn), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/Heroism.java b/Mage.Sets/src/mage/cards/h/Heroism.java index bd798b35289..ab55b5e213f 100644 --- a/Mage.Sets/src/mage/cards/h/Heroism.java +++ b/Mage.Sets/src/mage/cards/h/Heroism.java @@ -44,7 +44,7 @@ public final class Heroism extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); // Sacrifice a white creature: For each attacking red creature, prevent all combat damage that would be dealt by that creature this turn unless its controller pays {2}{R}. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new HeroismEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new HeroismEffect(), new SacrificeTargetCost(filter))); } private Heroism(final Heroism card) { diff --git a/Mage.Sets/src/mage/cards/h/HidetsuguDevouringChaos.java b/Mage.Sets/src/mage/cards/h/HidetsuguDevouringChaos.java index 9a40fc8f1a7..4128bc336bd 100644 --- a/Mage.Sets/src/mage/cards/h/HidetsuguDevouringChaos.java +++ b/Mage.Sets/src/mage/cards/h/HidetsuguDevouringChaos.java @@ -39,9 +39,7 @@ public final class HidetsuguDevouringChaos extends CardImpl { // {B}, Sacrifice a creature: Scry 2. Ability ability = new SimpleActivatedAbility(new ScryEffect(2), new ManaCostsImpl<>("{B}")); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); // {2}{R}, {T}: Exile the top card of your library. You may play that card this turn. When you exile a nonland card this way, Hidetsugu, Devouring Chaos deals damage equal to the exiled card's mana value to any target. diff --git a/Mage.Sets/src/mage/cards/h/HitRun.java b/Mage.Sets/src/mage/cards/h/HitRun.java index 51393c8bd9f..3d7cff140de 100644 --- a/Mage.Sets/src/mage/cards/h/HitRun.java +++ b/Mage.Sets/src/mage/cards/h/HitRun.java @@ -10,6 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.SpellAbilityType; +import mage.filter.StaticFilters; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; @@ -18,6 +19,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -71,11 +73,7 @@ class HitEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getTargets().getFirstTarget()); if (targetPlayer != null) { - FilterControlledPermanent filter = new FilterControlledPermanent("artifact or creature"); - filter.add(Predicates.or( - CardType.ARTIFACT.getPredicate(), - CardType.CREATURE.getPredicate())); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE); if (target.canChoose(targetPlayer.getId(), source, game)) { targetPlayer.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/h/HithlainRope.java b/Mage.Sets/src/mage/cards/h/HithlainRope.java new file mode 100644 index 00000000000..0adf39e6b3d --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HithlainRope.java @@ -0,0 +1,56 @@ +package mage.cards.h; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.PlayerToRightGainsControlOfSourceEffect; +import mage.abilities.effects.common.continuous.CantBeSacrificedSourceEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +import java.util.UUID; + +/** + * @author xenohedron + */ +public final class HithlainRope extends CardImpl { + + public HithlainRope(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // Hithlain Rope can't be sacrificed. + this.addAbility(new SimpleStaticAbility(new CantBeSacrificedSourceEffect())); + + // {1}, {T}: Search your library for a basic land card, put it onto the battlefield tapped, then shuffle. The player to your right gains control of Hithlain Rope. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect( + new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND_A), true + ), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addEffect(new PlayerToRightGainsControlOfSourceEffect()); + this.addAbility(ability); + + // {2}, {T}: Draw a card. The player to your right gains control of Hithlain Rope. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); + ability.addCost(new TapSourceCost()); + ability.addEffect(new PlayerToRightGainsControlOfSourceEffect()); + this.addAbility(ability); + + } + + private HithlainRope(final HithlainRope card) { + super(card); + } + + @Override + public HithlainRope copy() { + return new HithlainRope(this); + } +} diff --git a/Mage.Sets/src/mage/cards/h/Hobblefiend.java b/Mage.Sets/src/mage/cards/h/Hobblefiend.java index 7f81332b250..8d41233fb64 100644 --- a/Mage.Sets/src/mage/cards/h/Hobblefiend.java +++ b/Mage.Sets/src/mage/cards/h/Hobblefiend.java @@ -36,9 +36,7 @@ public final class Hobblefiend extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HomaridSpawningBed.java b/Mage.Sets/src/mage/cards/h/HomaridSpawningBed.java index 71596173a4e..c0534622309 100644 --- a/Mage.Sets/src/mage/cards/h/HomaridSpawningBed.java +++ b/Mage.Sets/src/mage/cards/h/HomaridSpawningBed.java @@ -36,7 +36,7 @@ public final class HomaridSpawningBed extends CardImpl { // {1}{U}{U}, Sacrifice a blue creature: create X 1/1 blue Camarid creature tokens, where X is the sacrificed creature's converted mana cost. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new CamaridToken(), SacrificeCostManaValue.CREATURE), new ManaCostsImpl<>("{1}{U}{U}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HorrorOfHorrors.java b/Mage.Sets/src/mage/cards/h/HorrorOfHorrors.java index b12124d4e5c..fb2e0232913 100644 --- a/Mage.Sets/src/mage/cards/h/HorrorOfHorrors.java +++ b/Mage.Sets/src/mage/cards/h/HorrorOfHorrors.java @@ -37,7 +37,7 @@ public final class HorrorOfHorrors extends CardImpl { // Sacrifice a Swamp: Regenerate target black creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(filter1))); + new SacrificeTargetCost(filter1)); ability.addTarget(new TargetCreaturePermanent(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IbHalfheartGoblinTactician.java b/Mage.Sets/src/mage/cards/i/IbHalfheartGoblinTactician.java index fbfa52de1fc..83a372ba1ff 100644 --- a/Mage.Sets/src/mage/cards/i/IbHalfheartGoblinTactician.java +++ b/Mage.Sets/src/mage/cards/i/IbHalfheartGoblinTactician.java @@ -55,7 +55,7 @@ public final class IbHalfheartGoblinTactician extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new CreateTokenEffect(new GoblinToken(), 2), - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true)))); + new SacrificeTargetCost(2, filter))); } diff --git a/Mage.Sets/src/mage/cards/i/IchorExplosion.java b/Mage.Sets/src/mage/cards/i/IchorExplosion.java index 3e695a4194a..d67fc60da48 100644 --- a/Mage.Sets/src/mage/cards/i/IchorExplosion.java +++ b/Mage.Sets/src/mage/cards/i/IchorExplosion.java @@ -25,7 +25,7 @@ public final class IchorExplosion extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}"); // As an additional cost to cast Ichor Explosion, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // All creatures get -X/-X until end of turn, where X is the sacrificed creature's power. this.getSpellAbility().addEffect(new BoostAllEffect(xValue, xValue, Duration.EndOfTurn)); diff --git a/Mage.Sets/src/mage/cards/i/IfnirDeadlands.java b/Mage.Sets/src/mage/cards/i/IfnirDeadlands.java index 33a72c4b31d..f7c32b88a0b 100644 --- a/Mage.Sets/src/mage/cards/i/IfnirDeadlands.java +++ b/Mage.Sets/src/mage/cards/i/IfnirDeadlands.java @@ -49,7 +49,7 @@ public final class IfnirDeadlands extends CardImpl { // {2}{B}{B}, {t}, Sacrifice a Desert: Put two -1/-1 counters on target creature an opponent controls. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.M1M1.createInstance(2)), new ManaCostsImpl<>("{2}{B}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetOpponentsCreaturePermanent()); this.addAbility(ability); @@ -63,4 +63,4 @@ public final class IfnirDeadlands extends CardImpl { public IfnirDeadlands copy() { return new IfnirDeadlands(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/i/IizukaTheRuthless.java b/Mage.Sets/src/mage/cards/i/IizukaTheRuthless.java index 6df95a40d4b..327fadf0a59 100644 --- a/Mage.Sets/src/mage/cards/i/IizukaTheRuthless.java +++ b/Mage.Sets/src/mage/cards/i/IizukaTheRuthless.java @@ -41,7 +41,7 @@ public final class IizukaTheRuthless extends CardImpl { this.addAbility(new BushidoAbility(2)); // {2}{R}, Sacrifice a Samurai: Samurai creatures you control gain double strike until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, filter2, false), new ManaCostsImpl<>("{2}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/ImmersturmPredator.java b/Mage.Sets/src/mage/cards/i/ImmersturmPredator.java index bd7bf394e27..2c1a11651ab 100644 --- a/Mage.Sets/src/mage/cards/i/ImmersturmPredator.java +++ b/Mage.Sets/src/mage/cards/i/ImmersturmPredator.java @@ -48,7 +48,7 @@ public final class ImmersturmPredator extends CardImpl { // Sacrifice another creature: Immersturm Predator gains indestructible until end of turn. Tap it. ability = new SimpleActivatedAbility(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn - ), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addEffect(new TapSourceEffect().setText("Tap it")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IncendiarySabotage.java b/Mage.Sets/src/mage/cards/i/IncendiarySabotage.java index 3c25a202b28..42b9dc01b2a 100644 --- a/Mage.Sets/src/mage/cards/i/IncendiarySabotage.java +++ b/Mage.Sets/src/mage/cards/i/IncendiarySabotage.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.DamageAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.target.common.TargetControlledPermanent; @@ -21,7 +22,7 @@ public final class IncendiarySabotage extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}"); // As an additional cost to cast Incendiary Sabotage, sacrifice an artifact. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); // Incendiary Sabotage deals 3 damage to each creature. this.getSpellAbility().addEffect(new DamageAllEffect(3, new FilterCreaturePermanent())); diff --git a/Mage.Sets/src/mage/cards/i/Incriminate.java b/Mage.Sets/src/mage/cards/i/Incriminate.java index efbe6765bf4..ef257e29f49 100644 --- a/Mage.Sets/src/mage/cards/i/Incriminate.java +++ b/Mage.Sets/src/mage/cards/i/Incriminate.java @@ -8,6 +8,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -17,6 +18,7 @@ import java.util.UUID; import mage.filter.FilterPermanent; import mage.filter.predicate.permanent.PermanentIdPredicate; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; /** * @author TheElk801 @@ -71,10 +73,9 @@ class IncriminateEffect extends OneShotEffect { || player == null) { return false; } - filter.add(mage.filter.predicate.Predicates.or(permanentIdPredicates)); - TargetPermanent target = new TargetPermanent(filter); - target.withNotTarget(true); - player.chooseTarget(Outcome.Sacrifice, target, source, game); + filter.add(Predicates.or(permanentIdPredicates)); + TargetSacrifice target = new TargetSacrifice(filter); + player.choose(Outcome.Sacrifice, target, source, game); Permanent sacrificeCreature = game.getPermanent(target.getFirstTarget()); return sacrificeCreature != null && sacrificeCreature.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/i/InfernalTribute.java b/Mage.Sets/src/mage/cards/i/InfernalTribute.java index 6eac256dfaf..81e12a6ecc9 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalTribute.java +++ b/Mage.Sets/src/mage/cards/i/InfernalTribute.java @@ -32,7 +32,7 @@ public final class InfernalTribute extends CardImpl { // {2}, Sacrifice a nontoken permanent: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IngenuityEngine.java b/Mage.Sets/src/mage/cards/i/IngenuityEngine.java index 7c380cb8c95..2d2d0347d0c 100644 --- a/Mage.Sets/src/mage/cards/i/IngenuityEngine.java +++ b/Mage.Sets/src/mage/cards/i/IngenuityEngine.java @@ -30,7 +30,7 @@ public final class IngenuityEngine extends CardImpl { // {1}, {T}, Sacrifice an artifact: Return target artifact you control to its owner's hand. Ability ability = new SimpleActivatedAbility(new ReturnToHandTargetEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java b/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java index aa28304573d..a28bc1d9eea 100644 --- a/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java +++ b/Mage.Sets/src/mage/cards/i/InsatiableAppetite.java @@ -25,7 +25,7 @@ public final class InsatiableAppetite extends CardImpl { this.getSpellAbility().addEffect(new DoIfCostPaid( new BoostTargetEffect(5, 5, Duration.EndOfTurn), new BoostTargetEffect(3, 3, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD) ).setText("You may sacrifice a Food. If you do, target creature gets +5/+5 until end of turn. " + "Otherwise, that creature gets +3/+3 until end of turn.")); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/i/IpnuRivulet.java b/Mage.Sets/src/mage/cards/i/IpnuRivulet.java index e7b40fbc366..f47244ac051 100644 --- a/Mage.Sets/src/mage/cards/i/IpnuRivulet.java +++ b/Mage.Sets/src/mage/cards/i/IpnuRivulet.java @@ -48,7 +48,7 @@ public final class IpnuRivulet extends CardImpl { // {1}{U}, {t}, Sacrifice a Desert: Target player puts the top four cards of their library into their graveyard. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MillCardsTargetEffect(4), new ManaCostsImpl<>("{1}{U}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IroncladRevolutionary.java b/Mage.Sets/src/mage/cards/i/IroncladRevolutionary.java index 5eb03c8575d..c310787c9d0 100644 --- a/Mage.Sets/src/mage/cards/i/IroncladRevolutionary.java +++ b/Mage.Sets/src/mage/cards/i/IroncladRevolutionary.java @@ -14,6 +14,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,7 +34,7 @@ public final class IroncladRevolutionary extends CardImpl { // When Ironclad Revolutionary enters the battlefield, you may sacrifice an artifact. If you do, put two +1/+1 counters on Ironclad Revolutionary and each opponent loses 2 life. DoIfCostPaid doEffect = new DoIfCostPaid(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2), true), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); Effect effect = new LoseLifeOpponentsEffect(2); effect.setText("and each opponent loses 2 life"); doEffect.addEffect(effect); diff --git a/Mage.Sets/src/mage/cards/i/IzoniThousandEyed.java b/Mage.Sets/src/mage/cards/i/IzoniThousandEyed.java index 9624ece5cf9..4ef237baf3c 100644 --- a/Mage.Sets/src/mage/cards/i/IzoniThousandEyed.java +++ b/Mage.Sets/src/mage/cards/i/IzoniThousandEyed.java @@ -55,9 +55,7 @@ public final class IzoniThousandEyed extends CardImpl { ability.addEffect( new DrawCardSourceControllerEffect(1).setText("and draw a card") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JaliraMasterPolymorphist.java b/Mage.Sets/src/mage/cards/j/JaliraMasterPolymorphist.java index acc34efa090..a83b39b5cd4 100644 --- a/Mage.Sets/src/mage/cards/j/JaliraMasterPolymorphist.java +++ b/Mage.Sets/src/mage/cards/j/JaliraMasterPolymorphist.java @@ -46,7 +46,7 @@ public final class JaliraMasterPolymorphist extends CardImpl { filterCard, PutCards.BATTLEFIELD, PutCards.BOTTOM_RANDOM ), new ManaCostsImpl<>("{2}{U}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java index 32446c9c407..a20b6b6b9da 100644 --- a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java +++ b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java @@ -51,13 +51,13 @@ public final class JaradGolgariLichLord extends CardImpl { // {1}{B}{G}, Sacrifice another creature: Each opponent loses life equal to the sacrificed creature's power. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(SacrificeCostCreaturesPower.instance), new ManaCostsImpl<>("{1}{B}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); // Sacrifice a Swamp and a Forest: Return Jarad from your graveyard to your hand. ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(filterSwamp))); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterForest))); + new SacrificeTargetCost(filterSwamp)); + ability.addCost(new SacrificeTargetCost(filterForest)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/j/JeweledSpirit.java b/Mage.Sets/src/mage/cards/j/JeweledSpirit.java index bf9dd6dbc82..b519fd40331 100644 --- a/Mage.Sets/src/mage/cards/j/JeweledSpirit.java +++ b/Mage.Sets/src/mage/cards/j/JeweledSpirit.java @@ -20,6 +20,7 @@ import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; @@ -43,7 +44,7 @@ public final class JeweledSpirit extends CardImpl { // Sacrifice two lands: Jeweled Spirit gains protection from artifacts or from the color of your choice until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new JeweledSpiritEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true)))); + new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS))); } private JeweledSpirit(final JeweledSpirit card) { diff --git a/Mage.Sets/src/mage/cards/j/Jokulmorder.java b/Mage.Sets/src/mage/cards/j/Jokulmorder.java index 0d4cf5bcb94..e216be516b3 100644 --- a/Mage.Sets/src/mage/cards/j/Jokulmorder.java +++ b/Mage.Sets/src/mage/cards/j/Jokulmorder.java @@ -16,6 +16,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -44,7 +45,7 @@ public final class Jokulmorder extends CardImpl { // When Jokulmorder enters the battlefield, sacrifice it unless you sacrifice five lands. Effect effect = new SacrificeSourceUnlessPaysEffect( - new SacrificeTargetCost(new TargetControlledPermanent(5, 5, new FilterControlledLandPermanent("five lands"), true))); + new SacrificeTargetCost(5, StaticFilters.FILTER_LANDS)); effect.setText("sacrifice it unless you sacrifice five lands"); this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false)); diff --git a/Mage.Sets/src/mage/cards/j/JoleneThePlunderQueen.java b/Mage.Sets/src/mage/cards/j/JoleneThePlunderQueen.java index 60c90b416ae..649b4187046 100644 --- a/Mage.Sets/src/mage/cards/j/JoleneThePlunderQueen.java +++ b/Mage.Sets/src/mage/cards/j/JoleneThePlunderQueen.java @@ -53,7 +53,7 @@ public final class JoleneThePlunderQueen extends CardImpl { // Sacrifice five Treasures: Put five +1/+1 counters on Jolene. this.addAbility(new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)), - new SacrificeTargetCost(new TargetControlledPermanent(5, filterTreasures)) + new SacrificeTargetCost(5, filterTreasures) )); } diff --git a/Mage.Sets/src/mage/cards/j/JonIrenicusShatteredOne.java b/Mage.Sets/src/mage/cards/j/JonIrenicusShatteredOne.java new file mode 100644 index 00000000000..63ca3dceb8c --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JonIrenicusShatteredOne.java @@ -0,0 +1,110 @@ +package mage.cards.j; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.combat.GoadTargetEffect; +import mage.abilities.effects.common.continuous.CantBeSacrificedSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author PurpleCrowbar, xenohedron + */ +public final class JonIrenicusShatteredOne extends CardImpl { + + private static final FilterCreaturePermanent filter + = new FilterCreaturePermanent("creature you own but don't control"); + + static { + filter.add(TargetController.YOU.getOwnerPredicate()); + filter.add(TargetController.NOT_YOU.getControllerPredicate()); + } + + public JonIrenicusShatteredOne(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{B}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.ELF); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // At the beginning of your end step, target opponent gains control of up to one target creature you control. Put two +1/+1 counters on it and tap it. + // It's goaded for the rest of the game and it gains “This creature can't be sacrificed.” + Ability ability = new BeginningOfEndStepTriggeredAbility(new JonIrenicusShatteredOneEffect(), TargetController.YOU, false); + ability.addTarget(new TargetOpponent()); + ability.addTarget(new TargetControlledCreaturePermanent(0, 1)); + this.addAbility(ability); + + // Whenever a creature you own but don't control attacks, you draw a card. + this.addAbility(new AttacksAllTriggeredAbility(new DrawCardSourceControllerEffect(1, "you"), false, filter, SetTargetPointer.NONE, false)); + } + + private JonIrenicusShatteredOne(final JonIrenicusShatteredOne card) {super(card);} + + @Override + public JonIrenicusShatteredOne copy() {return new JonIrenicusShatteredOne(this);} +} + + +class JonIrenicusShatteredOneEffect extends OneShotEffect { + + JonIrenicusShatteredOneEffect() { + super(Outcome.Detriment); + this.staticText = "target opponent gains control of up to one target creature you control. Put two +1/+1 counters on it and tap it. " + + "It's goaded for the rest of the game and it gains \"This creature can't be sacrificed.\""; + } + + private JonIrenicusShatteredOneEffect(final JonIrenicusShatteredOneEffect effect) { + super(effect); + } + + @Override + public JonIrenicusShatteredOneEffect copy() { + return new JonIrenicusShatteredOneEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player opponent = game.getPlayer(source.getTargets().get(0).getFirstTarget()); + Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (creature == null || opponent == null) { + return false; + } + ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame, opponent.getId()); + effect.setTargetPointer(new FixedTarget(creature, game)); + game.addEffect(effect, source); + game.getState().processAction(game); + creature.addCounters(CounterType.P1P1.createInstance(2), source.getControllerId(), source, game); + creature.tap(source, game); + game.addEffect(new GoadTargetEffect() + .setDuration(Duration.EndOfGame) + .setTargetPointer(new FixedTarget(creature, game)), + source + ); + game.addEffect(new GainAbilityTargetEffect( + new SimpleStaticAbility(new CantBeSacrificedSourceEffect().setText("This creature can't be sacrificed")), + Duration.Custom + ).setTargetPointer(new FixedTarget(creature, game)), source); + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/j/JunglePatrol.java b/Mage.Sets/src/mage/cards/j/JunglePatrol.java index 05b392c16fb..45605385062 100644 --- a/Mage.Sets/src/mage/cards/j/JunglePatrol.java +++ b/Mage.Sets/src/mage/cards/j/JunglePatrol.java @@ -52,7 +52,7 @@ public final class JunglePatrol extends CardImpl { // Sacrifice a token named Wood: Add {R}. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new BasicManaEffect(Mana.RedMana(1), new PermanentsOnBattlefieldCount(filter)), - new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true)))); + new SacrificeTargetCost(filter))); } private JunglePatrol(final JunglePatrol card) { diff --git a/Mage.Sets/src/mage/cards/k/KalitasTraitorOfGhet.java b/Mage.Sets/src/mage/cards/k/KalitasTraitorOfGhet.java index 4482007c7b3..8135ccc310d 100644 --- a/Mage.Sets/src/mage/cards/k/KalitasTraitorOfGhet.java +++ b/Mage.Sets/src/mage/cards/k/KalitasTraitorOfGhet.java @@ -57,7 +57,7 @@ public final class KalitasTraitorOfGhet extends CardImpl { // {2}{B}, Sacrifice another Vampire or Zombie: Put two +1/+1 counters on Kalitas, Traitor of Ghet. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{2}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KardursViciousReturn.java b/Mage.Sets/src/mage/cards/k/KardursViciousReturn.java index 86fde8115ed..5c5f6046ff1 100644 --- a/Mage.Sets/src/mage/cards/k/KardursViciousReturn.java +++ b/Mage.Sets/src/mage/cards/k/KardursViciousReturn.java @@ -46,7 +46,7 @@ public final class KardursViciousReturn extends CardImpl { ); ability.addTarget(new TargetAnyTarget()); sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new DoWhenCostPaid( - ability, new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)), + ability, new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), "Sacrifice a creature?" )); diff --git a/Mage.Sets/src/mage/cards/k/KeldonArsonist.java b/Mage.Sets/src/mage/cards/k/KeldonArsonist.java index fa34917323a..ac07a4e856d 100644 --- a/Mage.Sets/src/mage/cards/k/KeldonArsonist.java +++ b/Mage.Sets/src/mage/cards/k/KeldonArsonist.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetLandPermanent; @@ -32,7 +33,7 @@ public final class KeldonArsonist extends CardImpl { // {1}, Sacrifice two lands: Destroy target land. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS)); TargetLandPermanent target = new TargetLandPermanent(); target.setTargetName("land (to destroy)"); ability.addTarget(target); diff --git a/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java b/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java index 80310f6819f..ef4bae4481b 100644 --- a/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java +++ b/Mage.Sets/src/mage/cards/k/KeldonFirebombers.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterLandPermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; @@ -20,6 +21,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetLandPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -52,8 +54,6 @@ public final class KeldonFirebombers extends CardImpl { class KeldonFirebombersEffect extends OneShotEffect { - private static final FilterLandPermanent filter = new FilterLandPermanent(); - public KeldonFirebombersEffect() { super(Outcome.AIDontUseIt); this.staticText = "each player sacrifices all lands they control except for three"; @@ -74,11 +74,9 @@ class KeldonFirebombersEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - int amount = game.getBattlefield().getAllActivePermanents(filter, playerId, game).size() - 3; + int amount = game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_LANDS, playerId, game).size() - 3; if (amount > 0) { - FilterLandPermanent playerFilter = filter.copy(); - playerFilter.add(new ControllerIdPredicate(playerId)); - Target target = new TargetLandPermanent(amount, amount, playerFilter, true); + Target target = new TargetSacrifice(amount, StaticFilters.FILTER_LANDS); player.choose(outcome.Sacrifice, target, source, game); for (UUID landId : target.getTargets()) { Permanent land = game.getPermanent(landId); diff --git a/Mage.Sets/src/mage/cards/k/KelsFightFixer.java b/Mage.Sets/src/mage/cards/k/KelsFightFixer.java index 9194b64105b..e4b8e278ccb 100644 --- a/Mage.Sets/src/mage/cards/k/KelsFightFixer.java +++ b/Mage.Sets/src/mage/cards/k/KelsFightFixer.java @@ -46,7 +46,7 @@ public final class KelsFightFixer extends CardImpl { Ability ability = new SimpleActivatedAbility(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java b/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java index ae93540a7c2..cf327e22ed7 100644 --- a/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java +++ b/Mage.Sets/src/mage/cards/k/KeskitTheFleshSculptor.java @@ -51,7 +51,7 @@ public final class KeskitTheFleshSculptor extends CardImpl { Ability ability = new SimpleActivatedAbility( new LookLibraryAndPickControllerEffect(3, 2, PutCards.HAND, PutCards.GRAVEYARD), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter))); + ability.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(ability); // Partner diff --git a/Mage.Sets/src/mage/cards/k/KethekCrucibleGoliath.java b/Mage.Sets/src/mage/cards/k/KethekCrucibleGoliath.java index d04ab0b57af..82e2030fc1a 100644 --- a/Mage.Sets/src/mage/cards/k/KethekCrucibleGoliath.java +++ b/Mage.Sets/src/mage/cards/k/KethekCrucibleGoliath.java @@ -17,6 +17,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -79,9 +80,7 @@ class KethekCrucibleGoliathEffect extends OneShotEffect { return false; } // May sacrifice another creature - TargetPermanent target = (TargetPermanent) new TargetControlledPermanent( - 0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true - ).withChooseHint("to sacrifice"); + TargetSacrifice target = new TargetSacrifice(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null || !permanent.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/k/KheruBloodsucker.java b/Mage.Sets/src/mage/cards/k/KheruBloodsucker.java index b780e258a28..4ec6296a2bf 100644 --- a/Mage.Sets/src/mage/cards/k/KheruBloodsucker.java +++ b/Mage.Sets/src/mage/cards/k/KheruBloodsucker.java @@ -54,7 +54,7 @@ public final class KheruBloodsucker extends CardImpl { // {2}{B}, Sacrifice another creature: Put a +1/+1 counter on Kheru Bloodsucker. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{2}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java b/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java index 71099bfb4a3..c55b6befaa7 100644 --- a/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java +++ b/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java @@ -40,7 +40,7 @@ public final class KheruDreadmaw extends CardImpl { Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance); effect.setText("You gain life equal to the sacrificed creature's toughness"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KjeldoranOutpost.java b/Mage.Sets/src/mage/cards/k/KjeldoranOutpost.java index 62881e3666d..b5fabae1b06 100644 --- a/Mage.Sets/src/mage/cards/k/KjeldoranOutpost.java +++ b/Mage.Sets/src/mage/cards/k/KjeldoranOutpost.java @@ -36,7 +36,7 @@ public final class KjeldoranOutpost extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},""); // If Kjeldoran Outpost would enter the battlefield, sacrifice a Plains instead. If you do, put Kjeldoran Outpost onto the battlefield. If you don't, put it into its owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(filter)))); // {tap}: Add {W}. this.addAbility(new WhiteManaAbility()); // {1}{W}, {tap}: Create a 1/1 white Soldier creature token. diff --git a/Mage.Sets/src/mage/cards/k/KnightCaptainOfEos.java b/Mage.Sets/src/mage/cards/k/KnightCaptainOfEos.java index d92c6b4211b..c47438420c9 100644 --- a/Mage.Sets/src/mage/cards/k/KnightCaptainOfEos.java +++ b/Mage.Sets/src/mage/cards/k/KnightCaptainOfEos.java @@ -41,7 +41,7 @@ public final class KnightCaptainOfEos extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new SoldierToken(), 2), false)); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true), new ManaCostsImpl<>("{W}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KnightOfTheLastBreath.java b/Mage.Sets/src/mage/cards/k/KnightOfTheLastBreath.java index 354a378fc90..1d1d03e2ccb 100644 --- a/Mage.Sets/src/mage/cards/k/KnightOfTheLastBreath.java +++ b/Mage.Sets/src/mage/cards/k/KnightOfTheLastBreath.java @@ -45,7 +45,7 @@ public final class KnightOfTheLastBreath extends CardImpl { Ability ability = new SimpleActivatedAbility( new CreateTokenEffect(new WhiteBlackSpiritToken()), new GenericManaCost(3) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // Afterlife 3 diff --git a/Mage.Sets/src/mage/cards/k/KomaCosmosSerpent.java b/Mage.Sets/src/mage/cards/k/KomaCosmosSerpent.java index bed4aaab4fe..9da78763954 100644 --- a/Mage.Sets/src/mage/cards/k/KomaCosmosSerpent.java +++ b/Mage.Sets/src/mage/cards/k/KomaCosmosSerpent.java @@ -56,7 +56,7 @@ public final class KomaCosmosSerpent extends CardImpl { // Sacrifice another Serpent: Choose one — // • Tap target permanent. Its activated abilities can't be activated this turn. Ability ability = new SimpleActivatedAbility( - new TapTargetEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new TapTargetEffect(), new SacrificeTargetCost(filter) ); ability.addEffect(new KomaCosmosSerpentEffect()); ability.addTarget(new TargetPermanent()); diff --git a/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java b/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java index 26346760b3f..0d13a43b9d5 100644 --- a/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java +++ b/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java @@ -56,7 +56,7 @@ public final class KorozdaGuildmage extends CardImpl { // {2}{B}{G}, Sacrifice a nontoken creature: create X 1/1 green Saproling creature tokens, where X is the sacrificed creature's toughness. ability = new SimpleActivatedAbility(new CreateTokenEffect(new SaprolingToken(),SacrificeCostCreaturesToughness.instance),new ManaCostsImpl<>("{2}{B}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanEngineers.java b/Mage.Sets/src/mage/cards/k/KrarkClanEngineers.java index e0b08ca163f..9900e94f618 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanEngineers.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanEngineers.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,7 +34,7 @@ public final class KrarkClanEngineers extends CardImpl { // {R}, Sacrifice two artifacts: Destroy target artifact. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl<>("{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledArtifactPermanent("artifacts"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_ARTIFACTS)); ability.addTarget(new TargetArtifactPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanGrunt.java b/Mage.Sets/src/mage/cards/k/KrarkClanGrunt.java index 03ab95cf34d..365cf44bd8b 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanGrunt.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanGrunt.java @@ -40,7 +40,7 @@ public final class KrarkClanGrunt extends CardImpl { // Sacrifice an artifact: Krark-Clan Grunt gets +1/+0 and gains first strike until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn) - .setText("{this} gets +1/+0"), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + .setText("{this} gets +1/+0"), new SacrificeTargetCost(filter)); ability.addEffect(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn) .setText("and gains first strike until end of turn")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanIronworks.java b/Mage.Sets/src/mage/cards/k/KrarkClanIronworks.java index a946495aa76..7e07b4ef734 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanIronworks.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanIronworks.java @@ -26,7 +26,7 @@ public final class KrarkClanIronworks extends CardImpl { // Sacrifice an artifact: Add {C}{C}. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(2), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact"))), + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT), new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanOgre.java b/Mage.Sets/src/mage/cards/k/KrarkClanOgre.java index 93acf859a00..feea7369f40 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanOgre.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanOgre.java @@ -14,6 +14,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; @@ -33,7 +34,7 @@ public final class KrarkClanOgre extends CardImpl { // {R}, Sacrifice an artifact: Target creature can't block this turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent("an artifact"), true))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanShaman.java b/Mage.Sets/src/mage/cards/k/KrarkClanShaman.java index 08e265b5764..b68e8e98d1b 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanShaman.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanShaman.java @@ -39,7 +39,7 @@ public final class KrarkClanShaman extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filterTargetedCreatures), new SacrificeTargetCost(new TargetControlledPermanent(filterSacrificed)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filterTargetedCreatures), new SacrificeTargetCost(filterSacrificed))); } private KrarkClanShaman(final KrarkClanShaman card) { diff --git a/Mage.Sets/src/mage/cards/k/KrarkClanStoker.java b/Mage.Sets/src/mage/cards/k/KrarkClanStoker.java index 3aaecc4d0a8..01918be7cf8 100644 --- a/Mage.Sets/src/mage/cards/k/KrarkClanStoker.java +++ b/Mage.Sets/src/mage/cards/k/KrarkClanStoker.java @@ -14,6 +14,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -32,7 +33,7 @@ public final class KrarkClanStoker extends CardImpl { // {T}, Sacrifice an artifact: Add {R}{R}. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.RedMana(2), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KukemssaSerpent.java b/Mage.Sets/src/mage/cards/k/KukemssaSerpent.java index 166d6050044..85881e30bab 100644 --- a/Mage.Sets/src/mage/cards/k/KukemssaSerpent.java +++ b/Mage.Sets/src/mage/cards/k/KukemssaSerpent.java @@ -46,7 +46,7 @@ public final class KukemssaSerpent extends CardImpl { // {U}, Sacrifice an Island: Target land an opponent controls becomes an Island until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesBasicLandTargetEffect(Duration.EndOfTurn, SubType.ISLAND), new ManaCostsImpl<>("{U}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filterControlledLand, true))); + ability.addCost(new SacrificeTargetCost(filterControlledLand)); ability.addTarget(new TargetLandPermanent(filterOpponentLand)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/k/KuldothaFlamefiend.java b/Mage.Sets/src/mage/cards/k/KuldothaFlamefiend.java index c89a37a98e6..c844636eea9 100644 --- a/Mage.Sets/src/mage/cards/k/KuldothaFlamefiend.java +++ b/Mage.Sets/src/mage/cards/k/KuldothaFlamefiend.java @@ -29,7 +29,7 @@ public final class KuldothaFlamefiend extends CardImpl { // When Kuldotha Flamefiend enters the battlefield, you may sacrifice an artifact. If you do, Kuldotha Flamefiend deals 4 damage divided as you choose among any number of targets. EntersBattlefieldTriggeredAbility ability = - new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new DamageMultiEffect(4), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))), false); + new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(new DamageMultiEffect(4), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)), false); ability.addTarget(new TargetAnyTargetAmount(4)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KuldothaForgemaster.java b/Mage.Sets/src/mage/cards/k/KuldothaForgemaster.java index 88aadc7c143..692a94c24ad 100644 --- a/Mage.Sets/src/mage/cards/k/KuldothaForgemaster.java +++ b/Mage.Sets/src/mage/cards/k/KuldothaForgemaster.java @@ -37,7 +37,7 @@ public final class KuldothaForgemaster extends CardImpl { SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterArtifactCard())), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter))); + ability.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KuldothaRebirth.java b/Mage.Sets/src/mage/cards/k/KuldothaRebirth.java index 1158e0f46f3..bee0a093ad9 100644 --- a/Mage.Sets/src/mage/cards/k/KuldothaRebirth.java +++ b/Mage.Sets/src/mage/cards/k/KuldothaRebirth.java @@ -27,7 +27,7 @@ public final class KuldothaRebirth extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}"); this.getSpellAbility().addEffect(new CreateTokenEffect(new GoblinToken(), 3)); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); } private KuldothaRebirth(final KuldothaRebirth card) { diff --git a/Mage.Sets/src/mage/cards/k/KykarWindsFury.java b/Mage.Sets/src/mage/cards/k/KykarWindsFury.java index d018cb17052..ae3a25c11c3 100644 --- a/Mage.Sets/src/mage/cards/k/KykarWindsFury.java +++ b/Mage.Sets/src/mage/cards/k/KykarWindsFury.java @@ -51,7 +51,7 @@ public final class KykarWindsFury extends CardImpl { // Sacrifice a Spirit: Add {R}. this.addAbility(new SimpleManaAbility( Zone.BATTLEFIELD, new BasicManaEffect(Mana.RedMana(1), new PermanentsOnBattlefieldCount(filter)), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) )); } diff --git a/Mage.Sets/src/mage/cards/k/KyscuDrake.java b/Mage.Sets/src/mage/cards/k/KyscuDrake.java index b610fab9140..395c8755864 100644 --- a/Mage.Sets/src/mage/cards/k/KyscuDrake.java +++ b/Mage.Sets/src/mage/cards/k/KyscuDrake.java @@ -49,7 +49,7 @@ public final class KyscuDrake extends CardImpl { this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(0, 1, Duration.EndOfTurn), new ManaCostsImpl<>("{G}"))); // Sacrifice Kyscu Drake and a creature named Spitting Drake: Search your library for a card named Viashivan Dragon and put that card onto the battlefield. Then shuffle your library. - this.addAbility(new SimpleActivatedAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(1, 1, filter), false, true), new CompositeCost(new SacrificeSourceCost(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filterSpitting, false)), "sacrifice {this} and a creature named Spitting Drake"))); + this.addAbility(new SimpleActivatedAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(1, 1, filter), false, true), new CompositeCost(new SacrificeSourceCost(), new SacrificeTargetCost(filterSpitting), "sacrifice {this} and a creature named Spitting Drake"))); } private KyscuDrake(final KyscuDrake card) { diff --git a/Mage.Sets/src/mage/cards/l/LakeOfTheDead.java b/Mage.Sets/src/mage/cards/l/LakeOfTheDead.java index 1fca0a9dcca..8fb3e8e6e8e 100644 --- a/Mage.Sets/src/mage/cards/l/LakeOfTheDead.java +++ b/Mage.Sets/src/mage/cards/l/LakeOfTheDead.java @@ -34,13 +34,13 @@ public final class LakeOfTheDead extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},""); // If Lake of the Dead would enter the battlefield, sacrifice a Swamp instead. If you do, put Lake of the Dead onto the battlefield. If you don't, put it into its owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(filter)))); // {tap}: Add {B}. this.addAbility(new BlackManaAbility()); // {tap}, Sacrifice a Swamp: Add {B}{B}{B}{B}. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, Mana.BlackMana(4), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/LampadOfDeathsVigil.java b/Mage.Sets/src/mage/cards/l/LampadOfDeathsVigil.java index afb64653172..1dd76a2db93 100644 --- a/Mage.Sets/src/mage/cards/l/LampadOfDeathsVigil.java +++ b/Mage.Sets/src/mage/cards/l/LampadOfDeathsVigil.java @@ -31,9 +31,7 @@ public final class LampadOfDeathsVigil extends CardImpl { // {1}, Sacrifice a creature: Each opponent loses 1 life and you gain 1 life. Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(1), new GenericManaCost(1)); ability.addEffect(new GainLifeEffect(1).concatBy("and")); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/LastDitchEffort.java b/Mage.Sets/src/mage/cards/l/LastDitchEffort.java index bb6fba665e0..caafad37c97 100644 --- a/Mage.Sets/src/mage/cards/l/LastDitchEffort.java +++ b/Mage.Sets/src/mage/cards/l/LastDitchEffort.java @@ -6,6 +6,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -13,6 +14,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -59,27 +61,24 @@ class LastDitchEffortEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, new FilterControlledCreaturePermanent(), true); - player.chooseTarget(Outcome.Sacrifice, target, source, game); + Target target = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT_CREATURES); + player.choose(Outcome.Sacrifice, target, source, game); int numSacrificed = 0; for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); - if (permanent != null) { - if (permanent.sacrifice(source, game)) { - numSacrificed++; - } + if (permanent != null && permanent.sacrifice(source, game)) { + numSacrificed++; } } if (numSacrificed > 0) { - int damage = numSacrificed; UUID uuid = this.getTargetPointer().getFirst(game, source); Permanent permanent = game.getPermanent(uuid); Player opponent = game.getPlayer(uuid); if (permanent != null) { - permanent.damage(damage, source.getSourceId(), source, game, false, true); + permanent.damage(numSacrificed, source.getSourceId(), source, game, false, true); } if (opponent != null) { - opponent.damage(damage, source.getSourceId(), source, game); + opponent.damage(numSacrificed, source.getSourceId(), source, game); } } return true; diff --git a/Mage.Sets/src/mage/cards/l/LavaDart.java b/Mage.Sets/src/mage/cards/l/LavaDart.java index 8842cc5176a..3977276fe3c 100644 --- a/Mage.Sets/src/mage/cards/l/LavaDart.java +++ b/Mage.Sets/src/mage/cards/l/LavaDart.java @@ -34,7 +34,7 @@ public final class LavaDart extends CardImpl { this.getSpellAbility().addTarget(new TargetAnyTarget()); // Flashback-Sacrifice a Mountain. - this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new FlashbackAbility(this, new SacrificeTargetCost(filter))); } private LavaDart(final LavaDart card) { diff --git a/Mage.Sets/src/mage/cards/l/LegionVanguard.java b/Mage.Sets/src/mage/cards/l/LegionVanguard.java index 68cca9d72aa..347bdb84840 100644 --- a/Mage.Sets/src/mage/cards/l/LegionVanguard.java +++ b/Mage.Sets/src/mage/cards/l/LegionVanguard.java @@ -32,9 +32,7 @@ public final class LegionVanguard extends CardImpl { Ability ability = new SimpleActivatedAbility( new ExploreSourceEffect(true, "{this}"), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/Leviathan.java b/Mage.Sets/src/mage/cards/l/Leviathan.java index 05662fbbbd7..0e4d362d130 100644 --- a/Mage.Sets/src/mage/cards/l/Leviathan.java +++ b/Mage.Sets/src/mage/cards/l/Leviathan.java @@ -60,7 +60,7 @@ public final class Leviathan extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility( Zone.BATTLEFIELD, new DoIfCostPaid(new UntapSourceEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, false))), + new SacrificeTargetCost(2, filter)), TargetController.YOU, false)); @@ -89,7 +89,7 @@ class LeviathanCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl { LeviathanCostToAttackBlockEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK, - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, false))); + new SacrificeTargetCost(2, filter)); staticText = "{this} can't attack unless you sacrifice two Islands. (This cost is paid as attackers are declared.)"; } diff --git a/Mage.Sets/src/mage/cards/l/Lich.java b/Mage.Sets/src/mage/cards/l/Lich.java index d583939e99b..8c0068ca351 100644 --- a/Mage.Sets/src/mage/cards/l/Lich.java +++ b/Mage.Sets/src/mage/cards/l/Lich.java @@ -28,6 +28,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -167,7 +168,7 @@ class LichDamageEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Target target = new TargetControlledPermanent(amount, amount, filter, true); + TargetSacrifice target = new TargetSacrifice(amount, filter); if (target.canChoose(controller.getId(), source, game)) { if (controller.choose(Outcome.Sacrifice, target, source, game)) { for (UUID targetId : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/l/LichKnightsConquest.java b/Mage.Sets/src/mage/cards/l/LichKnightsConquest.java index fbd058c1ad4..14e607d95b3 100644 --- a/Mage.Sets/src/mage/cards/l/LichKnightsConquest.java +++ b/Mage.Sets/src/mage/cards/l/LichKnightsConquest.java @@ -20,6 +20,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTargets; import mage.util.CardUtil; @@ -84,7 +85,7 @@ class LichKnightsConquestEffect extends OneShotEffect { return false; } - Target target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); + Target target = new TargetSacrifice(0, Integer.MAX_VALUE, filter); if (!target.canChoose(source.getControllerId(), source, game)) { return false; } @@ -128,4 +129,4 @@ class LichKnightsConquestEffect extends OneShotEffect { return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/l/LiegeOfThePit.java b/Mage.Sets/src/mage/cards/l/LiegeOfThePit.java index 04649dab75d..bc5995508a8 100644 --- a/Mage.Sets/src/mage/cards/l/LiegeOfThePit.java +++ b/Mage.Sets/src/mage/cards/l/LiegeOfThePit.java @@ -18,6 +18,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -83,7 +84,7 @@ class LiegeOfThePitEffect extends OneShotEffect { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature other than " + sourcePermanent.getName()); filter.add(AnotherPredicate.instance); - Target target = new TargetControlledCreaturePermanent(1, 1, filter, true); + Target target = new TargetSacrifice(filter); if (target.canChoose(player.getId(), source, game)) { player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/l/Lifespinner.java b/Mage.Sets/src/mage/cards/l/Lifespinner.java index d6a4d016c66..db49ac4e601 100644 --- a/Mage.Sets/src/mage/cards/l/Lifespinner.java +++ b/Mage.Sets/src/mage/cards/l/Lifespinner.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; +import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterPermanentCard; import mage.target.common.TargetCardInLibrary; @@ -25,6 +26,7 @@ import mage.target.common.TargetControlledPermanent; public final class Lifespinner extends CardImpl { private static final FilterPermanentCard filter = new FilterPermanentCard("legendary Spirit permanent card"); + private static final FilterPermanent filterSac = new FilterPermanent(SubType.SPIRIT, "Spirits"); static { filter.add(SuperType.LEGENDARY.getPredicate()); @@ -42,7 +44,7 @@ public final class Lifespinner extends CardImpl { SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter)), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, new FilterControlledCreaturePermanent(SubType.SPIRIT, "Spirits"), false))); + ability.addCost(new SacrificeTargetCost(3, filterSac)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/Lithatog.java b/Mage.Sets/src/mage/cards/l/Lithatog.java index 8cd756b74bf..8c1350000cd 100644 --- a/Mage.Sets/src/mage/cards/l/Lithatog.java +++ b/Mage.Sets/src/mage/cards/l/Lithatog.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,12 +34,12 @@ public final class Lithatog extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact"))))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT))); // Sacrifice a land: Lithatog gets +1/+1 until end of turn. this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND))); } private Lithatog(final Lithatog card) { diff --git a/Mage.Sets/src/mage/cards/l/Lithophage.java b/Mage.Sets/src/mage/cards/l/Lithophage.java index 0960039e339..57923749804 100644 --- a/Mage.Sets/src/mage/cards/l/Lithophage.java +++ b/Mage.Sets/src/mage/cards/l/Lithophage.java @@ -35,7 +35,7 @@ public final class Lithophage extends CardImpl { // At the beginning of your upkeep, sacrifice Lithophage unless you sacrifice a Mountain. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))), TargetController.YOU, false)); + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)), TargetController.YOU, false)); } private Lithophage(final Lithophage card) { diff --git a/Mage.Sets/src/mage/cards/l/LochmereSerpent.java b/Mage.Sets/src/mage/cards/l/LochmereSerpent.java index 0ca107fe5e3..5d953715c20 100644 --- a/Mage.Sets/src/mage/cards/l/LochmereSerpent.java +++ b/Mage.Sets/src/mage/cards/l/LochmereSerpent.java @@ -49,13 +49,13 @@ public final class LochmereSerpent extends CardImpl { Ability ability = new SimpleActivatedAbility( new CantBeBlockedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{U}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter1))); + ability.addCost(new SacrificeTargetCost(filter1)); this.addAbility(ability); // {B}, Sacrifice a Swamp: You gain 1 life and draw a card. ability = new SimpleActivatedAbility(new GainLifeEffect(1), new ManaCostsImpl<>("{B}")); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); // {U}{B}: Exile five target cards from an opponent's graveyard. Return Lochmere Serpent from your graveyard to your hand. Activate this ability only any time you could cast a sorcery. diff --git a/Mage.Sets/src/mage/cards/l/LordOfTheForsaken.java b/Mage.Sets/src/mage/cards/l/LordOfTheForsaken.java index 2038e8ca703..4ccec2729d5 100644 --- a/Mage.Sets/src/mage/cards/l/LordOfTheForsaken.java +++ b/Mage.Sets/src/mage/cards/l/LordOfTheForsaken.java @@ -51,9 +51,7 @@ public final class LordOfTheForsaken extends CardImpl { Ability ability = new SimpleActivatedAbility( new MillCardsTargetEffect(3), new ManaCostsImpl<>("{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LordOfThePit.java b/Mage.Sets/src/mage/cards/l/LordOfThePit.java index e99a7029bc5..e0462bd7dea 100644 --- a/Mage.Sets/src/mage/cards/l/LordOfThePit.java +++ b/Mage.Sets/src/mage/cards/l/LordOfThePit.java @@ -16,6 +16,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -79,7 +80,7 @@ class LordOfThePitEffect extends OneShotEffect { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature other than " + sourcePermanent.getName()); filter.add(AnotherPredicate.instance); - Target target = new TargetControlledCreaturePermanent(1, 1, filter, true); + Target target = new TargetSacrifice(filter); if (target.canChoose(player.getId(), source, game)) { player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/l/LotusVale.java b/Mage.Sets/src/mage/cards/l/LotusVale.java index e34e42d9644..0f46d6ef8ce 100644 --- a/Mage.Sets/src/mage/cards/l/LotusVale.java +++ b/Mage.Sets/src/mage/cards/l/LotusVale.java @@ -33,7 +33,7 @@ public final class LotusVale extends CardImpl { // If Lotus Vale would enter the battlefield, sacrifice two untapped lands instead. If you do, put Lotus Vale onto the battlefield. If you don't, put it into its owner's graveyard. this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect( - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, false))))); + new SacrificeTargetCost(2, filter)))); // {tap}: Add three mana of any one color. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(3), new TapSourceCost())); diff --git a/Mage.Sets/src/mage/cards/l/LunarchMantle.java b/Mage.Sets/src/mage/cards/l/LunarchMantle.java index 6bb7a8473ee..05b6b51874f 100644 --- a/Mage.Sets/src/mage/cards/l/LunarchMantle.java +++ b/Mage.Sets/src/mage/cards/l/LunarchMantle.java @@ -21,6 +21,7 @@ import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; @@ -48,7 +49,7 @@ public final class LunarchMantle extends CardImpl { SimpleStaticAbility ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)); Ability abilityToGain = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl<>("{1}")); - abilityToGain.addCost(new SacrificeTargetCost(new TargetControlledPermanent())); + abilityToGain.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT)); ability2.addEffect(new GainAbilityAttachedEffect(abilityToGain, AttachmentType.AURA, Duration.WhileOnBattlefield, rule)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/m/MagdaBrazenOutlaw.java b/Mage.Sets/src/mage/cards/m/MagdaBrazenOutlaw.java index 4bf4651f7c4..18718c44a1f 100644 --- a/Mage.Sets/src/mage/cards/m/MagdaBrazenOutlaw.java +++ b/Mage.Sets/src/mage/cards/m/MagdaBrazenOutlaw.java @@ -59,7 +59,7 @@ public final class MagdaBrazenOutlaw extends CardImpl { // Sacrifice five Treasures: Search your library for an artifact or Dragon card, put that card onto the battlefield, then shuffle your library. this.addAbility(new SimpleActivatedAbility( new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter3), false, true), - new SacrificeTargetCost(new TargetControlledPermanent(5, filter4)) + new SacrificeTargetCost(5, filter4) )); } diff --git a/Mage.Sets/src/mage/cards/m/MagmaBurst.java b/Mage.Sets/src/mage/cards/m/MagmaBurst.java index fae373be57d..6623ce6ef42 100644 --- a/Mage.Sets/src/mage/cards/m/MagmaBurst.java +++ b/Mage.Sets/src/mage/cards/m/MagmaBurst.java @@ -9,6 +9,7 @@ import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetAnyTarget; @@ -26,8 +27,7 @@ public final class MagmaBurst extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{R}"); // Kicker-Sacrifice two lands. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, - new FilterControlledLandPermanent("lands"), true)))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS))); // Magma Burst deals 3 damage to any target. If Magma Burst was kicked, it deals 3 damage to another any target. Effect effect = new DamageTargetEffect(3); @@ -53,4 +53,4 @@ enum MagmaBurstAdjuster implements TargetAdjuster { public void adjustTargets(Ability ability, Game game) { ability.addTarget(new TargetAnyTarget(KickedCondition.ONCE.apply(game, ability) ? 2 : 1)); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MagmaRift.java b/Mage.Sets/src/mage/cards/m/MagmaRift.java index ae116988883..2b8a5eb6a5e 100644 --- a/Mage.Sets/src/mage/cards/m/MagmaRift.java +++ b/Mage.Sets/src/mage/cards/m/MagmaRift.java @@ -21,7 +21,7 @@ public final class MagmaRift extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); // As an additional cost to cast Magma Rift, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); // Magma Rift deals 5 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(5)); diff --git a/Mage.Sets/src/mage/cards/m/MagmaVein.java b/Mage.Sets/src/mage/cards/m/MagmaVein.java index eff727e4227..6c5e35b1b82 100644 --- a/Mage.Sets/src/mage/cards/m/MagmaVein.java +++ b/Mage.Sets/src/mage/cards/m/MagmaVein.java @@ -38,7 +38,7 @@ public final class MagmaVein extends CardImpl { // {R}, Sacrifice a land: Magma Vein deals 1 damage to each creature without flying. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filter1), new ManaCostsImpl<>("{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/Magmaw.java b/Mage.Sets/src/mage/cards/m/Magmaw.java index 99f84354340..83ff87cd642 100644 --- a/Mage.Sets/src/mage/cards/m/Magmaw.java +++ b/Mage.Sets/src/mage/cards/m/Magmaw.java @@ -37,7 +37,7 @@ public final class Magmaw extends CardImpl { this.toughness = new MageInt(4); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheOrder.java b/Mage.Sets/src/mage/cards/m/MagusOfTheOrder.java index d6491cb1499..2a76e8cbe86 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheOrder.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheOrder.java @@ -54,7 +54,7 @@ public final class MagusOfTheOrder extends CardImpl { ), new ManaCostsImpl<>("{G}")); ability.addCost(new TapSourceCost()); ability.addCost(new CompositeCost( - new SacrificeSourceCost(), new SacrificeTargetCost(new TargetControlledPermanent(filter2)), + new SacrificeSourceCost(), new SacrificeTargetCost(filter2), "sacrifice Magus of the Order and another green creature" )); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MakeAnExample.java b/Mage.Sets/src/mage/cards/m/MakeAnExample.java index 8e58ca42e0a..a6ea9e663d3 100644 --- a/Mage.Sets/src/mage/cards/m/MakeAnExample.java +++ b/Mage.Sets/src/mage/cards/m/MakeAnExample.java @@ -16,6 +16,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -71,8 +72,8 @@ class MakeAnExampleEffect extends OneShotEffect { if (opponent == null) { continue; } - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, filter, true); - opponent.chooseTarget(Outcome.Sacrifice, target, source, game); + TargetSacrifice target = new TargetSacrifice(0, Integer.MAX_VALUE, filter); + opponent.choose(Outcome.Sacrifice, target, source, game); List chosenTargets = target.getTargets(); List pile1 = new ArrayList<>(); List pile2 = new ArrayList<>(); diff --git a/Mage.Sets/src/mage/cards/m/MalevolentNoble.java b/Mage.Sets/src/mage/cards/m/MalevolentNoble.java index 71c8dec34a5..9ee7b4b9c23 100644 --- a/Mage.Sets/src/mage/cards/m/MalevolentNoble.java +++ b/Mage.Sets/src/mage/cards/m/MalevolentNoble.java @@ -44,7 +44,7 @@ public final class MalevolentNoble extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MalevolentWitchkite.java b/Mage.Sets/src/mage/cards/m/MalevolentWitchkite.java index 38bb7c452df..317673c5349 100644 --- a/Mage.Sets/src/mage/cards/m/MalevolentWitchkite.java +++ b/Mage.Sets/src/mage/cards/m/MalevolentWitchkite.java @@ -20,6 +20,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTargets; import mage.util.CardUtil; @@ -92,12 +93,12 @@ class MalevolentWitchkiteEffect extends OneShotEffect { return false; } - Target target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); + Target target = new TargetSacrifice(0, Integer.MAX_VALUE, filter); if (!target.canChoose(source.getControllerId(), source, game)) { return false; } - controller.chooseTarget(Outcome.Sacrifice, target, source, game); + controller.choose(Outcome.Sacrifice, target, source, game); List toSacrifice = target .getTargets() .stream() @@ -120,4 +121,4 @@ class MalevolentWitchkiteEffect extends OneShotEffect { return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/ManaSeism.java b/Mage.Sets/src/mage/cards/m/ManaSeism.java index 0e5c577378d..ac00a0a908e 100644 --- a/Mage.Sets/src/mage/cards/m/ManaSeism.java +++ b/Mage.Sets/src/mage/cards/m/ManaSeism.java @@ -9,11 +9,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -63,11 +65,11 @@ class ManaSeismEffect extends OneShotEffect { return false; } int amount = 0; - TargetControlledPermanent sacrificeLand = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledLandPermanent(), true); - if(player.chooseTarget(Outcome.Sacrifice, sacrificeLand, source, game)){ - for(UUID uuid : sacrificeLand.getTargets()){ + TargetSacrifice sacrificeLand = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_LAND); + if (player.choose(Outcome.Sacrifice, sacrificeLand, source, game)) { + for (UUID uuid : sacrificeLand.getTargets()) { Permanent land = game.getPermanent(uuid); - if(land != null){ + if (land != null) { land.sacrifice(source, game); amount++; } diff --git a/Mage.Sets/src/mage/cards/m/ManaVortex.java b/Mage.Sets/src/mage/cards/m/ManaVortex.java index 50f8bd4b95c..78432e52f72 100644 --- a/Mage.Sets/src/mage/cards/m/ManaVortex.java +++ b/Mage.Sets/src/mage/cards/m/ManaVortex.java @@ -84,7 +84,7 @@ class CounterSourceEffect extends OneShotEffect { if(spell != null){ Player controller = game.getPlayer(source.getControllerId()); if(controller != null && controller.chooseUse(Outcome.Detriment, "Sacrifice a land to not counter " + spell.getName() + '?', source, game)){ - SacrificeTargetCost cost = new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent())); + SacrificeTargetCost cost = new SacrificeTargetCost(StaticFilters.FILTER_LAND); if(cost.pay(source, game, source, source.getControllerId(), false, null)){ game.informPlayers(controller.getLogName() + " sacrifices a land to not counter " + spell.getName() + '.'); return true; @@ -119,4 +119,4 @@ class ManaVortexStateTriggeredAbility extends StateTriggeredAbility { public boolean checkTrigger(GameEvent event, Game game) { return game.getBattlefield().count(StaticFilters.FILTER_LANDS, this.getControllerId(), this, game) == 0; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MaraleafRider.java b/Mage.Sets/src/mage/cards/m/MaraleafRider.java index 0c81a7f7beb..9b45ba61904 100644 --- a/Mage.Sets/src/mage/cards/m/MaraleafRider.java +++ b/Mage.Sets/src/mage/cards/m/MaraleafRider.java @@ -30,7 +30,7 @@ public final class MaraleafRider extends CardImpl { // Sacrifice a Food: Target creature blocks Maraleaf Rider this turn if able. Ability ability = new SimpleActivatedAbility( - new MustBeBlockedByTargetSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD)) + new MustBeBlockedByTargetSourceEffect(), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD) ); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MarrowGnawer.java b/Mage.Sets/src/mage/cards/m/MarrowGnawer.java index acef9ce38fa..930733a9516 100644 --- a/Mage.Sets/src/mage/cards/m/MarrowGnawer.java +++ b/Mage.Sets/src/mage/cards/m/MarrowGnawer.java @@ -46,7 +46,7 @@ public final class MarrowGnawer extends CardImpl { // {T}, Sacrifice a Rat: create X 1/1 black Rat creature tokens, where X is the number of Rats you control. Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new RatToken(), xValue), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterSacrifice))); + ability.addCost(new SacrificeTargetCost(filterSacrifice)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MarshFlitter.java b/Mage.Sets/src/mage/cards/m/MarshFlitter.java index 641acb0a167..30e2db8c098 100644 --- a/Mage.Sets/src/mage/cards/m/MarshFlitter.java +++ b/Mage.Sets/src/mage/cards/m/MarshFlitter.java @@ -46,7 +46,7 @@ public final class MarshFlitter extends CardImpl { // Sacrifice a Goblin: Marsh Flitter has base power and toughness 3/3 until end of turn. Effect effect = new SetBasePowerToughnessSourceEffect(3, 3, Duration.EndOfTurn); effect.setText("{this} has base power and toughness 3/3 until end of turn"); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MarshLurker.java b/Mage.Sets/src/mage/cards/m/MarshLurker.java index c0ba11137d8..1414d116f2b 100644 --- a/Mage.Sets/src/mage/cards/m/MarshLurker.java +++ b/Mage.Sets/src/mage/cards/m/MarshLurker.java @@ -34,7 +34,7 @@ public final class MarshLurker extends CardImpl { this.power = new MageInt(3); this.toughness = new MageInt(2); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FearAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FearAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(filter))); } private MarshLurker(final MarshLurker card) { diff --git a/Mage.Sets/src/mage/cards/m/MartyrsBond.java b/Mage.Sets/src/mage/cards/m/MartyrsBond.java index 8792aa12620..5cb99758b96 100644 --- a/Mage.Sets/src/mage/cards/m/MartyrsBond.java +++ b/Mage.Sets/src/mage/cards/m/MartyrsBond.java @@ -17,6 +17,7 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.ArrayList; @@ -119,9 +120,9 @@ class MartyrsBondEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !playerId.equals(controller.getId())) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(filter); if (target.canChoose(playerId, source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.add(target.getFirstTarget()); } } diff --git a/Mage.Sets/src/mage/cards/m/MawOfTheObzedat.java b/Mage.Sets/src/mage/cards/m/MawOfTheObzedat.java index cdafefa4f3e..a59eac7bc06 100644 --- a/Mage.Sets/src/mage/cards/m/MawOfTheObzedat.java +++ b/Mage.Sets/src/mage/cards/m/MawOfTheObzedat.java @@ -26,7 +26,7 @@ public final class MawOfTheObzedat extends CardImpl { // Sacrifice a creature: Creatures you control get +1/+1 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); } diff --git a/Mage.Sets/src/mage/cards/m/Megatog.java b/Mage.Sets/src/mage/cards/m/Megatog.java index cb5d525c492..374cb64caa1 100644 --- a/Mage.Sets/src/mage/cards/m/Megatog.java +++ b/Mage.Sets/src/mage/cards/m/Megatog.java @@ -38,7 +38,7 @@ public final class Megatog extends CardImpl { // Sacrifice an artifact: Megatog gets +3/+3 and gains trample until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(3, 3, Duration.EndOfTurn) - .setText("{this} gets +3/+3"), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + .setText("{this} gets +3/+3"), new SacrificeTargetCost(filter)); ability.addEffect(new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn) .setText("and gains trample until end of turn")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MercilessResolve.java b/Mage.Sets/src/mage/cards/m/MercilessResolve.java index 46284225fe6..0adb230230d 100644 --- a/Mage.Sets/src/mage/cards/m/MercilessResolve.java +++ b/Mage.Sets/src/mage/cards/m/MercilessResolve.java @@ -27,7 +27,7 @@ public final class MercilessResolve extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}"); // As an additional cost to cast Merciless Resolve, sacrifice a creature or land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Draw two cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); diff --git a/Mage.Sets/src/mage/cards/m/MetalworkColossus.java b/Mage.Sets/src/mage/cards/m/MetalworkColossus.java index 75aa860b99c..30e2fdbd28b 100644 --- a/Mage.Sets/src/mage/cards/m/MetalworkColossus.java +++ b/Mage.Sets/src/mage/cards/m/MetalworkColossus.java @@ -17,6 +17,7 @@ import mage.filter.common.FilterControlledArtifactPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -49,7 +50,7 @@ public final class MetalworkColossus extends CardImpl { ); // Sacrifice two artifacts: Return Metalwork Colossus from your graveyard to your hand. - this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new SacrificeTargetCost(new TargetControlledPermanent(2, filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new SacrificeTargetCost(2, filter))); } private MetalworkColossus(final MetalworkColossus card) { @@ -60,4 +61,4 @@ public final class MetalworkColossus extends CardImpl { public MetalworkColossus copy() { return new MetalworkColossus(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MindExtraction.java b/Mage.Sets/src/mage/cards/m/MindExtraction.java index 69fd54fef0c..0ac1fd6b108 100644 --- a/Mage.Sets/src/mage/cards/m/MindExtraction.java +++ b/Mage.Sets/src/mage/cards/m/MindExtraction.java @@ -29,9 +29,7 @@ public final class MindExtraction extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( - 1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, false - ))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Target player reveals their hand and discards all cards of each of the sacrificed creature’s colors. this.getSpellAbility().addEffect(new MindExtractionEffect()); @@ -102,4 +100,4 @@ class MindExtractionEffect extends OneShotEffect { player.discard(toDiscard, false, source, game); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MineCollapse.java b/Mage.Sets/src/mage/cards/m/MineCollapse.java index c389fdfd918..976d45fcd95 100644 --- a/Mage.Sets/src/mage/cards/m/MineCollapse.java +++ b/Mage.Sets/src/mage/cards/m/MineCollapse.java @@ -28,7 +28,7 @@ public final class MineCollapse extends CardImpl { // If it's your turn, you may sacrifice a Mountain rather than pay this spell's mana cost. this.addAbility(new AlternativeCostSourceAbility( - new SacrificeTargetCost(new TargetControlledPermanent(filter)), + new SacrificeTargetCost(filter), MyTurnCondition.instance, "If it's your turn, you may sacrifice a Mountain rather than pay this spell's mana cost." ).addHint(MyTurnHint.instance)); diff --git a/Mage.Sets/src/mage/cards/m/MireShade.java b/Mage.Sets/src/mage/cards/m/MireShade.java index 139429636e6..17574ae3c3e 100644 --- a/Mage.Sets/src/mage/cards/m/MireShade.java +++ b/Mage.Sets/src/mage/cards/m/MireShade.java @@ -38,7 +38,7 @@ public final class MireShade extends CardImpl { // {B}, Sacrifice a Swamp: Put a +1/+1 counter on Mire Shade. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MoggAlarm.java b/Mage.Sets/src/mage/cards/m/MoggAlarm.java index ad7cedf6842..3574c1c3bd8 100644 --- a/Mage.Sets/src/mage/cards/m/MoggAlarm.java +++ b/Mage.Sets/src/mage/cards/m/MoggAlarm.java @@ -28,7 +28,7 @@ public final class MoggAlarm extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{R}{R}"); // You may sacrifice two Mountains rather than pay Mogg Alarm's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(2, filter))); // Create two 1/1 red Goblin creature tokens. this.getSpellAbility().addEffect(new CreateTokenEffect(new GoblinToken(),2)); diff --git a/Mage.Sets/src/mage/cards/m/MoggRaider.java b/Mage.Sets/src/mage/cards/m/MoggRaider.java index b63cbb2988f..546d9aa2eb8 100644 --- a/Mage.Sets/src/mage/cards/m/MoggRaider.java +++ b/Mage.Sets/src/mage/cards/m/MoggRaider.java @@ -35,7 +35,7 @@ public final class MoggRaider extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java b/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java index 0a236768c18..3e8a4c3ed59 100644 --- a/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java +++ b/Mage.Sets/src/mage/cards/m/MogisGodOfSlaughter.java @@ -17,6 +17,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -83,8 +84,7 @@ class MogisGodOfSlaughterEffect extends OneShotEffect { if (game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT_CREATURE, game.getActivePlayerId(), game) == 0) { return player.damage(2, source.getSourceId(), source, game) > 0; } - TargetPermanent target = new TargetControlledCreaturePermanent(1); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game) && player.chooseUse(Outcome.Detriment, "Sacrifice a creature to prevent 2 damage?", source, game) && player.choose(Outcome.Sacrifice, target, source, game)) { @@ -95,4 +95,4 @@ class MogisGodOfSlaughterEffect extends OneShotEffect { } return player.damage(2, source.getSourceId(), source, game) > 0; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/m/MoldDemon.java b/Mage.Sets/src/mage/cards/m/MoldDemon.java index cdda3e0588a..ad1a91951de 100644 --- a/Mage.Sets/src/mage/cards/m/MoldDemon.java +++ b/Mage.Sets/src/mage/cards/m/MoldDemon.java @@ -34,7 +34,7 @@ public final class MoldDemon extends CardImpl { // When Mold Demon enters the battlefield, sacrifice it unless you sacrifice two Swamps. this.addAbility(new EntersBattlefieldTriggeredAbility( - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true))))); + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(2, filter)))); } private MoldDemon(final MoldDemon card) { diff --git a/Mage.Sets/src/mage/cards/m/MondrakGloryDominus.java b/Mage.Sets/src/mage/cards/m/MondrakGloryDominus.java index 977b6e27371..73186cb514f 100644 --- a/Mage.Sets/src/mage/cards/m/MondrakGloryDominus.java +++ b/Mage.Sets/src/mage/cards/m/MondrakGloryDominus.java @@ -16,6 +16,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -53,7 +54,7 @@ public final class MondrakGloryDominus extends CardImpl { CounterType.INDESTRUCTIBLE.createInstance() ), new ManaCostsImpl<>("{1}{W/P}{W/P}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MorkrutBehemoth.java b/Mage.Sets/src/mage/cards/m/MorkrutBehemoth.java index 48772fd9b2f..e5cead4663a 100644 --- a/Mage.Sets/src/mage/cards/m/MorkrutBehemoth.java +++ b/Mage.Sets/src/mage/cards/m/MorkrutBehemoth.java @@ -29,9 +29,7 @@ public final class MorkrutBehemoth extends CardImpl { // As an additional cost to cast this spell, sacrifice a creature or pay {1}{B}. this.getSpellAbility().addCost(new OrCost( - "sacrifice a creature or pay {1}{B}", new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - )), new ManaCostsImpl<>("{1}{B}") + "sacrifice a creature or pay {1}{B}", new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), new ManaCostsImpl<>("{1}{B}") )); // Menace diff --git a/Mage.Sets/src/mage/cards/m/MukotaiSoulripper.java b/Mage.Sets/src/mage/cards/m/MukotaiSoulripper.java index 3c4f0a92fd7..9cb7b75bd2c 100644 --- a/Mage.Sets/src/mage/cards/m/MukotaiSoulripper.java +++ b/Mage.Sets/src/mage/cards/m/MukotaiSoulripper.java @@ -45,7 +45,7 @@ public final class MukotaiSoulripper extends CardImpl { // Whenever Mukotai Soulripper attacks, you may sacrifice another artifact or creature. If you do, put a +1/+1 counter on Mukotai Soulripper and it gains menace until end of turn. this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) ).addEffect(new GainAbilitySourceEffect( new MenaceAbility(false), Duration.EndOfTurn ).setText("and it gains menace until end of turn")))); diff --git a/Mage.Sets/src/mage/cards/m/Mycologist.java b/Mage.Sets/src/mage/cards/m/Mycologist.java index d44f102733e..953762fd4ef 100644 --- a/Mage.Sets/src/mage/cards/m/Mycologist.java +++ b/Mage.Sets/src/mage/cards/m/Mycologist.java @@ -47,7 +47,7 @@ public final class Mycologist extends CardImpl { // Sacrifice a Saproling: You gain 2 life. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), - new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false)))); + new SacrificeTargetCost(filter))); } private Mycologist(final Mycologist card) { diff --git a/Mage.Sets/src/mage/cards/n/NahirisSacrifice.java b/Mage.Sets/src/mage/cards/n/NahirisSacrifice.java index b2d62aeeb21..99ac69681c7 100644 --- a/Mage.Sets/src/mage/cards/n/NahirisSacrifice.java +++ b/Mage.Sets/src/mage/cards/n/NahirisSacrifice.java @@ -88,8 +88,7 @@ class SacrificeXManaValueCost extends VariableCostImpl implements SacrificeCost FilterControlledPermanent manavaluefilter = new FilterControlledPermanent(filter.getMessage() + " with mana value "+xValue); manavaluefilter.add(filter.getPredicates().get(0)); manavaluefilter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, xValue)); - TargetControlledPermanent target = new TargetControlledPermanent(manavaluefilter); - return new SacrificeTargetCost(target); + return new SacrificeTargetCost(manavaluefilter); } } diff --git a/Mage.Sets/src/mage/cards/n/NaturalOrder.java b/Mage.Sets/src/mage/cards/n/NaturalOrder.java index d5e44201951..92f79211261 100644 --- a/Mage.Sets/src/mage/cards/n/NaturalOrder.java +++ b/Mage.Sets/src/mage/cards/n/NaturalOrder.java @@ -33,7 +33,7 @@ public final class NaturalOrder extends CardImpl { // As an additional cost to cast Natural Order, sacrifice a green creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Search your library for a green creature card and put it onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(1 , filterCard), false)); } diff --git a/Mage.Sets/src/mage/cards/n/NeedForSpeed.java b/Mage.Sets/src/mage/cards/n/NeedForSpeed.java index b51c5bf19e1..0f630b8ab87 100644 --- a/Mage.Sets/src/mage/cards/n/NeedForSpeed.java +++ b/Mage.Sets/src/mage/cards/n/NeedForSpeed.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; @@ -31,7 +32,7 @@ public final class NeedForSpeed extends CardImpl { // Sacrifice a land: Target creature gains haste until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledPermanent("land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NemataGroveGuardian.java b/Mage.Sets/src/mage/cards/n/NemataGroveGuardian.java index ed9e3cf947b..5f89e15f905 100644 --- a/Mage.Sets/src/mage/cards/n/NemataGroveGuardian.java +++ b/Mage.Sets/src/mage/cards/n/NemataGroveGuardian.java @@ -40,7 +40,7 @@ public final class NemataGroveGuardian extends CardImpl { // {2}{G}: Create a 1/1 green Saproling creature token. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken()), new ManaCostsImpl<>("{2}{G}"))); // Sacrifice a Saproling: Saproling creatures get +1/+1 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), new SacrificeTargetCost(new TargetControlledPermanent(filter1)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), new SacrificeTargetCost(filter1))); } private NemataGroveGuardian(final NemataGroveGuardian card) { diff --git a/Mage.Sets/src/mage/cards/n/NemataPrimevalWarden.java b/Mage.Sets/src/mage/cards/n/NemataPrimevalWarden.java index 5fd69c1bff9..38c4fad173b 100644 --- a/Mage.Sets/src/mage/cards/n/NemataPrimevalWarden.java +++ b/Mage.Sets/src/mage/cards/n/NemataPrimevalWarden.java @@ -55,14 +55,14 @@ public final class NemataPrimevalWarden extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // {1}{B}, Sacrifice 2 Saprolings: Draw a card. Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{B}")); - ability2.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, filter2, false))); + ability2.addCost(new SacrificeTargetCost(2, filter2)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/n/Neoform.java b/Mage.Sets/src/mage/cards/n/Neoform.java index de5ed763bd9..e29892b8c44 100644 --- a/Mage.Sets/src/mage/cards/n/Neoform.java +++ b/Mage.Sets/src/mage/cards/n/Neoform.java @@ -34,9 +34,7 @@ public final class Neoform extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}{U}"); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( - 1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true - ))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Search your library for a creature card with converted mana cost equal to 1 plus the sacrificed creature's converted mana cost, // put that card onto the battlefield with an additional +1/+1 counter on it, then shuffle your library. diff --git a/Mage.Sets/src/mage/cards/n/NimDevourer.java b/Mage.Sets/src/mage/cards/n/NimDevourer.java index 28fb9cccb47..88256534f03 100644 --- a/Mage.Sets/src/mage/cards/n/NimDevourer.java +++ b/Mage.Sets/src/mage/cards/n/NimDevourer.java @@ -8,19 +8,14 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.decorator.ConditionalActivatedAbility; import mage.abilities.dynamicvalue.common.ArtifactYouControlCount; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect; +import mage.abilities.effects.common.SacrificeControllerEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.hint.common.ArtifactYouControlHint; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -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.common.TargetControlledPermanent; +import mage.filter.StaticFilters; import java.util.UUID; @@ -46,7 +41,7 @@ public final class NimDevourer extends CardImpl { new ReturnSourceFromGraveyardToBattlefieldEffect(false, false), new ManaCostsImpl<>("{B}{B}"), new IsStepCondition(PhaseStep.UPKEEP), null); - ability.addEffect(new NimDevourerEffect()); + ability.addEffect(new SacrificeControllerEffect(StaticFilters.FILTER_PERMANENT_A_CREATURE, 1, ", then")); this.addAbility(ability); } @@ -59,36 +54,3 @@ public final class NimDevourer extends CardImpl { return new NimDevourer(this); } } - -class NimDevourerEffect extends OneShotEffect { - - public NimDevourerEffect() { - super(Outcome.Sacrifice); - this.staticText = ", then sacrifice a creature"; - } - - private NimDevourerEffect(final NimDevourerEffect effect) { - super(effect); - } - - @Override - public NimDevourerEffect copy() { - return new NimDevourerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Target target = new TargetControlledPermanent(new FilterControlledCreaturePermanent()); - - if (target.canChoose(player.getId(), source, game) && player.choose(Outcome.Sacrifice, target, source, game)) { - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - return permanent.sacrifice(source, game); - } - } - } - return false; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/n/NoviceDissector.java b/Mage.Sets/src/mage/cards/n/NoviceDissector.java index 24b7b2efc88..292552f9c71 100644 --- a/Mage.Sets/src/mage/cards/n/NoviceDissector.java +++ b/Mage.Sets/src/mage/cards/n/NoviceDissector.java @@ -34,9 +34,7 @@ public final class NoviceDissector extends CardImpl { Ability ability = new ActivateAsSorceryActivatedAbility( new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NuteGunray.java b/Mage.Sets/src/mage/cards/n/NuteGunray.java index d7347fd373c..3e63b09ca84 100644 --- a/Mage.Sets/src/mage/cards/n/NuteGunray.java +++ b/Mage.Sets/src/mage/cards/n/NuteGunray.java @@ -50,7 +50,7 @@ public final class NuteGunray extends CardImpl { // {1}{T}, Sacrifice a non-token artifact: Create a 1/1 colorless Battle Droid artifact creature token. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DroidToken()), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/ObNixilisTheAdversary.java b/Mage.Sets/src/mage/cards/o/ObNixilisTheAdversary.java index f8036239231..cef0cc6224c 100644 --- a/Mage.Sets/src/mage/cards/o/ObNixilisTheAdversary.java +++ b/Mage.Sets/src/mage/cards/o/ObNixilisTheAdversary.java @@ -24,7 +24,7 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.players.Player; import mage.target.TargetPlayer; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.functions.StackObjectCopyApplier; import java.util.List; @@ -93,8 +93,8 @@ class ObNixilisTheAdversaryCasualtyAbility extends StaticAbility { class ObNixilisTheAdversaryCost extends SacrificeTargetCost { - public ObNixilisTheAdversaryCost() { - super(new TargetControlledPermanent(0, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true)); + ObNixilisTheAdversaryCost() { + super(new TargetSacrifice(0, 1, StaticFilters.FILTER_CONTROLLED_CREATURE)); this.text = ""; } @@ -132,7 +132,7 @@ class ObNixilisTheAdversaryCopyEffect extends OneShotEffect { private final StackObjectCopyApplier applier; - public ObNixilisTheAdversaryCopyEffect(StackObjectCopyApplier applier) { + ObNixilisTheAdversaryCopyEffect(StackObjectCopyApplier applier) { super(Outcome.Copy); this.applier = applier; this.staticText = "copy {this}"; @@ -163,7 +163,7 @@ class ObNixilisTheAdversaryApplier implements StackObjectCopyApplier { private final int loyalty; - public ObNixilisTheAdversaryApplier(int loyalty) { + ObNixilisTheAdversaryApplier(int loyalty) { this.loyalty = loyalty; } @@ -181,7 +181,7 @@ class ObNixilisTheAdversaryApplier implements StackObjectCopyApplier { class ObNixilisTheAdversaryDiscardEffect extends OneShotEffect { - public ObNixilisTheAdversaryDiscardEffect() { + ObNixilisTheAdversaryDiscardEffect() { super(Outcome.LoseLife); this.staticText = "Each opponent loses 2 life unless they discard a card. If you control a Demon or Devil, you gain 2 life"; } diff --git a/Mage.Sets/src/mage/cards/o/OozeGarden.java b/Mage.Sets/src/mage/cards/o/OozeGarden.java index f7755c7961b..ff6f55de9b6 100644 --- a/Mage.Sets/src/mage/cards/o/OozeGarden.java +++ b/Mage.Sets/src/mage/cards/o/OozeGarden.java @@ -40,7 +40,7 @@ public final class OozeGarden extends CardImpl { // {1}{G}, Sacrifice a non-Ooze creature: Create an X/X green Ooze creature token, where X is the sacrificed creature's power. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new OozeGardenCreateTokenEffect(), new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } @@ -107,4 +107,4 @@ class OozeToken extends TokenImpl { public OozeToken copy() { return new OozeToken(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/o/OrcGeneral.java b/Mage.Sets/src/mage/cards/o/OrcGeneral.java index 82735ea427b..161278b49cb 100644 --- a/Mage.Sets/src/mage/cards/o/OrcGeneral.java +++ b/Mage.Sets/src/mage/cards/o/OrcGeneral.java @@ -44,7 +44,7 @@ public final class OrcGeneral extends CardImpl { // {tap}, Sacrifice another Orc or Goblin: Other Orc creatures get +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.EndOfTurn, filterOrc, true), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterOrcOrGoblin))); + ability.addCost(new SacrificeTargetCost(filterOrcOrGoblin)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java b/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java index e8377018d91..a7abb7d486a 100644 --- a/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java +++ b/Mage.Sets/src/mage/cards/o/OrcishLumberjack.java @@ -42,7 +42,7 @@ public final class OrcishLumberjack extends CardImpl { // {tap}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G}. Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new OrcishLumberjackManaEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OrcishMechanics.java b/Mage.Sets/src/mage/cards/o/OrcishMechanics.java index a4a2644ebb8..d4e2a3609fd 100644 --- a/Mage.Sets/src/mage/cards/o/OrcishMechanics.java +++ b/Mage.Sets/src/mage/cards/o/OrcishMechanics.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetAnyTarget; @@ -31,7 +32,7 @@ public final class OrcishMechanics extends CardImpl { // {tap}, Sacrifice an artifact: Orcish Mechanics deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OrcishVandal.java b/Mage.Sets/src/mage/cards/o/OrcishVandal.java index 81b2803157b..a7df87c18c3 100644 --- a/Mage.Sets/src/mage/cards/o/OrcishVandal.java +++ b/Mage.Sets/src/mage/cards/o/OrcishVandal.java @@ -39,7 +39,7 @@ public final class OrcishVandal extends CardImpl { // {t}, Sacrifice an artifact: Orcish Vandal deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); ability.addTarget(new TargetAnyTarget()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java b/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java index a4fadaff363..146362a66fb 100644 --- a/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java +++ b/Mage.Sets/src/mage/cards/o/OrmendahlTheCorrupter.java @@ -44,9 +44,7 @@ public final class OrmendahlTheCorrupter extends CardImpl { // Sacrifice another creature: Draw a card. this.addAbility(new SimpleActivatedAbility( new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - )) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) )); } diff --git a/Mage.Sets/src/mage/cards/o/OsgirTheReconstructor.java b/Mage.Sets/src/mage/cards/o/OsgirTheReconstructor.java index f653aa4f403..ee16b866776 100644 --- a/Mage.Sets/src/mage/cards/o/OsgirTheReconstructor.java +++ b/Mage.Sets/src/mage/cards/o/OsgirTheReconstructor.java @@ -59,7 +59,7 @@ public final class OsgirTheReconstructor extends CardImpl { // {1}, Sacrifice an artifact: Target creature you control gets +2/+0 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{1}")); ability.addTarget(new TargetControlledCreaturePermanent()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability); // {X},{T}, Exile an artifact with mana value X from your graveyard: Create two tokens that are copies of the exiled card. Activate only as diff --git a/Mage.Sets/src/mage/cards/o/OswaldFiddlebender.java b/Mage.Sets/src/mage/cards/o/OswaldFiddlebender.java index e8255a95050..34b51eb2bb3 100644 --- a/Mage.Sets/src/mage/cards/o/OswaldFiddlebender.java +++ b/Mage.Sets/src/mage/cards/o/OswaldFiddlebender.java @@ -43,9 +43,7 @@ public final class OswaldFiddlebender extends CardImpl { new OswaldFiddlebenderEffect(), new ManaCostsImpl<>("{W}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability.withFlavorWord("Magical Tinkering")); } diff --git a/Mage.Sets/src/mage/cards/o/OvergrownEstate.java b/Mage.Sets/src/mage/cards/o/OvergrownEstate.java index f39a6daff7d..eb0e5011710 100644 --- a/Mage.Sets/src/mage/cards/o/OvergrownEstate.java +++ b/Mage.Sets/src/mage/cards/o/OvergrownEstate.java @@ -24,7 +24,7 @@ public final class OvergrownEstate extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{B}{G}"); // Sacrifice a land: You gain 3 life. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(3), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(3), new SacrificeTargetCost(filter))); } private OvergrownEstate(final OvergrownEstate card) { diff --git a/Mage.Sets/src/mage/cards/o/OxiddaDaredevil.java b/Mage.Sets/src/mage/cards/o/OxiddaDaredevil.java index 6226717873e..3c1da4ffeb9 100644 --- a/Mage.Sets/src/mage/cards/o/OxiddaDaredevil.java +++ b/Mage.Sets/src/mage/cards/o/OxiddaDaredevil.java @@ -38,7 +38,7 @@ public final class OxiddaDaredevil extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + new SacrificeTargetCost(filter))); } private OxiddaDaredevil(final OxiddaDaredevil card) { diff --git a/Mage.Sets/src/mage/cards/p/PallidMycoderm.java b/Mage.Sets/src/mage/cards/p/PallidMycoderm.java index 8308a37fb84..629152ff3d2 100644 --- a/Mage.Sets/src/mage/cards/p/PallidMycoderm.java +++ b/Mage.Sets/src/mage/cards/p/PallidMycoderm.java @@ -62,7 +62,7 @@ public final class PallidMycoderm extends CardImpl { this.addAbility(new SimpleActivatedAbility( new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false) .setText("each creature you control that's a Fungus or a Saproling gets +1/+1 until end of turn"), - new SacrificeTargetCost(new TargetControlledPermanent(filterSaproling)) + new SacrificeTargetCost(filterSaproling) )); } diff --git a/Mage.Sets/src/mage/cards/p/PashalikMons.java b/Mage.Sets/src/mage/cards/p/PashalikMons.java index 74725c23ae1..b160ba2d6b8 100644 --- a/Mage.Sets/src/mage/cards/p/PashalikMons.java +++ b/Mage.Sets/src/mage/cards/p/PashalikMons.java @@ -59,7 +59,7 @@ public final class PashalikMons extends CardImpl { ability = new SimpleActivatedAbility( new CreateTokenEffect(new GoblinToken(), 2), new ManaCostsImpl<>("{3}{R}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PegasusStampede.java b/Mage.Sets/src/mage/cards/p/PegasusStampede.java index 790fe698d5d..5b220b4c55a 100644 --- a/Mage.Sets/src/mage/cards/p/PegasusStampede.java +++ b/Mage.Sets/src/mage/cards/p/PegasusStampede.java @@ -22,7 +22,7 @@ public final class PegasusStampede extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{W}"); // Buyback-Sacrifice a land. - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT, true)))); + this.addAbility(new BuybackAbility(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); // Create a 1/1 white Pegasus creature token with flying. this.getSpellAbility().addEffect(new CreateTokenEffect(new PegasusToken())); diff --git a/Mage.Sets/src/mage/cards/p/Pentavus.java b/Mage.Sets/src/mage/cards/p/Pentavus.java index f5d5abcb09c..d1954c12d0b 100644 --- a/Mage.Sets/src/mage/cards/p/Pentavus.java +++ b/Mage.Sets/src/mage/cards/p/Pentavus.java @@ -50,7 +50,7 @@ public final class Pentavus extends CardImpl { // {1}, Sacrifice a Pentavite: Put a +1/+1 counter on Pentavus. Ability secondAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new GenericManaCost(1)); - secondAbility.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + secondAbility.addCost(new SacrificeTargetCost(filter)); this.addAbility(secondAbility); } diff --git a/Mage.Sets/src/mage/cards/p/PeregrinTook.java b/Mage.Sets/src/mage/cards/p/PeregrinTook.java index 29a93503f4b..c7d260943a3 100644 --- a/Mage.Sets/src/mage/cards/p/PeregrinTook.java +++ b/Mage.Sets/src/mage/cards/p/PeregrinTook.java @@ -43,7 +43,7 @@ public final class PeregrinTook extends CardImpl { // Sacrifice three Foods: Draw a card. this.addAbility(new SimpleActivatedAbility( new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(3, filter)) + new SacrificeTargetCost(3, filter) )); } @@ -101,4 +101,4 @@ class PeregrinTookReplacementEffect extends ReplacementEffectImpl { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PerilousPredicament.java b/Mage.Sets/src/mage/cards/p/PerilousPredicament.java index 187cf74a7da..e06f59a6732 100644 --- a/Mage.Sets/src/mage/cards/p/PerilousPredicament.java +++ b/Mage.Sets/src/mage/cards/p/PerilousPredicament.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -65,21 +66,19 @@ class PerilousPredicamentSacrificeOpponentsEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { FilterArtifactCreaturePermanent filterArtifact = new FilterArtifactCreaturePermanent("an artifact creature"); - filterArtifact.add(new ControllerIdPredicate(player.getId())); FilterCreaturePermanent filterNonArtifact = new FilterCreaturePermanent("a nonartifact creature"); filterNonArtifact.add(Predicates.not(CardType.ARTIFACT.getPredicate())); - filterNonArtifact.add(new ControllerIdPredicate(player.getId())); if (game.getBattlefield().countAll(filterArtifact, player.getId(), game) > 0) { - TargetPermanent target = new TargetPermanent(1, 1, filterArtifact, true); + TargetSacrifice target = new TargetSacrifice(filterArtifact); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } if (game.getBattlefield().countAll(filterNonArtifact, player.getId(), game) > 0) { - TargetPermanent target = new TargetPermanent(1, 1, filterNonArtifact, true); + TargetSacrifice target = new TargetSacrifice(filterNonArtifact); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } diff --git a/Mage.Sets/src/mage/cards/p/Phantatog.java b/Mage.Sets/src/mage/cards/p/Phantatog.java index 4d6e76cfefe..70402a43e75 100644 --- a/Mage.Sets/src/mage/cards/p/Phantatog.java +++ b/Mage.Sets/src/mage/cards/p/Phantatog.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,7 +34,7 @@ public final class Phantatog extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledEnchantmentPermanent("enchantment"))))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ENCHANTMENT))); // Discard a card: Phantatog gets +1/+1 until end of turn. this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianAltar.java b/Mage.Sets/src/mage/cards/p/PhyrexianAltar.java index cf851f777b3..17e74904312 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianAltar.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianAltar.java @@ -21,7 +21,7 @@ public final class PhyrexianAltar extends CardImpl { // Sacrifice a creature: Add one mana of any color. this.addAbility(new AnyColorManaAbility( - new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), CreaturesYouControlCount.instance, false )); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianTribute.java b/Mage.Sets/src/mage/cards/p/PhyrexianTribute.java index e9685c06e38..4ab4c34023d 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexianTribute.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexianTribute.java @@ -11,6 +11,7 @@ import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -25,7 +26,7 @@ public final class PhyrexianTribute extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); // As an additional cost to cast Phyrexian Tribute, sacrifice two creatures. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(2, filter)); // Destroy target artifact. this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addTarget(new TargetArtifactPermanent()); diff --git a/Mage.Sets/src/mage/cards/p/PhyrexiasCore.java b/Mage.Sets/src/mage/cards/p/PhyrexiasCore.java index c0fbc91f2fe..cf3f87ceb65 100644 --- a/Mage.Sets/src/mage/cards/p/PhyrexiasCore.java +++ b/Mage.Sets/src/mage/cards/p/PhyrexiasCore.java @@ -33,7 +33,7 @@ public final class PhyrexiasCore extends CardImpl { this.addAbility(new ColorlessManaAbility()); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(1), new TapSourceCost()); ability.addCost(new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PiaAndKiranNalaar.java b/Mage.Sets/src/mage/cards/p/PiaAndKiranNalaar.java index 427de4864e4..117a8e758bb 100644 --- a/Mage.Sets/src/mage/cards/p/PiaAndKiranNalaar.java +++ b/Mage.Sets/src/mage/cards/p/PiaAndKiranNalaar.java @@ -17,6 +17,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.permanent.token.ThopterColorlessToken; import mage.target.common.TargetControlledPermanent; @@ -43,7 +44,7 @@ public final class PiaAndKiranNalaar extends CardImpl { // {2}{R}, Sacrifice an artifact: Pia and Kiran Nalaar deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{2}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent("an artifact"), true))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PiaNalaar.java b/Mage.Sets/src/mage/cards/p/PiaNalaar.java index 27450f6a037..316bc869270 100644 --- a/Mage.Sets/src/mage/cards/p/PiaNalaar.java +++ b/Mage.Sets/src/mage/cards/p/PiaNalaar.java @@ -50,7 +50,7 @@ public final class PiaNalaar extends CardImpl { // {1}, Sacrifice an artifact: Target creature can't block this turn. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantBlockTargetEffect(Duration.EndOfTurn), new GenericManaCost(1)); ability.addTarget(new TargetCreaturePermanent()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java b/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java index cbdd9a3dcf1..015c41c446b 100644 --- a/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java +++ b/Mage.Sets/src/mage/cards/p/PillarTombsOfAku.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.TargetController; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; @@ -70,7 +71,7 @@ class PillarTombsOfAkuEffect extends OneShotEffect { return false; } if (activePlayer.chooseUse(Outcome.Sacrifice, "Sacrifice a creature?", source, game)) { - Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE); if (cost.canPay(source, source, activePlayer.getId(), game) && cost.pay(source, game, source, activePlayer.getId(), true)) { return true; diff --git a/Mage.Sets/src/mage/cards/p/PiousEvangel.java b/Mage.Sets/src/mage/cards/p/PiousEvangel.java index 47dfa82fdc8..859245e532f 100644 --- a/Mage.Sets/src/mage/cards/p/PiousEvangel.java +++ b/Mage.Sets/src/mage/cards/p/PiousEvangel.java @@ -50,7 +50,7 @@ public final class PiousEvangel extends CardImpl { this.addAbility(new TransformAbility()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java b/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java index 06d41422d4b..2161b5a040d 100644 --- a/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java +++ b/Mage.Sets/src/mage/cards/p/PiperOfTheSwarm.java @@ -58,7 +58,7 @@ public final class PiperOfTheSwarm extends CardImpl { new GainControlTargetEffect(Duration.Custom), new ManaCostsImpl<>("{2}{B}{B}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter2))); + ability.addCost(new SacrificeTargetCost(3, filter2)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PippinWardenOfIsengard.java b/Mage.Sets/src/mage/cards/p/PippinWardenOfIsengard.java index 53f6a676226..2a72ee497a4 100644 --- a/Mage.Sets/src/mage/cards/p/PippinWardenOfIsengard.java +++ b/Mage.Sets/src/mage/cards/p/PippinWardenOfIsengard.java @@ -53,7 +53,7 @@ public final class PippinWardenOfIsengard extends CardImpl { ability = new ActivateAsSorceryActivatedAbility(new BoostControlledEffect( 3, 3, Duration.EndOfTurn, true ).setText("other creatures you control get +3/+3"), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(4, filter))); + ability.addCost(new SacrificeTargetCost(4, filter)); ability.addEffect(new GainAbilityControlledEffect( HasteAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURES, true ).setText("and gain haste until end of turn")); diff --git a/Mage.Sets/src/mage/cards/p/PistonSledge.java b/Mage.Sets/src/mage/cards/p/PistonSledge.java index 49de9c997ca..980e6e44ac4 100644 --- a/Mage.Sets/src/mage/cards/p/PistonSledge.java +++ b/Mage.Sets/src/mage/cards/p/PistonSledge.java @@ -40,7 +40,7 @@ public final class PistonSledge extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(3, 1))); // Equip—Sacrifice an artifact. - this.addAbility(new EquipAbility(Outcome.AddAbility, new SacrificeTargetCost(new TargetControlledPermanent(filter)), false)); + this.addAbility(new EquipAbility(Outcome.AddAbility, new SacrificeTargetCost(filter), false)); } private PistonSledge(final PistonSledge card) { diff --git a/Mage.Sets/src/mage/cards/p/PitilessPontiff.java b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java index 4b342f2c18e..8fac347c717 100644 --- a/Mage.Sets/src/mage/cards/p/PitilessPontiff.java +++ b/Mage.Sets/src/mage/cards/p/PitilessPontiff.java @@ -38,9 +38,7 @@ public final class PitilessPontiff extends CardImpl { ability.addEffect(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ).setText("and indestructible until end of turn")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/Plaguecrafter.java b/Mage.Sets/src/mage/cards/p/Plaguecrafter.java index 2baf7d8d832..2a2db8f7acf 100644 --- a/Mage.Sets/src/mage/cards/p/Plaguecrafter.java +++ b/Mage.Sets/src/mage/cards/p/Plaguecrafter.java @@ -11,12 +11,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.ArrayList; @@ -84,12 +86,7 @@ class PlaguecrafterEffect extends OneShotEffect { if (player == null) { continue; } - FilterControlledPermanent filter = new FilterControlledPermanent("creature or planeswalker"); - filter.add(Predicates.or( - CardType.CREATURE.getPredicate(), - CardType.PLANESWALKER.getPredicate() - )); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_CREATURE_OR_PLANESWALKER); if (target.canChoose(player.getId(), source, game)) { while (!target.isChosen() && player.canRespond()) { player.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/p/PlantElemental.java b/Mage.Sets/src/mage/cards/p/PlantElemental.java index 0432f29b979..dc2715be8e7 100644 --- a/Mage.Sets/src/mage/cards/p/PlantElemental.java +++ b/Mage.Sets/src/mage/cards/p/PlantElemental.java @@ -33,7 +33,7 @@ public final class PlantElemental extends CardImpl { this.toughness = new MageInt(4); // When Plant Elemental enters the battlefield, sacrifice it unless you sacrifice a Forest. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)))); } private PlantElemental(final PlantElemental card) { diff --git a/Mage.Sets/src/mage/cards/p/PlumbTheForbidden.java b/Mage.Sets/src/mage/cards/p/PlumbTheForbidden.java index 378d01c85f9..32d7e32de69 100644 --- a/Mage.Sets/src/mage/cards/p/PlumbTheForbidden.java +++ b/Mage.Sets/src/mage/cards/p/PlumbTheForbidden.java @@ -12,7 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.filter.StaticFilters; import mage.game.Game; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -45,7 +45,7 @@ public final class PlumbTheForbidden extends CardImpl { class PlumbTheForbiddenCost extends SacrificeTargetCost { PlumbTheForbiddenCost() { - super(new TargetControlledPermanent(0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_CREATURES, true)); + super(new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_CREATURES)); this.text = "you may sacrifice one or more creatures. When you do, " + "copy this spell for each creature sacrificed this way"; } diff --git a/Mage.Sets/src/mage/cards/p/PlungeIntoDarkness.java b/Mage.Sets/src/mage/cards/p/PlungeIntoDarkness.java index f4af94dff22..4bc9c771d0d 100644 --- a/Mage.Sets/src/mage/cards/p/PlungeIntoDarkness.java +++ b/Mage.Sets/src/mage/cards/p/PlungeIntoDarkness.java @@ -17,6 +17,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -24,6 +25,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetCard; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -77,8 +79,8 @@ class PlungeIntoDarknessLifeEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - Target target = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, new FilterControlledCreaturePermanent(), true); - player.chooseTarget(Outcome.Sacrifice, target, source, game); + Target target = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT_CREATURE); + player.choose(Outcome.Sacrifice, target, source, game); int numSacrificed = 0; for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); diff --git a/Mage.Sets/src/mage/cards/p/PolarKraken.java b/Mage.Sets/src/mage/cards/p/PolarKraken.java index 3b5ec85903c..887b4a2d9a4 100644 --- a/Mage.Sets/src/mage/cards/p/PolarKraken.java +++ b/Mage.Sets/src/mage/cards/p/PolarKraken.java @@ -32,7 +32,7 @@ public final class PolarKraken extends CardImpl { // Polar Kraken enters the battlefield tapped. this.addAbility(new EntersBattlefieldTappedAbility()); // Cumulative upkeep-Sacrifice a land. - this.addAbility(new CumulativeUpkeepAbility(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)))); + this.addAbility(new CumulativeUpkeepAbility(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); } private PolarKraken(final PolarKraken card) { diff --git a/Mage.Sets/src/mage/cards/p/PollenRemedy.java b/Mage.Sets/src/mage/cards/p/PollenRemedy.java index 54797103ddc..12006dadf12 100644 --- a/Mage.Sets/src/mage/cards/p/PollenRemedy.java +++ b/Mage.Sets/src/mage/cards/p/PollenRemedy.java @@ -11,6 +11,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetAnyTargetAmount; @@ -28,8 +29,7 @@ public final class PollenRemedy extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Kicker-Sacrifice a land. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, - new FilterControlledLandPermanent("a land"), true)))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // Prevent the next 3 damage that would be dealt this turn to any number of target creatures and/or players, divided as you choose. // If Pollen Remedy was kicked, prevent the next 6 damage this way instead. diff --git a/Mage.Sets/src/mage/cards/p/PortcullisVine.java b/Mage.Sets/src/mage/cards/p/PortcullisVine.java index 9886ec191b2..bf11586be09 100644 --- a/Mage.Sets/src/mage/cards/p/PortcullisVine.java +++ b/Mage.Sets/src/mage/cards/p/PortcullisVine.java @@ -47,9 +47,7 @@ public final class PortcullisVine extends CardImpl { new DrawCardSourceControllerEffect(1), new GenericManaCost(2) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(filter) - )); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PossessedPortal.java b/Mage.Sets/src/mage/cards/p/PossessedPortal.java index 770234ff2e7..cde71b627cd 100644 --- a/Mage.Sets/src/mage/cards/p/PossessedPortal.java +++ b/Mage.Sets/src/mage/cards/p/PossessedPortal.java @@ -17,6 +17,7 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; @@ -106,7 +107,7 @@ class PossessedPortalEffect extends OneShotEffect { discardCost.pay(source, game, source, playerId, true, null); } else { - Cost sacrificeCost = new SacrificeTargetCost(new TargetControlledPermanent()); + Cost sacrificeCost = new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT); sacrificeCost.pay(source, game, source, playerId, true, null); } } diff --git a/Mage.Sets/src/mage/cards/p/Pox.java b/Mage.Sets/src/mage/cards/p/Pox.java index 06ba4e4758a..b1a0c1db13c 100644 --- a/Mage.Sets/src/mage/cards/p/Pox.java +++ b/Mage.Sets/src/mage/cards/p/Pox.java @@ -15,6 +15,7 @@ import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -88,7 +89,7 @@ class PoxEffect extends OneShotEffect { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); int creaturesToSacrifice = (int) Math.ceil(game.getBattlefield().count(filter, player.getId(), source, game) / 3.0); if (creaturesToSacrifice > 0) { - Target target = new TargetControlledCreaturePermanent(creaturesToSacrifice, creaturesToSacrifice, filter, true); + Target target = new TargetSacrifice(creaturesToSacrifice, filter); target.chooseTarget(Outcome.Sacrifice, playerId, source, game); for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); @@ -106,7 +107,7 @@ class PoxEffect extends OneShotEffect { FilterControlledLandPermanent filter = new FilterControlledLandPermanent(); int landsToSacrifice = (int) Math.ceil(game.getBattlefield().count(filter, player.getId(), source, game) / 3.0); if (landsToSacrifice > 0) { - Target target = new TargetControlledPermanent(landsToSacrifice, landsToSacrifice, filter, true); + Target target = new TargetSacrifice(landsToSacrifice, filter); target.chooseTarget(Outcome.Sacrifice, playerId, source, game); for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); diff --git a/Mage.Sets/src/mage/cards/p/PrestonTheVanisher.java b/Mage.Sets/src/mage/cards/p/PrestonTheVanisher.java index 166a367b63d..3690c5fb798 100644 --- a/Mage.Sets/src/mage/cards/p/PrestonTheVanisher.java +++ b/Mage.Sets/src/mage/cards/p/PrestonTheVanisher.java @@ -62,7 +62,7 @@ public final class PrestonTheVanisher extends CardImpl { // {1}{W}, Sacrifice five Illusions: Exile target nonland permanent. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetEffect(), new ManaCostsImpl<>("{1}{W}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(5, activeCostFilter))); + ability.addCost(new SacrificeTargetCost(5, activeCostFilter)); ability.addTarget(new TargetNonlandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java b/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java index 639d3647fa0..a91a681c5ab 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java @@ -53,7 +53,7 @@ public final class PriestOfForgottenGods extends CardImpl { new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "") .setText("and sacrifice a creature") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true))); + ability.addCost(new SacrificeTargetCost(2, filter)); ability.addEffect(new BasicManaEffect(Mana.BlackMana(2)).setText("You add {B}{B}")); ability.addEffect(new DrawCardSourceControllerEffect(1).setText("and draw a card")); ability.addTarget(new TargetPlayer(0, Integer.MAX_VALUE, false)); @@ -68,4 +68,4 @@ public final class PriestOfForgottenGods extends CardImpl { public PriestOfForgottenGods copy() { return new PriestOfForgottenGods(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java b/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java index c2835ddcc1f..4931d713ffe 100644 --- a/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/p/PriestOfYawgmoth.java @@ -38,7 +38,7 @@ public final class PriestOfYawgmoth extends CardImpl { false, new HighestCMCOfPermanentValue(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT, true) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java b/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java index 3a879fabbc2..8ee3b8d2bc4 100644 --- a/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java +++ b/Mage.Sets/src/mage/cards/p/PrimeSpeakerVannifar.java @@ -41,9 +41,7 @@ public final class PrimeSpeakerVannifar extends CardImpl { Ability ability = new ActivateAsSorceryActivatedAbility( Zone.BATTLEFIELD, new PrimeSpeakerVannifarEffect(), new TapSourceCost() ); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PrimevalForce.java b/Mage.Sets/src/mage/cards/p/PrimevalForce.java index 7ca2bd8b1c8..aab5007a90c 100644 --- a/Mage.Sets/src/mage/cards/p/PrimevalForce.java +++ b/Mage.Sets/src/mage/cards/p/PrimevalForce.java @@ -32,7 +32,7 @@ public final class PrimevalForce extends CardImpl { this.toughness = new MageInt(8); // When Primeval Force enters the battlefield, sacrifice it unless you sacrifice three Forests. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, true))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(3, filter)))); } private PrimevalForce(final PrimevalForce card) { diff --git a/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java b/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java index cdcbb8ab377..0d15ca99a85 100644 --- a/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java +++ b/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java @@ -41,7 +41,7 @@ public final class ProsshSkyraiderOfKher extends CardImpl { this.addAbility(new CastSourceTriggeredAbility(new CreateTokenEffect(new KherKeepKoboldToken(), ManaSpentToCastCount.instance), false)); // Sacrifice another creature: Prossh gets +1/+0 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private ProsshSkyraiderOfKher(final ProsshSkyraiderOfKher card) { diff --git a/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java b/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java index ddbbf230377..714b1231788 100644 --- a/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java +++ b/Mage.Sets/src/mage/cards/p/ProwlingPangolin.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -66,7 +67,7 @@ class ProwlingPangolinEffect extends OneShotEffect { if (controller != null) { boolean costPaid = false; for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledCreaturePermanent("creatures"), true)); + Cost cost = new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_CREATURES); Player player = game.getPlayer(playerId); if (player != null && cost.canPay(source, source, playerId, game) diff --git a/Mage.Sets/src/mage/cards/p/PsychicAllergy.java b/Mage.Sets/src/mage/cards/p/PsychicAllergy.java index 514a4dfa99f..51ffe4246ff 100644 --- a/Mage.Sets/src/mage/cards/p/PsychicAllergy.java +++ b/Mage.Sets/src/mage/cards/p/PsychicAllergy.java @@ -45,7 +45,7 @@ public final class PsychicAllergy extends CardImpl { // At the beginning of your upkeep, destroy Psychic Allergy unless you sacrifice two Islands. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DoUnlessControllerPaysEffect(new DestroySourceEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, false))).setText("destroy {this} unless you sacrifice two Islands"), + new SacrificeTargetCost(2, filter)).setText("destroy {this} unless you sacrifice two Islands"), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/p/PsychotropeThallid.java b/Mage.Sets/src/mage/cards/p/PsychotropeThallid.java index 77b34964716..5f561b3acae 100644 --- a/Mage.Sets/src/mage/cards/p/PsychotropeThallid.java +++ b/Mage.Sets/src/mage/cards/p/PsychotropeThallid.java @@ -49,7 +49,7 @@ public final class PsychotropeThallid extends CardImpl { // {1}, Sacrifice a Saproling: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, false))); + new SacrificeTargetCost(filter)); ability.addCost(new GenericManaCost(1)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/Pulverize.java b/Mage.Sets/src/mage/cards/p/Pulverize.java index db6f4e08998..f300eafb62a 100644 --- a/Mage.Sets/src/mage/cards/p/Pulverize.java +++ b/Mage.Sets/src/mage/cards/p/Pulverize.java @@ -29,7 +29,7 @@ public final class Pulverize extends CardImpl { // You may sacrifice two Mountains rather than pay Pulverize's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(2, filter))); // Destroy all artifacts. this.getSpellAbility().addEffect(new DestroyAllEffect(StaticFilters.FILTER_PERMANENT_ARTIFACTS)); diff --git a/Mage.Sets/src/mage/cards/p/PyreOfHeroes.java b/Mage.Sets/src/mage/cards/p/PyreOfHeroes.java index 6ff399a88d0..2ad1aa62465 100644 --- a/Mage.Sets/src/mage/cards/p/PyreOfHeroes.java +++ b/Mage.Sets/src/mage/cards/p/PyreOfHeroes.java @@ -40,9 +40,7 @@ public final class PyreOfHeroes extends CardImpl { Zone.BATTLEFIELD, new PyreOfHeroesEffect(), new GenericManaCost(2) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/q/QarsiHighPriest.java b/Mage.Sets/src/mage/cards/q/QarsiHighPriest.java index f20b96a217d..0efe20e02ad 100644 --- a/Mage.Sets/src/mage/cards/q/QarsiHighPriest.java +++ b/Mage.Sets/src/mage/cards/q/QarsiHighPriest.java @@ -33,7 +33,7 @@ public final class QarsiHighPriest extends CardImpl { // {1}{B}, {t}, Sacrifice another creature: Manifest the top card of your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ManifestEffect(1), new ManaCostsImpl<>("{1}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Ragamuffyn.java b/Mage.Sets/src/mage/cards/r/Ragamuffyn.java index f34b3d467ff..21f8e3433e9 100644 --- a/Mage.Sets/src/mage/cards/r/Ragamuffyn.java +++ b/Mage.Sets/src/mage/cards/r/Ragamuffyn.java @@ -41,7 +41,7 @@ public final class Ragamuffyn extends CardImpl { // Hellbent - {tap}, Sacrifice a creature or land: Draw a card. Activate this ability only if you have no cards in hand. Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD,new DrawCardSourceControllerEffect(1),new TapSourceCost(), HellbentCondition.instance); ability.setAbilityWord(AbilityWord.HELLBENT); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RaidingParty.java b/Mage.Sets/src/mage/cards/r/RaidingParty.java index e533c67b07a..52fa45cd59f 100644 --- a/Mage.Sets/src/mage/cards/r/RaidingParty.java +++ b/Mage.Sets/src/mage/cards/r/RaidingParty.java @@ -52,7 +52,7 @@ public final class RaidingParty extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filterWhite, Duration.WhileOnBattlefield))); // Sacrifice an Orc: Each player may tap any number of untapped white creatures they control. For each creature tapped this way, that player chooses up to two Plains. Then destroy all Plains that weren't chosen this way by any player. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RaidingPartyEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterOrc, true)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RaidingPartyEffect(), new SacrificeTargetCost(filterOrc))); } private RaidingParty(final RaidingParty card) { diff --git a/Mage.Sets/src/mage/cards/r/RamunapRuins.java b/Mage.Sets/src/mage/cards/r/RamunapRuins.java index 1f61ca20306..9549f6155e1 100644 --- a/Mage.Sets/src/mage/cards/r/RamunapRuins.java +++ b/Mage.Sets/src/mage/cards/r/RamunapRuins.java @@ -51,7 +51,7 @@ public final class RamunapRuins extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamagePlayersEffect(Outcome.Damage, StaticValue.get(2), TargetController.OPPONENT), new ManaCostsImpl<>("{2}{R}{R}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RathiDragon.java b/Mage.Sets/src/mage/cards/r/RathiDragon.java index e44e5e8b916..955c3858bae 100644 --- a/Mage.Sets/src/mage/cards/r/RathiDragon.java +++ b/Mage.Sets/src/mage/cards/r/RathiDragon.java @@ -37,7 +37,7 @@ public final class RathiDragon extends CardImpl { // When Rathi Dragon enters the battlefield, sacrifice it unless you sacrifice two Mountains. this.addAbility(new EntersBattlefieldTriggeredAbility( - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, filter, true))))); + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(2, filter)))); } private RathiDragon(final RathiDragon card) { diff --git a/Mage.Sets/src/mage/cards/r/RathsEdge.java b/Mage.Sets/src/mage/cards/r/RathsEdge.java index 37791363f6b..4ab90ece4e1 100644 --- a/Mage.Sets/src/mage/cards/r/RathsEdge.java +++ b/Mage.Sets/src/mage/cards/r/RathsEdge.java @@ -35,7 +35,7 @@ public final class RathsEdge extends CardImpl { // {4}, {tap}, Sacrifice a land: Rath's Edge deals 1 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl<>("{4}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RavenousBaloth.java b/Mage.Sets/src/mage/cards/r/RavenousBaloth.java index d99b23a637a..e970faafd9b 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousBaloth.java +++ b/Mage.Sets/src/mage/cards/r/RavenousBaloth.java @@ -34,7 +34,7 @@ public final class RavenousBaloth extends CardImpl { // Sacrifice a Beast: You gain 4 life. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(4), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true)))); + new SacrificeTargetCost(filter))); } private RavenousBaloth(final RavenousBaloth card) { diff --git a/Mage.Sets/src/mage/cards/r/RavenousDemon.java b/Mage.Sets/src/mage/cards/r/RavenousDemon.java index d4f60829f80..cef1ce7b990 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousDemon.java +++ b/Mage.Sets/src/mage/cards/r/RavenousDemon.java @@ -37,7 +37,7 @@ public final class RavenousDemon extends CardImpl { // Sacrifice a Human: Transform Ravenous Demon. Activate this ability only any time you could cast a sorcery. this.addAbility(new TransformAbility()); - this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new SacrificeTargetCost(filter))); } private RavenousDemon(final RavenousDemon card) { @@ -48,4 +48,4 @@ public final class RavenousDemon extends CardImpl { public RavenousDemon copy() { return new RavenousDemon(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/r/RavenousHarpy.java b/Mage.Sets/src/mage/cards/r/RavenousHarpy.java index 2bd73fd0bc3..b124670fc3b 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousHarpy.java +++ b/Mage.Sets/src/mage/cards/r/RavenousHarpy.java @@ -39,9 +39,7 @@ public final class RavenousHarpy extends CardImpl { new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RavenousIntruder.java b/Mage.Sets/src/mage/cards/r/RavenousIntruder.java index dd11bdfa072..c8c3561eaf9 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousIntruder.java +++ b/Mage.Sets/src/mage/cards/r/RavenousIntruder.java @@ -35,7 +35,7 @@ public final class RavenousIntruder extends CardImpl { this.toughness = new MageInt(2); // Sacrifice an artifact: Ravenous Intruder gets +2/+2 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new SacrificeTargetCost(filter))); } private RavenousIntruder(final RavenousIntruder card) { diff --git a/Mage.Sets/src/mage/cards/r/RavenousVampire.java b/Mage.Sets/src/mage/cards/r/RavenousVampire.java index e998df0f16e..a4b8547c94b 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousVampire.java +++ b/Mage.Sets/src/mage/cards/r/RavenousVampire.java @@ -45,7 +45,7 @@ public final class RavenousVampire extends CardImpl { new DoIfCostPaid( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new TapSourceEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)) + new SacrificeTargetCost(filter) ), TargetController.YOU, false )); diff --git a/Mage.Sets/src/mage/cards/r/RavenousWampa.java b/Mage.Sets/src/mage/cards/r/RavenousWampa.java index 678ec16af2f..d5f59e79c10 100644 --- a/Mage.Sets/src/mage/cards/r/RavenousWampa.java +++ b/Mage.Sets/src/mage/cards/r/RavenousWampa.java @@ -1,7 +1,6 @@ package mage.cards.r; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; @@ -11,16 +10,15 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.MonstrosityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import static mage.cards.r.RavenousWampa.RAVENOUS_WAMPA_STATE_VALUE_KEY_PREFIX; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; /** * @@ -38,7 +36,7 @@ public final class RavenousWampa extends CardImpl { // {2}{G}, Sacrifice another creature: Monstrosity 2. Ability ability = new MonstrosityAbility("{2}{G}", 2); - ability.addCost(new RavenousWampaSacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new RavenousWampaSacrificeTargetCost()); this.addAbility(ability); // When Ravenous Wampa becomes monstrous, you gain life equal to the sacrificied creature's toughness. @@ -57,9 +55,9 @@ public final class RavenousWampa extends CardImpl { class RavenousWampaEffect extends OneShotEffect { - public RavenousWampaEffect() { + RavenousWampaEffect() { super(Outcome.GainLife); - this.staticText = "you gain life equal to the sacrificied creature's toughness"; + this.staticText = "you gain life equal to the sacrificed creature's toughness"; } private RavenousWampaEffect(final RavenousWampaEffect effect) { @@ -76,7 +74,7 @@ class RavenousWampaEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourceObject != null) { - Integer toughness = (Integer) game.getState().getValue(RAVENOUS_WAMPA_STATE_VALUE_KEY_PREFIX + source.getSourceId() + sourceObject.getZoneChangeCounter(game)); + Integer toughness = (Integer) game.getState().getValue(RavenousWampa.RAVENOUS_WAMPA_STATE_VALUE_KEY_PREFIX + source.getSourceId() + sourceObject.getZoneChangeCounter(game)); if (toughness != null) { controller.gainLife(toughness, game, source); } @@ -88,8 +86,8 @@ class RavenousWampaEffect extends OneShotEffect { class RavenousWampaSacrificeTargetCost extends SacrificeTargetCost { - public RavenousWampaSacrificeTargetCost(TargetControlledPermanent target) { - super(target); + RavenousWampaSacrificeTargetCost() { + super(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE); } private RavenousWampaSacrificeTargetCost(final RavenousWampaSacrificeTargetCost cost) { @@ -103,7 +101,7 @@ class RavenousWampaSacrificeTargetCost extends SacrificeTargetCost { Permanent sacrificedPermanen = getPermanents().get(0); Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent != null && sacrificedPermanen != null) { - game.getState().setValue(RAVENOUS_WAMPA_STATE_VALUE_KEY_PREFIX + source.getSourceId() + sourcePermanent.getZoneChangeCounter(game), sacrificedPermanen.getToughness().getValue()); + game.getState().setValue(RavenousWampa.RAVENOUS_WAMPA_STATE_VALUE_KEY_PREFIX + source.getSourceId() + sourcePermanent.getZoneChangeCounter(game), sacrificedPermanen.getToughness().getValue()); } } return result; diff --git a/Mage.Sets/src/mage/cards/r/RazakethTheFoulblooded.java b/Mage.Sets/src/mage/cards/r/RazakethTheFoulblooded.java index 0ac2d389cd3..f16bc876ea3 100644 --- a/Mage.Sets/src/mage/cards/r/RazakethTheFoulblooded.java +++ b/Mage.Sets/src/mage/cards/r/RazakethTheFoulblooded.java @@ -42,8 +42,7 @@ public final class RazakethTheFoulblooded extends CardImpl { // Pay 2 life, Sacrifice another creature: Search your library for a card and put that card into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(), false, true), new PayLifeCost(2)); - ability.addCost(new SacrificeTargetCost( - new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/Raze.java b/Mage.Sets/src/mage/cards/r/Raze.java index 52c597997da..f045079f653 100644 --- a/Mage.Sets/src/mage/cards/r/Raze.java +++ b/Mage.Sets/src/mage/cards/r/Raze.java @@ -22,7 +22,7 @@ public final class Raze extends CardImpl { // As an additional cost to cast Raze, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); // Destroy target land. this.getSpellAbility().addEffect(new DestroyTargetEffect()); this.getSpellAbility().addTarget(new TargetLandPermanent()); diff --git a/Mage.Sets/src/mage/cards/r/ReadTheRunes.java b/Mage.Sets/src/mage/cards/r/ReadTheRunes.java index 4003fb791bb..2fd72cf5b92 100644 --- a/Mage.Sets/src/mage/cards/r/ReadTheRunes.java +++ b/Mage.Sets/src/mage/cards/r/ReadTheRunes.java @@ -8,12 +8,14 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -60,8 +62,8 @@ class ReadTheRunesEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { int drawnCards = controller.drawCards(source.getManaCostsToPay().getX(), source, game); - Target target = new TargetControlledPermanent(0, drawnCards, new FilterControlledPermanent(), true); - controller.chooseTarget(Outcome.Sacrifice, target, source, game); + Target target = new TargetSacrifice(0, drawnCards, StaticFilters.FILTER_PERMANENT); + controller.choose(Outcome.Sacrifice, target, source, game); int sacrificedPermanents = 0; for (UUID permanentId : target.getTargets()) { Permanent permanent = game.getPermanent(permanentId); diff --git a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java index 80cef1a84bf..8fa3e7731eb 100644 --- a/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java +++ b/Mage.Sets/src/mage/cards/r/ReapingTheRewards.java @@ -8,6 +8,7 @@ import mage.abilities.keyword.BuybackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -21,7 +22,7 @@ public final class ReapingTheRewards extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}"); // Buyback-Sacrifice a land. - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + this.addAbility(new BuybackAbility(new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // You gain 2 life. this.getSpellAbility().addEffect(new GainLifeEffect(2)); diff --git a/Mage.Sets/src/mage/cards/r/Reclamation.java b/Mage.Sets/src/mage/cards/r/Reclamation.java index c94fb49a1eb..99ec81e27bb 100644 --- a/Mage.Sets/src/mage/cards/r/Reclamation.java +++ b/Mage.Sets/src/mage/cards/r/Reclamation.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -47,7 +48,7 @@ class ReclamationCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl ReclamationCostToAttackBlockEffect() { super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK, - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); staticText = "Black creatures can't attack unless their controller sacrifices a land (This cost is paid as attackers are declared.)"; } diff --git a/Mage.Sets/src/mage/cards/r/RecurringNightmare.java b/Mage.Sets/src/mage/cards/r/RecurringNightmare.java index b0ff7867537..3a6fe963efb 100644 --- a/Mage.Sets/src/mage/cards/r/RecurringNightmare.java +++ b/Mage.Sets/src/mage/cards/r/RecurringNightmare.java @@ -27,7 +27,7 @@ public final class RecurringNightmare extends CardImpl { Ability ability = new ActivateAsSorceryActivatedAbility( Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) ); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); ability.addCost(new ReturnToHandFromBattlefieldSourceCost()); diff --git a/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java b/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java index 089ddf801e4..25d16b32146 100644 --- a/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java +++ b/Mage.Sets/src/mage/cards/r/RedcapGutterDweller.java @@ -44,7 +44,7 @@ public final class RedcapGutterDweller extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility( new DoIfCostPaid( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE), "Sacrifice another creature? If you do, put a +1/+1 counter on {this} " + "and exile the top card of your library. You may play that card this turn." ).addEffect(new ExileTopXMayPlayUntilEndOfTurnEffect(1, false) diff --git a/Mage.Sets/src/mage/cards/r/ReignOfThePit.java b/Mage.Sets/src/mage/cards/r/ReignOfThePit.java index 0c97563911c..11d36e849e5 100644 --- a/Mage.Sets/src/mage/cards/r/ReignOfThePit.java +++ b/Mage.Sets/src/mage/cards/r/ReignOfThePit.java @@ -7,12 +7,14 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.DemonFlyingToken; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.ArrayList; import java.util.List; @@ -67,7 +69,7 @@ class ReignOfThePitEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game)) { while (!target.isChosen() && player.canRespond()) { player.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/r/RelicVial.java b/Mage.Sets/src/mage/cards/r/RelicVial.java index a22a5602e7f..e4a09a024aa 100644 --- a/Mage.Sets/src/mage/cards/r/RelicVial.java +++ b/Mage.Sets/src/mage/cards/r/RelicVial.java @@ -41,9 +41,7 @@ public final class RelicVial extends CardImpl { new DrawCardSourceControllerEffect(1), new GenericManaCost(2) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); // As long as you control a Cleric, Relic Vial has "Whenever a creature you control dies, each opponent loses 1 life and you gain 1 life." diff --git a/Mage.Sets/src/mage/cards/r/Renewal.java b/Mage.Sets/src/mage/cards/r/Renewal.java index 7f921c6d4e6..408f5ca1e50 100644 --- a/Mage.Sets/src/mage/cards/r/Renewal.java +++ b/Mage.Sets/src/mage/cards/r/Renewal.java @@ -26,7 +26,7 @@ public final class Renewal extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}"); // As an additional cost to cast Renewal, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); // Search your library for a basic land card and put that card onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND), false, true)); diff --git a/Mage.Sets/src/mage/cards/r/Renounce.java b/Mage.Sets/src/mage/cards/r/Renounce.java index 71b0f75a809..4eb71ed7e98 100644 --- a/Mage.Sets/src/mage/cards/r/Renounce.java +++ b/Mage.Sets/src/mage/cards/r/Renounce.java @@ -8,11 +8,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -56,15 +58,15 @@ class RenounceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player == null){ + if (player == null) { return false; } int amount = 0; - TargetControlledPermanent toSacrifice = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledPermanent(), true); - if(player.chooseTarget(Outcome.Sacrifice, toSacrifice, source, game)) { - for(UUID uuid : toSacrifice.getTargets()){ + TargetSacrifice toSacrifice = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT); + if (player.choose(Outcome.Sacrifice, toSacrifice, source, game)) { + for (UUID uuid : toSacrifice.getTargets()) { Permanent permanent = game.getPermanent(uuid); - if(permanent != null){ + if (permanent != null) { permanent.sacrifice(source, game); amount++; } diff --git a/Mage.Sets/src/mage/cards/r/Reprocess.java b/Mage.Sets/src/mage/cards/r/Reprocess.java index 6dc47c46036..d1dc6a3a9f5 100644 --- a/Mage.Sets/src/mage/cards/r/Reprocess.java +++ b/Mage.Sets/src/mage/cards/r/Reprocess.java @@ -14,6 +14,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -69,8 +70,8 @@ class ReprocessEffect extends OneShotEffect { return false; } int amount = 0; - TargetControlledPermanent toSacrifice = new TargetControlledPermanent(0, Integer.MAX_VALUE, filter, true); - if(player.chooseTarget(Outcome.Sacrifice, toSacrifice, source, game)) { + TargetSacrifice toSacrifice = new TargetSacrifice(0, Integer.MAX_VALUE, filter); + if(player.choose(Outcome.Sacrifice, toSacrifice, source, game)) { for(UUID uuid : toSacrifice.getTargets()){ Permanent permanent = game.getPermanent(uuid); if(permanent != null){ diff --git a/Mage.Sets/src/mage/cards/r/RescueFromTheUnderworld.java b/Mage.Sets/src/mage/cards/r/RescueFromTheUnderworld.java index 14cce94107a..b1deb89a353 100644 --- a/Mage.Sets/src/mage/cards/r/RescueFromTheUnderworld.java +++ b/Mage.Sets/src/mage/cards/r/RescueFromTheUnderworld.java @@ -57,7 +57,7 @@ public final class RescueFromTheUnderworld extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{B}"); // As an additional cost to cast Rescue from the Underworld, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Choose target creature card in your graveyard. Return that card and the sacrificed card to the battlefield under your control at the beginning of your next upkeep. Exile Rescue from the Underworld. this.getSpellAbility().addEffect(new RescueFromTheUnderworldTextEffect()); diff --git a/Mage.Sets/src/mage/cards/r/Reshape.java b/Mage.Sets/src/mage/cards/r/Reshape.java index 8838a7426ff..31b37c9068a 100644 --- a/Mage.Sets/src/mage/cards/r/Reshape.java +++ b/Mage.Sets/src/mage/cards/r/Reshape.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.search.SearchLibraryWithLessCMCPutInPlayEff import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -21,7 +22,7 @@ public final class Reshape extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}{U}"); // As an additional cost to cast Reshape, sacrifice an artifact. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent("an artifact"), false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); // Search your library for an artifact card with converted mana cost X or less and put it onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryWithLessCMCPutInPlayEffect(new FilterArtifactCard())); diff --git a/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java b/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java index 2525c0588d9..4ad07aa614b 100644 --- a/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java +++ b/Mage.Sets/src/mage/cards/r/RestlessBloodseeker.java @@ -18,6 +18,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.permanent.TokenPredicate; import mage.game.permanent.token.BloodToken; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.watchers.common.PlayerGainedLifeWatcher; import java.util.UUID; @@ -54,7 +55,7 @@ public final class RestlessBloodseeker extends CardImpl { this.addAbility(new TransformAbility()); this.addAbility(new ActivateAsSorceryActivatedAbility( new TransformSourceEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) )); } diff --git a/Mage.Sets/src/mage/cards/r/RetrofitterFoundry.java b/Mage.Sets/src/mage/cards/r/RetrofitterFoundry.java index 463b2b873e7..e2a8ce11169 100644 --- a/Mage.Sets/src/mage/cards/r/RetrofitterFoundry.java +++ b/Mage.Sets/src/mage/cards/r/RetrofitterFoundry.java @@ -57,7 +57,7 @@ public final class RetrofitterFoundry extends CardImpl { new GenericManaCost(1) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter1))); + ability.addCost(new SacrificeTargetCost(filter1)); this.addAbility(ability); // {T}, Sacrifice a Thopter: Create a 4/4 colorless Construct artifact creature token. @@ -65,7 +65,7 @@ public final class RetrofitterFoundry extends CardImpl { new CreateTokenEffect(new Construct4Token()), new TapSourceCost() ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RhysTheExiled.java b/Mage.Sets/src/mage/cards/r/RhysTheExiled.java index 7c05f5b65e5..3bc7e571bf4 100644 --- a/Mage.Sets/src/mage/cards/r/RhysTheExiled.java +++ b/Mage.Sets/src/mage/cards/r/RhysTheExiled.java @@ -44,7 +44,7 @@ public final class RhysTheExiled extends CardImpl { // {B}, Sacrifice an Elf: Regenerate Rhys the Exiled. Ability ability = new SimpleActivatedAbility(new RegenerateSourceEffect(), new ManaCostsImpl<>("{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RiteOfConsumption.java b/Mage.Sets/src/mage/cards/r/RiteOfConsumption.java index ffd779ac0ed..58a3a2b9ece 100644 --- a/Mage.Sets/src/mage/cards/r/RiteOfConsumption.java +++ b/Mage.Sets/src/mage/cards/r/RiteOfConsumption.java @@ -27,7 +27,7 @@ public final class RiteOfConsumption extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // As an additional cost to cast Rite of Consumption, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Rite of Consumption deals damage equal to the sacrificed creature's power to target player. You gain life equal to the damage dealt this way. this.getSpellAbility().addEffect(new RiteOfConsumptionEffect()); this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker()); diff --git a/Mage.Sets/src/mage/cards/r/RiteOfOblivion.java b/Mage.Sets/src/mage/cards/r/RiteOfOblivion.java index b0c85137e9b..3d1bb938b89 100644 --- a/Mage.Sets/src/mage/cards/r/RiteOfOblivion.java +++ b/Mage.Sets/src/mage/cards/r/RiteOfOblivion.java @@ -30,7 +30,7 @@ public final class RiteOfOblivion extends CardImpl { // As an additional cost to cast this spell, sacrifice a nonland permanent. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); // Exile target nonland permanent this.getSpellAbility().addEffect(new ExileTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/r/RogueElephant.java b/Mage.Sets/src/mage/cards/r/RogueElephant.java index 87b1c955082..eda0aab6409 100644 --- a/Mage.Sets/src/mage/cards/r/RogueElephant.java +++ b/Mage.Sets/src/mage/cards/r/RogueElephant.java @@ -32,7 +32,7 @@ public final class RogueElephant extends CardImpl { this.toughness = new MageInt(3); // When Rogue Elephant enters the battlefield, sacrifice it unless you sacrifice a Forest. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)))); } private RogueElephant(final RogueElephant card) { diff --git a/Mage.Sets/src/mage/cards/r/RootwaterAlligator.java b/Mage.Sets/src/mage/cards/r/RootwaterAlligator.java index 24b251d363e..f66faf5b9d3 100644 --- a/Mage.Sets/src/mage/cards/r/RootwaterAlligator.java +++ b/Mage.Sets/src/mage/cards/r/RootwaterAlligator.java @@ -33,7 +33,7 @@ public final class RootwaterAlligator extends CardImpl { this.toughness = new MageInt(2); // Sacrifice a Forest: Regenerate Rootwater Alligator. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(filter))); } private RootwaterAlligator(final RootwaterAlligator card) { diff --git a/Mage.Sets/src/mage/cards/r/Rupture.java b/Mage.Sets/src/mage/cards/r/Rupture.java index 6000bd3ac1a..da43d281a8d 100644 --- a/Mage.Sets/src/mage/cards/r/Rupture.java +++ b/Mage.Sets/src/mage/cards/r/Rupture.java @@ -10,6 +10,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; @@ -18,6 +19,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -64,10 +66,10 @@ class RuptureEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); if (player != null) { int power = 0; - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("creature to sacrifice"), true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game)) { while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); } Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { diff --git a/Mage.Sets/src/mage/cards/r/RushingRiver.java b/Mage.Sets/src/mage/cards/r/RushingRiver.java index 613dbfe92a5..120a95cf86c 100644 --- a/Mage.Sets/src/mage/cards/r/RushingRiver.java +++ b/Mage.Sets/src/mage/cards/r/RushingRiver.java @@ -10,6 +10,7 @@ import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.target.common.TargetControlledPermanent; @@ -29,7 +30,7 @@ public final class RushingRiver extends CardImpl { // Kicker-Sacrifice a land. - this.addAbility(new KickerAbility(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + this.addAbility(new KickerAbility(new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // Return target nonland permanent to its owner's hand. If Rushing River was kicked, return another target nonland permanent to its owner's hand. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); @@ -63,4 +64,4 @@ enum RushingRiverAdjuster implements TargetAdjuster { ability.addTarget(new TargetNonlandPermanent(2)); } } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/r/RustElemental.java b/Mage.Sets/src/mage/cards/r/RustElemental.java index 4b567378e76..ab148557dd1 100644 --- a/Mage.Sets/src/mage/cards/r/RustElemental.java +++ b/Mage.Sets/src/mage/cards/r/RustElemental.java @@ -17,6 +17,7 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -76,7 +77,7 @@ class RustElementalEffect extends OneShotEffect { // create cost for sacrificing an artifact Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(filter); // if they can pay the cost, then they must pay if (target.canChoose(controller.getId(), source, game)) { controller.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/r/RustMonster.java b/Mage.Sets/src/mage/cards/r/RustMonster.java index c2e226d5fad..0eeee912a38 100644 --- a/Mage.Sets/src/mage/cards/r/RustMonster.java +++ b/Mage.Sets/src/mage/cards/r/RustMonster.java @@ -33,7 +33,7 @@ public final class RustMonster extends CardImpl { // Sacrifice an artifact: Rust Monster gets +2/+0 until end of turn. this.addAbility(new SimpleActivatedAbility( new BoostSourceEffect(2, 0, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) )); } diff --git a/Mage.Sets/src/mage/cards/r/RustedSlasher.java b/Mage.Sets/src/mage/cards/r/RustedSlasher.java index 96b62615972..fa796f32ecd 100644 --- a/Mage.Sets/src/mage/cards/r/RustedSlasher.java +++ b/Mage.Sets/src/mage/cards/r/RustedSlasher.java @@ -32,7 +32,7 @@ public final class RustedSlasher extends CardImpl { this.subtype.add(SubType.HORROR); this.power = new MageInt(4); this.toughness = new MageInt(1); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(filter))); } private RustedSlasher(final RustedSlasher card) { diff --git a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java index 71a46746d89..dc6c96eef25 100644 --- a/Mage.Sets/src/mage/cards/r/RuthlessKnave.java +++ b/Mage.Sets/src/mage/cards/r/RuthlessKnave.java @@ -49,7 +49,7 @@ public final class RuthlessKnave extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, false)) + new SacrificeTargetCost(3, filter) )); } diff --git a/Mage.Sets/src/mage/cards/s/SacredMesa.java b/Mage.Sets/src/mage/cards/s/SacredMesa.java index cb0f69113d5..1abf64ac21a 100644 --- a/Mage.Sets/src/mage/cards/s/SacredMesa.java +++ b/Mage.Sets/src/mage/cards/s/SacredMesa.java @@ -33,7 +33,7 @@ public final class SacredMesa extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}"); // At the beginning of your upkeep, sacrifice Sacred Mesa unless you sacrifice a Pegasus. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))), TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)), TargetController.YOU, false)); // {1}{W}: Create a 1/1 white Pegasus creature token with flying. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new PegasusToken()), new ManaCostsImpl<>("{1}{W}"))); diff --git a/Mage.Sets/src/mage/cards/s/SageOfLatNam.java b/Mage.Sets/src/mage/cards/s/SageOfLatNam.java index f0306c190c2..b99151a59a0 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfLatNam.java +++ b/Mage.Sets/src/mage/cards/s/SageOfLatNam.java @@ -32,7 +32,7 @@ public final class SageOfLatNam extends CardImpl { // {T}, Sacrifice an artifact: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SaiMasterThopterist.java b/Mage.Sets/src/mage/cards/s/SaiMasterThopterist.java index 197e1c72aee..dd846ac7485 100644 --- a/Mage.Sets/src/mage/cards/s/SaiMasterThopterist.java +++ b/Mage.Sets/src/mage/cards/s/SaiMasterThopterist.java @@ -46,9 +46,7 @@ public final class SaiMasterThopterist extends CardImpl { new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{U}") ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(2, 2, filter2, false) - )); + ability.addCost(new SacrificeTargetCost(2, filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SalvageSquad.java b/Mage.Sets/src/mage/cards/s/SalvageSquad.java index e354a132843..8c8bc52c40e 100644 --- a/Mage.Sets/src/mage/cards/s/SalvageSquad.java +++ b/Mage.Sets/src/mage/cards/s/SalvageSquad.java @@ -12,6 +12,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -29,7 +30,7 @@ public final class SalvageSquad extends CardImpl { this.toughness = new MageInt(2); // When you Salvage Squad enters the battlefied, you may sacrifice an artifact. If you do, you gain 2 life and draw two cards. - DoIfCostPaid effect = new DoIfCostPaid(new GainLifeEffect(2), new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent()))); + DoIfCostPaid effect = new DoIfCostPaid(new GainLifeEffect(2), new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); effect.addEffect(new DrawCardSourceControllerEffect(2)); this.addAbility(new EntersBattlefieldTriggeredAbility(effect)); } diff --git a/Mage.Sets/src/mage/cards/s/SalvageTitan.java b/Mage.Sets/src/mage/cards/s/SalvageTitan.java index 2c163626e44..42378d8ff4f 100644 --- a/Mage.Sets/src/mage/cards/s/SalvageTitan.java +++ b/Mage.Sets/src/mage/cards/s/SalvageTitan.java @@ -32,7 +32,7 @@ public final class SalvageTitan extends CardImpl { this.toughness = new MageInt(4); // You may sacrifice three artifacts rather than pay Salvage Titan's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, new FilterControlledArtifactPermanent("artifacts"), true)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(3, StaticFilters.FILTER_PERMANENT_ARTIFACTS))); // Exile three artifact cards from your graveyard: Return Salvage Titan from your graveyard to your hand. this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ExileFromGraveCost(new TargetCardInYourGraveyard(3, StaticFilters.FILTER_CARD_ARTIFACTS)))); diff --git a/Mage.Sets/src/mage/cards/s/SamwiseGamgee.java b/Mage.Sets/src/mage/cards/s/SamwiseGamgee.java index 32b9ef0f08e..ce4132a5c80 100644 --- a/Mage.Sets/src/mage/cards/s/SamwiseGamgee.java +++ b/Mage.Sets/src/mage/cards/s/SamwiseGamgee.java @@ -54,7 +54,7 @@ public final class SamwiseGamgee extends CardImpl { // Sacrifice three Foods: Return target historic card from your graveyard to your hand. Ability ability = new SimpleActivatedAbility( new ReturnFromGraveyardToHandTargetEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(3, filter2)) + new SacrificeTargetCost(3, filter2) ); ability.addTarget(new TargetCardInYourGraveyard(filter3)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/SandstoneDeadfall.java b/Mage.Sets/src/mage/cards/s/SandstoneDeadfall.java index c5988eaeb6b..923f603a4ee 100644 --- a/Mage.Sets/src/mage/cards/s/SandstoneDeadfall.java +++ b/Mage.Sets/src/mage/cards/s/SandstoneDeadfall.java @@ -11,6 +11,7 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetAttackingCreature; @@ -26,7 +27,7 @@ public final class SandstoneDeadfall extends CardImpl { // {tap}, Sacrifice two lands and Sandstone Deadfall: Destroy target attacking creature. Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS)); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetAttackingCreature()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/Sarcatog.java b/Mage.Sets/src/mage/cards/s/Sarcatog.java index 8c980a5cc44..70775c6422a 100644 --- a/Mage.Sets/src/mage/cards/s/Sarcatog.java +++ b/Mage.Sets/src/mage/cards/s/Sarcatog.java @@ -14,6 +14,7 @@ import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetControlledPermanent; @@ -41,7 +42,7 @@ public final class Sarcatog extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("artifact"))))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT))); } private Sarcatog(final Sarcatog card) { diff --git a/Mage.Sets/src/mage/cards/s/SarlaccPit.java b/Mage.Sets/src/mage/cards/s/SarlaccPit.java index f4f3e74e6b3..e7eb54402aa 100644 --- a/Mage.Sets/src/mage/cards/s/SarlaccPit.java +++ b/Mage.Sets/src/mage/cards/s/SarlaccPit.java @@ -18,6 +18,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -41,7 +42,7 @@ public final class SarlaccPit extends CardImpl { // {R}{G}, Sacrifice a land: Monstrosity 1. Ability ability = new MonstrosityAbility("{R}{G}", 1); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(ability); // When Sarlacc Pit becomes monstrous, it loses hexproof and gains first strike and deathtouch. diff --git a/Mage.Sets/src/mage/cards/s/SavageThallid.java b/Mage.Sets/src/mage/cards/s/SavageThallid.java index 1217b395c9e..a74071d99b3 100644 --- a/Mage.Sets/src/mage/cards/s/SavageThallid.java +++ b/Mage.Sets/src/mage/cards/s/SavageThallid.java @@ -55,7 +55,7 @@ public final class SavageThallid extends CardImpl { // Sacrifice a Saproling: Regenerate target Fungus. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter2, false))); + new SacrificeTargetCost(filter2)); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SavraQueenOfTheGolgari.java b/Mage.Sets/src/mage/cards/s/SavraQueenOfTheGolgari.java index 395fd3d4e80..f3c6f0b292f 100644 --- a/Mage.Sets/src/mage/cards/s/SavraQueenOfTheGolgari.java +++ b/Mage.Sets/src/mage/cards/s/SavraQueenOfTheGolgari.java @@ -18,11 +18,13 @@ import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -109,10 +111,9 @@ class SavraSacrificeEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !playerId.equals(source.getControllerId())) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } diff --git a/Mage.Sets/src/mage/cards/s/SavvyHunter.java b/Mage.Sets/src/mage/cards/s/SavvyHunter.java index 3e184b35b9b..39100c7f37e 100644 --- a/Mage.Sets/src/mage/cards/s/SavvyHunter.java +++ b/Mage.Sets/src/mage/cards/s/SavvyHunter.java @@ -13,6 +13,7 @@ import mage.constants.SubType; import mage.filter.common.FilterControlledPermanent; import mage.game.permanent.token.FoodToken; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -37,7 +38,7 @@ public final class SavvyHunter extends CardImpl { // Sacrifice two Foods: Draw a card. this.addAbility(new SimpleActivatedAbility( new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(2, filter)) + new SacrificeTargetCost(2, filter) )); } diff --git a/Mage.Sets/src/mage/cards/s/Scapeshift.java b/Mage.Sets/src/mage/cards/s/Scapeshift.java index d7bda0b734f..36769395f22 100644 --- a/Mage.Sets/src/mage/cards/s/Scapeshift.java +++ b/Mage.Sets/src/mage/cards/s/Scapeshift.java @@ -10,6 +10,7 @@ import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterLandCard; import mage.game.Game; @@ -17,6 +18,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -64,8 +66,8 @@ class ScapeshiftEffect extends OneShotEffect { return false; } int amount = 0; - TargetControlledPermanent sacrificeLand = new TargetControlledPermanent(0, Integer.MAX_VALUE, new FilterControlledLandPermanent("lands you control"), true); - if (controller.chooseTarget(Outcome.Sacrifice, sacrificeLand, source, game)) { + TargetSacrifice sacrificeLand = new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_LANDS); + if (controller.choose(Outcome.Sacrifice, sacrificeLand, source, game)) { for (UUID uuid : sacrificeLand.getTargets()) { Permanent land = game.getPermanent(uuid); if (land != null) { diff --git a/Mage.Sets/src/mage/cards/s/Scarecrone.java b/Mage.Sets/src/mage/cards/s/Scarecrone.java index 682158b8adf..7cd461b4c74 100644 --- a/Mage.Sets/src/mage/cards/s/Scarecrone.java +++ b/Mage.Sets/src/mage/cards/s/Scarecrone.java @@ -41,7 +41,7 @@ public final class Scarecrone extends CardImpl { // {1}, Sacrifice a Scarecrow: Draw a card. Ability firstAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(1)); - firstAbility.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterScarecrow, false))); + firstAbility.addCost(new SacrificeTargetCost(filterScarecrow)); this.addAbility(firstAbility); // {4}, {T}: Return target artifact creature card from your graveyard to the battlefield. diff --git a/Mage.Sets/src/mage/cards/s/ScavengerGrounds.java b/Mage.Sets/src/mage/cards/s/ScavengerGrounds.java index db84024227d..4489de94ec6 100644 --- a/Mage.Sets/src/mage/cards/s/ScavengerGrounds.java +++ b/Mage.Sets/src/mage/cards/s/ScavengerGrounds.java @@ -43,7 +43,7 @@ public final class ScavengerGrounds extends CardImpl { new ExileGraveyardAllPlayersEffect(), new ManaCostsImpl<>("{2}")); ability2.addCost(new TapSourceCost()); - ability2.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability2.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/s/ScionOfOpulence.java b/Mage.Sets/src/mage/cards/s/ScionOfOpulence.java index 2233763e73f..d95ccf90d3d 100644 --- a/Mage.Sets/src/mage/cards/s/ScionOfOpulence.java +++ b/Mage.Sets/src/mage/cards/s/ScionOfOpulence.java @@ -52,7 +52,7 @@ public final class ScionOfOpulence extends CardImpl { Ability ability = new SimpleActivatedAbility( new ExileTopXMayPlayUntilEndOfTurnEffect(1), new ManaCostsImpl<>("{R}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter2))); + ability.addCost(new SacrificeTargetCost(2, filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ScorchedRuins.java b/Mage.Sets/src/mage/cards/s/ScorchedRuins.java index 33dbe1f1cc6..cf661a5f402 100644 --- a/Mage.Sets/src/mage/cards/s/ScorchedRuins.java +++ b/Mage.Sets/src/mage/cards/s/ScorchedRuins.java @@ -32,7 +32,7 @@ public final class ScorchedRuins extends CardImpl { // If Scorched Ruins would enter the battlefield, sacrifice two untapped lands instead. // If you do, put Scorched Ruins onto the battlefield. If you don't, put it into its // owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(2,2,filter,false))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(2, filter)))); // {tap}: Add {C}{C}{C}{C} this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(4), new TapSourceCost())); diff --git a/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java b/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java index 8188fdf1bdf..ed6ba17bfca 100644 --- a/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java +++ b/Mage.Sets/src/mage/cards/s/ScourgeOfNelToth.java @@ -15,6 +15,7 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; @@ -79,7 +80,7 @@ class ScourgeOfNelTothPlayEffect extends AsThoughEffectImpl { Player player = game.getPlayer(affectedControllerId); if (player != null) { Costs costs = new CostsImpl<>(); - costs.add(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2))); + costs.add(new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_CREATURES)); player.setCastSourceIdWithAlternateMana( sourceId, new ManaCostsImpl<>("{B}{B}"), costs, MageIdentifier.ScourgeOfNelTothAlternateCast diff --git a/Mage.Sets/src/mage/cards/s/ScourgeOfSkolaVale.java b/Mage.Sets/src/mage/cards/s/ScourgeOfSkolaVale.java index bdc21fdb92b..129d8321fc6 100644 --- a/Mage.Sets/src/mage/cards/s/ScourgeOfSkolaVale.java +++ b/Mage.Sets/src/mage/cards/s/ScourgeOfSkolaVale.java @@ -46,7 +46,7 @@ public final class ScourgeOfSkolaVale extends CardImpl { this.addAbility(new EntersBattlefieldAbility(effect)); // {T}, Sacrifice another creature: Put a number of +1/+1 counters on Scourge of Skola Vale equal to the sacrificed creature's toughness. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScourgeOfSkolaValeEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ScrapyardRecombiner.java b/Mage.Sets/src/mage/cards/s/ScrapyardRecombiner.java index e4eb401d2dd..cd2233e0142 100644 --- a/Mage.Sets/src/mage/cards/s/ScrapyardRecombiner.java +++ b/Mage.Sets/src/mage/cards/s/ScrapyardRecombiner.java @@ -46,7 +46,7 @@ public final class ScrapyardRecombiner extends CardImpl { Ability ability = new SimpleActivatedAbility( new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true), new TapSourceCost() ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ScrapyardSteelbreaker.java b/Mage.Sets/src/mage/cards/s/ScrapyardSteelbreaker.java index 50bca8eac09..7cef7428e7f 100644 --- a/Mage.Sets/src/mage/cards/s/ScrapyardSteelbreaker.java +++ b/Mage.Sets/src/mage/cards/s/ScrapyardSteelbreaker.java @@ -42,7 +42,7 @@ public final class ScrapyardSteelbreaker extends CardImpl { Ability ability = new SimpleActivatedAbility( new BoostSourceEffect(2, 1, Duration.EndOfTurn), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ScytheTiger.java b/Mage.Sets/src/mage/cards/s/ScytheTiger.java index 5162eb79804..4d7cd8563e1 100644 --- a/Mage.Sets/src/mage/cards/s/ScytheTiger.java +++ b/Mage.Sets/src/mage/cards/s/ScytheTiger.java @@ -31,7 +31,7 @@ public final class ScytheTiger extends CardImpl { this.addAbility(ShroudAbility.getInstance()); // When Scythe Tiger enters the battlefield, sacrifice it unless you sacrifice a land. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))).setText("sacrifice it unless you sacrifice a land"))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)).setText("sacrifice it unless you sacrifice a land"))); } private ScytheTiger(final ScytheTiger card) { diff --git a/Mage.Sets/src/mage/cards/s/SeasideHaven.java b/Mage.Sets/src/mage/cards/s/SeasideHaven.java index 61f1f5536e7..bb6584bc2a2 100644 --- a/Mage.Sets/src/mage/cards/s/SeasideHaven.java +++ b/Mage.Sets/src/mage/cards/s/SeasideHaven.java @@ -37,7 +37,7 @@ public final class SeasideHaven extends CardImpl { // {W}{U}, {tap}, Sacrifice a Bird: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{W}{U}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SeethingPathblazer.java b/Mage.Sets/src/mage/cards/s/SeethingPathblazer.java index 2d98395c8de..ff51805e462 100644 --- a/Mage.Sets/src/mage/cards/s/SeethingPathblazer.java +++ b/Mage.Sets/src/mage/cards/s/SeethingPathblazer.java @@ -33,7 +33,7 @@ public final class SeethingPathblazer extends CardImpl { this.toughness = new MageInt(2); Ability ability = new SimpleActivatedAbility(new BoostSourceEffect( 2, 0, Duration.EndOfTurn - ).setText("{this} gets +2/+0"), new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ).setText("{this} gets +2/+0"), new SacrificeTargetCost(filter)); ability.addEffect(new GainAbilitySourceEffect( FirstStrikeAbility.getInstance(), Duration.EndOfTurn ).setText("and gains first strike until end of turn")); diff --git a/Mage.Sets/src/mage/cards/s/SekkiSeasonsGuide.java b/Mage.Sets/src/mage/cards/s/SekkiSeasonsGuide.java index 30984980fbf..da02492fa93 100644 --- a/Mage.Sets/src/mage/cards/s/SekkiSeasonsGuide.java +++ b/Mage.Sets/src/mage/cards/s/SekkiSeasonsGuide.java @@ -22,6 +22,7 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.permanent.token.SpiritToken; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -53,7 +54,7 @@ public final class SekkiSeasonsGuide extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.GRAVEYARD, new ReturnSourceFromGraveyardToBattlefieldEffect(false, false), - new SacrificeTargetCost(new TargetControlledPermanent(8, 8, filter, true)))); + new SacrificeTargetCost(new TargetSacrifice(8, filter)))); } private SekkiSeasonsGuide(final SekkiSeasonsGuide card) { diff --git a/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java b/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java index 6d68a4dd1ce..c81463c9fac 100644 --- a/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java +++ b/Mage.Sets/src/mage/cards/s/SelfInflictedWound.java @@ -11,6 +11,7 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.filter.common.FilterControlledPermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; @@ -18,6 +19,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; /** * @@ -46,6 +48,15 @@ public final class SelfInflictedWound extends CardImpl { class SelfInflictedWoundEffect extends OneShotEffect { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a green or white creature"); + + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.GREEN), + new ColorPredicate(ObjectColor.WHITE) + )); + } + SelfInflictedWoundEffect() { super(Outcome.Sacrifice); staticText = "Target opponent sacrifices a green or white creature. If that player does, they lose 2 life"; @@ -67,14 +78,9 @@ class SelfInflictedWoundEffect extends OneShotEffect { if (targetOpponent == null || controller == null) { return false; } - FilterControlledPermanent filter = new FilterControlledPermanent("a green or white creature"); - filter.add(CardType.CREATURE.getPredicate()); - filter.add(TargetController.YOU.getControllerPredicate()); - filter.add(Predicates.or(new ColorPredicate(ObjectColor.GREEN), new ColorPredicate(ObjectColor.WHITE))); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); - + TargetSacrifice target = new TargetSacrifice(filter); if (target.canChoose(targetOpponent.getId(), source, game)) { - targetOpponent.chooseTarget(Outcome.Sacrifice, target, source, game); + targetOpponent.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { if (permanent.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/s/SepulcherGhoul.java b/Mage.Sets/src/mage/cards/s/SepulcherGhoul.java index 3c1721f5bd7..abfca3d43eb 100644 --- a/Mage.Sets/src/mage/cards/s/SepulcherGhoul.java +++ b/Mage.Sets/src/mage/cards/s/SepulcherGhoul.java @@ -31,7 +31,7 @@ public final class SepulcherGhoul extends CardImpl { this.addAbility(new LimitedTimesPerTurnActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) )); } diff --git a/Mage.Sets/src/mage/cards/s/SerendibDjinn.java b/Mage.Sets/src/mage/cards/s/SerendibDjinn.java index da5bf6e1dd3..f0211272f30 100644 --- a/Mage.Sets/src/mage/cards/s/SerendibDjinn.java +++ b/Mage.Sets/src/mage/cards/s/SerendibDjinn.java @@ -17,6 +17,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -73,7 +74,7 @@ class SerendibDjinnEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Target target = new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND); if (target.canChoose(controller.getId(), source, game)) { controller.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/s/SeveredStrands.java b/Mage.Sets/src/mage/cards/s/SeveredStrands.java index d1466b969b8..258f2c64941 100644 --- a/Mage.Sets/src/mage/cards/s/SeveredStrands.java +++ b/Mage.Sets/src/mage/cards/s/SeveredStrands.java @@ -22,7 +22,7 @@ public final class SeveredStrands extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}"); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // You gain life equal to the sacrificed creature's toughness. Destroy target creature an opponent controls. this.getSpellAbility().addEffect(new GainLifeEffect( diff --git a/Mage.Sets/src/mage/cards/s/ShadowbornApostle.java b/Mage.Sets/src/mage/cards/s/ShadowbornApostle.java index 88753702518..9b0284512ed 100644 --- a/Mage.Sets/src/mage/cards/s/ShadowbornApostle.java +++ b/Mage.Sets/src/mage/cards/s/ShadowbornApostle.java @@ -47,7 +47,7 @@ public final class ShadowbornApostle extends CardImpl { // {B}, Sacrifice six creatures named Shadowborn Apostle: Search your library for a Demon creature and put it onto the battlefield. Then shuffle your library. Effect effect = new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(filter), false); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(6,6,filterApostle, false))); + ability.addCost(new SacrificeTargetCost(6, filterApostle)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ShardVolley.java b/Mage.Sets/src/mage/cards/s/ShardVolley.java index f5163bc4e4d..5650cd6b2e5 100644 --- a/Mage.Sets/src/mage/cards/s/ShardVolley.java +++ b/Mage.Sets/src/mage/cards/s/ShardVolley.java @@ -22,7 +22,7 @@ public final class ShardVolley extends CardImpl { // As an additional cost to cast Shard Volley, sacrifice a land. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); // Shard Volley deals 3 damage to any target. this.getSpellAbility().addEffect(new DamageTargetEffect(3)); diff --git a/Mage.Sets/src/mage/cards/s/ShattergangBrothers.java b/Mage.Sets/src/mage/cards/s/ShattergangBrothers.java index dcec812e023..cfd69bc0701 100644 --- a/Mage.Sets/src/mage/cards/s/ShattergangBrothers.java +++ b/Mage.Sets/src/mage/cards/s/ShattergangBrothers.java @@ -47,13 +47,13 @@ public final class ShattergangBrothers extends CardImpl { // {2}{R}, Sacrifice an artifact: Each other player sacrifices an artifact. FilterControlledPermanent filter = new FilterControlledArtifactPermanent("an artifact"); ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShattergangBrothersEffect(filter), new ManaCostsImpl<>("{2}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // {2}{G}, Sacrifice an enchantment: Each other player sacrifices an enchantment. filter = new FilterControlledPermanent("an enchantment"); filter.add(CardType.ENCHANTMENT.getPredicate()); ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShattergangBrothersEffect(filter), new ManaCostsImpl<>("{2}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ShefetDunes.java b/Mage.Sets/src/mage/cards/s/ShefetDunes.java index f5724b9d3c2..eea66aa9444 100644 --- a/Mage.Sets/src/mage/cards/s/ShefetDunes.java +++ b/Mage.Sets/src/mage/cards/s/ShefetDunes.java @@ -51,7 +51,7 @@ public final class ShefetDunes extends CardImpl { new BoostControlledEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{W}{W}")); ability2.addCost(new TapSourceCost()); - ability2.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filterDesertPermanent, true))); + ability2.addCost(new SacrificeTargetCost(filterDesertPermanent)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/s/ShivanWumpus.java b/Mage.Sets/src/mage/cards/s/ShivanWumpus.java index 65882085c12..b644baf2702 100644 --- a/Mage.Sets/src/mage/cards/s/ShivanWumpus.java +++ b/Mage.Sets/src/mage/cards/s/ShivanWumpus.java @@ -14,6 +14,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.players.Player; @@ -70,7 +71,7 @@ class ShivanWumpusEffect extends PutOnLibrarySourceEffect { if (controller != null) { boolean costPaid = false; for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent())); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_LAND); Player player = game.getPlayer(playerId); if (player != null && cost.canPay(source, source, playerId, game) diff --git a/Mage.Sets/src/mage/cards/s/ShrapnelBlast.java b/Mage.Sets/src/mage/cards/s/ShrapnelBlast.java index 2f1875d2be2..d5967db4ddd 100644 --- a/Mage.Sets/src/mage/cards/s/ShrapnelBlast.java +++ b/Mage.Sets/src/mage/cards/s/ShrapnelBlast.java @@ -25,7 +25,7 @@ public final class ShrapnelBlast extends CardImpl { public ShrapnelBlast(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filter)); this.getSpellAbility().addEffect(new DamageTargetEffect(5)); this.getSpellAbility().addTarget(new TargetAnyTarget()); } diff --git a/Mage.Sets/src/mage/cards/s/SiegeGangCommander.java b/Mage.Sets/src/mage/cards/s/SiegeGangCommander.java index 8c08fe05539..2b9b9f16e53 100644 --- a/Mage.Sets/src/mage/cards/s/SiegeGangCommander.java +++ b/Mage.Sets/src/mage/cards/s/SiegeGangCommander.java @@ -40,7 +40,7 @@ public final class SiegeGangCommander extends CardImpl { this.toughness = new MageInt(2); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new GoblinToken(), 3), false)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SilvarDevourerOfTheFree.java b/Mage.Sets/src/mage/cards/s/SilvarDevourerOfTheFree.java index b6b82bad9be..b5ee45b67e8 100644 --- a/Mage.Sets/src/mage/cards/s/SilvarDevourerOfTheFree.java +++ b/Mage.Sets/src/mage/cards/s/SilvarDevourerOfTheFree.java @@ -47,7 +47,7 @@ public final class SilvarDevourerOfTheFree extends CardImpl { // Sacrifice a Human: Put a +1/+1 counter on Silvar, Devourer of the Free. It gains indestructible until end of turn. Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) ); ability.addEffect(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn diff --git a/Mage.Sets/src/mage/cards/s/SkeletalVampire.java b/Mage.Sets/src/mage/cards/s/SkeletalVampire.java index 265cf143e30..10a0b7fd00e 100644 --- a/Mage.Sets/src/mage/cards/s/SkeletalVampire.java +++ b/Mage.Sets/src/mage/cards/s/SkeletalVampire.java @@ -46,10 +46,10 @@ public final class SkeletalVampire extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BatToken(), 2))); // {3}{B}{B}, Sacrifice a Bat: Create two 1/1 black Bat creature tokens with flying. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new BatToken(), 2), new ManaCostsImpl<>("{3}{B}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // Sacrifice a Bat: Regenerate Skeletal Vampire. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(filter))); } private SkeletalVampire(final SkeletalVampire card) { @@ -61,4 +61,3 @@ public final class SkeletalVampire extends CardImpl { return new SkeletalVampire(this); } } - diff --git a/Mage.Sets/src/mage/cards/s/SkirkProspector.java b/Mage.Sets/src/mage/cards/s/SkirkProspector.java index 18517de3819..b4b2a3f0405 100644 --- a/Mage.Sets/src/mage/cards/s/SkirkProspector.java +++ b/Mage.Sets/src/mage/cards/s/SkirkProspector.java @@ -36,7 +36,7 @@ public final class SkirkProspector extends CardImpl { // Sacrifice a Goblin: Add {R}. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.RedMana(1), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter,true)), + new SacrificeTargetCost(filter), new PermanentsOnBattlefieldCount(filter))); } diff --git a/Mage.Sets/src/mage/cards/s/SkirkVolcanist.java b/Mage.Sets/src/mage/cards/s/SkirkVolcanist.java index d130eeb8114..536733d44c2 100644 --- a/Mage.Sets/src/mage/cards/s/SkirkVolcanist.java +++ b/Mage.Sets/src/mage/cards/s/SkirkVolcanist.java @@ -14,6 +14,7 @@ import mage.constants.SubType; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.common.TargetSacrifice; /** * @@ -34,7 +35,7 @@ public final class SkirkVolcanist extends CardImpl { this.toughness = new MageInt(1); // Morph-Sacrifice two Mountains. - this.addAbility(new MorphAbility(this, new SacrificeTargetCost(new TargetControlledPermanent(2, filter)))); + this.addAbility(new MorphAbility(this, new SacrificeTargetCost(2, filter))); // When Skirk Volcanist is turned face up, it deals 3 damage divided as you choose among one, two, or three target creatures. Ability ability = new TurnedFaceUpSourceTriggeredAbility(new DamageMultiEffect(3, "it")); diff --git a/Mage.Sets/src/mage/cards/s/SkirsdagFlayer.java b/Mage.Sets/src/mage/cards/s/SkirsdagFlayer.java index 1ea4d5e62b8..599c7b5bb76 100644 --- a/Mage.Sets/src/mage/cards/s/SkirsdagFlayer.java +++ b/Mage.Sets/src/mage/cards/s/SkirsdagFlayer.java @@ -41,7 +41,7 @@ public final class SkirsdagFlayer extends CardImpl { // {3}{B}, {tap}, Sacrifice a Human: Destroy target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl<>("{3}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SkizzikSurger.java b/Mage.Sets/src/mage/cards/s/SkizzikSurger.java index 32c666976f8..97e864caea8 100644 --- a/Mage.Sets/src/mage/cards/s/SkizzikSurger.java +++ b/Mage.Sets/src/mage/cards/s/SkizzikSurger.java @@ -10,6 +10,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -28,7 +29,7 @@ public final class SkizzikSurger extends CardImpl { // Haste this.addAbility(HasteAbility.getInstance()); // Echo-Sacrifice two lands. - this.addAbility(new EchoAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true)))); + this.addAbility(new EchoAbility(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS))); } private SkizzikSurger(final SkizzikSurger card) { diff --git a/Mage.Sets/src/mage/cards/s/SkophosWarleader.java b/Mage.Sets/src/mage/cards/s/SkophosWarleader.java index 0325d9ef2ad..dd5b7e13b7f 100644 --- a/Mage.Sets/src/mage/cards/s/SkophosWarleader.java +++ b/Mage.Sets/src/mage/cards/s/SkophosWarleader.java @@ -50,7 +50,7 @@ public final class SkophosWarleader extends CardImpl { new BoostSourceEffect(1, 0, Duration.EndOfTurn) .setText("{this} gets +1/+0"), new ColoredManaCost(ColoredManaSymbol.R)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn) .setText("and gains menace until end of turn. " + "(It can't be blocked except by two or more creatures.)")); diff --git a/Mage.Sets/src/mage/cards/s/SkullportMerchant.java b/Mage.Sets/src/mage/cards/s/SkullportMerchant.java index 0dcd5c53052..c8a41ffd7ff 100644 --- a/Mage.Sets/src/mage/cards/s/SkullportMerchant.java +++ b/Mage.Sets/src/mage/cards/s/SkullportMerchant.java @@ -46,7 +46,7 @@ public final class SkullportMerchant extends CardImpl { // {1}{B}, Sacrifice another creature or a Treasure: Draw a card. Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/Skulltap.java b/Mage.Sets/src/mage/cards/s/Skulltap.java index 3b17e3a5ce1..cc9f90a7f5e 100644 --- a/Mage.Sets/src/mage/cards/s/Skulltap.java +++ b/Mage.Sets/src/mage/cards/s/Skulltap.java @@ -20,7 +20,7 @@ public final class Skulltap extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}"); // As an additional cost to cast Skulltap, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, true))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Draw two cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); } diff --git a/Mage.Sets/src/mage/cards/s/SkyclaveShadowcat.java b/Mage.Sets/src/mage/cards/s/SkyclaveShadowcat.java index a0063e15fad..5d6afd40bd1 100644 --- a/Mage.Sets/src/mage/cards/s/SkyclaveShadowcat.java +++ b/Mage.Sets/src/mage/cards/s/SkyclaveShadowcat.java @@ -35,9 +35,7 @@ public final class SkyclaveShadowcat extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new ManaCostsImpl<>("{1}{B}") ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); // Whenever a creature you control with a +1/+1 counter on it dies, draw a card. diff --git a/Mage.Sets/src/mage/cards/s/SlagStrider.java b/Mage.Sets/src/mage/cards/s/SlagStrider.java index 015eff9257e..047939ea95d 100644 --- a/Mage.Sets/src/mage/cards/s/SlagStrider.java +++ b/Mage.Sets/src/mage/cards/s/SlagStrider.java @@ -34,9 +34,7 @@ public final class SlagStrider extends CardImpl { // {1}, Sacrifice an artifact: Slag Strider deals 1 damage to any target. Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SlaughterPriestOfMogis.java b/Mage.Sets/src/mage/cards/s/SlaughterPriestOfMogis.java index c6834e23dc0..3c3591cb8ff 100644 --- a/Mage.Sets/src/mage/cards/s/SlaughterPriestOfMogis.java +++ b/Mage.Sets/src/mage/cards/s/SlaughterPriestOfMogis.java @@ -55,7 +55,7 @@ public final class SlaughterPriestOfMogis extends CardImpl { Ability ability = new SimpleActivatedAbility( new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SlingGangLieutenant.java b/Mage.Sets/src/mage/cards/s/SlingGangLieutenant.java index 65fc28f5b53..d3ee968420c 100644 --- a/Mage.Sets/src/mage/cards/s/SlingGangLieutenant.java +++ b/Mage.Sets/src/mage/cards/s/SlingGangLieutenant.java @@ -43,7 +43,7 @@ public final class SlingGangLieutenant extends CardImpl { // Sacrifice a Goblin: Target player loses 1 life and you gain 1 life. Ability ability = new SimpleActivatedAbility( new LoseLifeTargetEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) ); ability.addEffect(new GainLifeEffect(1).concatBy("and")); ability.addTarget(new TargetPlayer()); diff --git a/Mage.Sets/src/mage/cards/s/SlobadGoblinTinkerer.java b/Mage.Sets/src/mage/cards/s/SlobadGoblinTinkerer.java index 5cf9d60566f..6400efb679c 100644 --- a/Mage.Sets/src/mage/cards/s/SlobadGoblinTinkerer.java +++ b/Mage.Sets/src/mage/cards/s/SlobadGoblinTinkerer.java @@ -44,7 +44,7 @@ public final class SlobadGoblinTinkerer extends CardImpl { // Sacrifice an artifact: Target artifact is indestructible this turn. Ability ability = new SimpleActivatedAbility( new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(filterControlled)) + new SacrificeTargetCost(filterControlled) ); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/Smokestack.java b/Mage.Sets/src/mage/cards/s/Smokestack.java index 0b5f20721bf..c2649f018d5 100644 --- a/Mage.Sets/src/mage/cards/s/Smokestack.java +++ b/Mage.Sets/src/mage/cards/s/Smokestack.java @@ -12,12 +12,14 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.counters.CounterType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -68,8 +70,8 @@ class SmokestackEffect extends OneShotEffect { if (activePlayer != null && sourcePermanent != null) { int count = sourcePermanent.getCounters(game).getCount(CounterType.SOOT); if (count > 0) { - int amount = Math.min(count, game.getBattlefield().countAll(new FilterControlledPermanent(), activePlayer.getId(), game)); - Target target = new TargetControlledPermanent(amount, amount, new FilterControlledPermanent(), true); + int amount = Math.min(count, game.getBattlefield().countAll(StaticFilters.FILTER_PERMANENT, activePlayer.getId(), game)); + TargetSacrifice target = new TargetSacrifice(amount, StaticFilters.FILTER_PERMANENT); //A spell or ability could have removed the only legal target this player //had, if thats the case this ability should fizzle. if (target.canChoose(activePlayer.getId(), source, game)) { diff --git a/Mage.Sets/src/mage/cards/s/SokenzanSmelter.java b/Mage.Sets/src/mage/cards/s/SokenzanSmelter.java index 12747f795fa..33339b1e092 100644 --- a/Mage.Sets/src/mage/cards/s/SokenzanSmelter.java +++ b/Mage.Sets/src/mage/cards/s/SokenzanSmelter.java @@ -36,9 +36,7 @@ public final class SokenzanSmelter extends CardImpl { new CreateTokenEffect(new ConstructRedToken()), new CompositeCost( new GenericManaCost(1), - new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN - )), "pay {1} and sacrifice an artifact" + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN), "pay {1} and sacrifice an artifact" ) ), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/s/SolarTide.java b/Mage.Sets/src/mage/cards/s/SolarTide.java index 28bc9f08cbe..7185455d12a 100644 --- a/Mage.Sets/src/mage/cards/s/SolarTide.java +++ b/Mage.Sets/src/mage/cards/s/SolarTide.java @@ -10,6 +10,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ComparisonType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; @@ -40,7 +41,7 @@ public final class SolarTide extends CardImpl { this.getSpellAbility().getModes().addMode(mode); // Entwine-Sacrifice two lands. - this.addAbility(new EntwineAbility(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true)))); + this.addAbility(new EntwineAbility(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS))); } private SolarTide(final SolarTide card) { diff --git a/Mage.Sets/src/mage/cards/s/SoldeviAdnate.java b/Mage.Sets/src/mage/cards/s/SoldeviAdnate.java index f521f14b71a..02213349755 100644 --- a/Mage.Sets/src/mage/cards/s/SoldeviAdnate.java +++ b/Mage.Sets/src/mage/cards/s/SoldeviAdnate.java @@ -43,7 +43,7 @@ public final class SoldeviAdnate extends CardImpl { Ability ability = new DynamicManaAbility(Mana.BlackMana(1), SacrificeCostManaValue.CREATURE, new TapSourceCost(), "add an amount of {B} equal to the sacrificed creature's mana value", false, new HighestCMCOfPermanentValue(filter, true)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SoldeviExcavations.java b/Mage.Sets/src/mage/cards/s/SoldeviExcavations.java index 7e297f38243..ee00953d068 100644 --- a/Mage.Sets/src/mage/cards/s/SoldeviExcavations.java +++ b/Mage.Sets/src/mage/cards/s/SoldeviExcavations.java @@ -38,7 +38,7 @@ public final class SoldeviExcavations extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.LAND},""); // If Soldevi Excavations would enter the battlefield, sacrifice an untapped Island instead. If you do, put Soldevi Excavations onto the battlefield. If you don't, put it into its owner's graveyard. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new EnterBattlefieldPayCostOrPutGraveyardEffect(new SacrificeTargetCost(filter)))); // {tap}: Add {C}{U}. this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new Mana(0, 1, 0, 0, 0, 0, 0, 1), new TapSourceCost())); diff --git a/Mage.Sets/src/mage/cards/s/SoldeviSage.java b/Mage.Sets/src/mage/cards/s/SoldeviSage.java index 3bc135cb34c..da91d3f2402 100644 --- a/Mage.Sets/src/mage/cards/s/SoldeviSage.java +++ b/Mage.Sets/src/mage/cards/s/SoldeviSage.java @@ -13,6 +13,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -32,7 +33,7 @@ public final class SoldeviSage extends CardImpl { // {T}, Sacrifice two lands: Draw three cards, then discard one of them. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawDiscardOneOfThemEffect(3), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS)); this.addAbility(ability); } @@ -44,4 +45,4 @@ public final class SoldeviSage extends CardImpl { public SoldeviSage copy() { return new SoldeviSage(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SorinImperiousBloodlord.java b/Mage.Sets/src/mage/cards/s/SorinImperiousBloodlord.java index 476f5ef2235..1612f8de53c 100644 --- a/Mage.Sets/src/mage/cards/s/SorinImperiousBloodlord.java +++ b/Mage.Sets/src/mage/cards/s/SorinImperiousBloodlord.java @@ -62,7 +62,7 @@ public final class SorinImperiousBloodlord extends CardImpl { triggeredAbility.addTarget(new TargetAnyTarget()); this.addAbility(new LoyaltyAbility(new DoWhenCostPaid( triggeredAbility, - new SacrificeTargetCost(new TargetControlledPermanent(filter)), + new SacrificeTargetCost(filter), "Sacrifice a Vampire?" ), 1)); diff --git a/Mage.Sets/src/mage/cards/s/SoulreaperOfMogis.java b/Mage.Sets/src/mage/cards/s/SoulreaperOfMogis.java index 16e674c60af..4905830416f 100644 --- a/Mage.Sets/src/mage/cards/s/SoulreaperOfMogis.java +++ b/Mage.Sets/src/mage/cards/s/SoulreaperOfMogis.java @@ -32,9 +32,7 @@ public final class SoulreaperOfMogis extends CardImpl { Ability ability = new SimpleActivatedAbility( new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{2}{B}") ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SoulsOfTheLost.java b/Mage.Sets/src/mage/cards/s/SoulsOfTheLost.java index 9d910043916..d685d5fd648 100644 --- a/Mage.Sets/src/mage/cards/s/SoulsOfTheLost.java +++ b/Mage.Sets/src/mage/cards/s/SoulsOfTheLost.java @@ -37,7 +37,7 @@ public final class SoulsOfTheLost extends CardImpl { // As an additional cost to cast this spell, discard a card or sacrifice a permanent. this.getSpellAbility().addCost(new OrCost("discard a card or sacrifice a permanent", new DiscardCardCost(), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT) )); // Fathomless descent -- Souls of the Lost's power is equal to the number of permanent cards in your graveyard and its toughness is equal to that number plus 1. diff --git a/Mage.Sets/src/mage/cards/s/SparkHarvest.java b/Mage.Sets/src/mage/cards/s/SparkHarvest.java index 4466c10ae66..94eb2fb6595 100644 --- a/Mage.Sets/src/mage/cards/s/SparkHarvest.java +++ b/Mage.Sets/src/mage/cards/s/SparkHarvest.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreatureOrPlaneswalker; @@ -22,7 +23,7 @@ public final class SparkHarvest extends CardImpl { // As an additional cost to cast this spell, sacrifice a creature or pay {3}{B}. this.getSpellAbility().addCost(new OrCost( - "sacrifice a creature or pay {3}{B}", new SacrificeTargetCost(new TargetControlledCreaturePermanent()), + "sacrifice a creature or pay {3}{B}", new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE), new ManaCostsImpl<>("{3}{B}") )); diff --git a/Mage.Sets/src/mage/cards/s/SparkReaper.java b/Mage.Sets/src/mage/cards/s/SparkReaper.java index 1a6ad093f03..695e56dd1ad 100644 --- a/Mage.Sets/src/mage/cards/s/SparkReaper.java +++ b/Mage.Sets/src/mage/cards/s/SparkReaper.java @@ -42,7 +42,7 @@ public final class SparkReaper extends CardImpl { // {3}, Sacrifice a creature or planeswalker: You gain 1 life and draw a card. Ability ability = new SimpleActivatedAbility(new GainLifeEffect(1), new GenericManaCost(3)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SphinxsHerald.java b/Mage.Sets/src/mage/cards/s/SphinxsHerald.java index 1518737ec19..77908328c60 100644 --- a/Mage.Sets/src/mage/cards/s/SphinxsHerald.java +++ b/Mage.Sets/src/mage/cards/s/SphinxsHerald.java @@ -14,7 +14,7 @@ import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.NamePredicate; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetControlledCreatureEachColor; +import mage.target.common.TargetSacrificeCreatureEachColor; import java.util.UUID; @@ -43,7 +43,7 @@ public final class SphinxsHerald extends CardImpl { new TargetCardInLibrary(filter)), new ManaCostsImpl<>("{2}{U}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreatureEachColor("WUB"))); + ability.addCost(new SacrificeTargetCost(new TargetSacrificeCreatureEachColor("WUB"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SpiritBonds.java b/Mage.Sets/src/mage/cards/s/SpiritBonds.java index 98a17673e2d..ff1565d4d23 100644 --- a/Mage.Sets/src/mage/cards/s/SpiritBonds.java +++ b/Mage.Sets/src/mage/cards/s/SpiritBonds.java @@ -48,7 +48,7 @@ public final class SpiritBonds extends CardImpl { // {1}{W}, Sacrifice a Spirit: Target non-Spirit creature gains indestructible until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl<>("{1}{W}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filterSpirit, true))); + ability.addCost(new SacrificeTargetCost(filterSpirit)); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SpittingSpider.java b/Mage.Sets/src/mage/cards/s/SpittingSpider.java index 3ef6383007f..b15961d03a2 100644 --- a/Mage.Sets/src/mage/cards/s/SpittingSpider.java +++ b/Mage.Sets/src/mage/cards/s/SpittingSpider.java @@ -38,7 +38,7 @@ public final class SpittingSpider extends CardImpl { // Reach this.addAbility(ReachAbility.getInstance()); // Sacrifice a land: Spitting Spider deals 1 damage to each creature with flying. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filter), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageAllEffect(1, filter), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); } private SpittingSpider(final SpittingSpider card) { diff --git a/Mage.Sets/src/mage/cards/s/SquanderedResources.java b/Mage.Sets/src/mage/cards/s/SquanderedResources.java index 6b943c3f885..e5f1883bb34 100644 --- a/Mage.Sets/src/mage/cards/s/SquanderedResources.java +++ b/Mage.Sets/src/mage/cards/s/SquanderedResources.java @@ -36,7 +36,7 @@ public final class SquanderedResources extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}{G}"); // Sacrifice a land: Add one mana of any type the sacrificed land could produce. - this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new SquanderedResourcesEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new SquanderedResourcesEffect(), new SacrificeTargetCost(filter))); } private SquanderedResources(final SquanderedResources card) { diff --git a/Mage.Sets/src/mage/cards/s/SquirrelWrangler.java b/Mage.Sets/src/mage/cards/s/SquirrelWrangler.java index 97fe961411f..552ff358e78 100644 --- a/Mage.Sets/src/mage/cards/s/SquirrelWrangler.java +++ b/Mage.Sets/src/mage/cards/s/SquirrelWrangler.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.game.permanent.token.SquirrelToken; @@ -37,12 +38,12 @@ public final class SquirrelWrangler extends CardImpl { // {1}{G}, Sacrifice a land: Create two 1/1 green Squirrel creature tokens. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SquirrelToken(), 2), new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(ability); // {1}{G}, Sacrifice a land: Squirrel creatures get +1/+1 until end of turn. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), new ManaCostsImpl<>("{1}{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StarlitSanctum.java b/Mage.Sets/src/mage/cards/s/StarlitSanctum.java index 2c5d29eb981..c9555d2188f 100644 --- a/Mage.Sets/src/mage/cards/s/StarlitSanctum.java +++ b/Mage.Sets/src/mage/cards/s/StarlitSanctum.java @@ -37,13 +37,13 @@ public final class StarlitSanctum extends CardImpl { // {W}, {T}, Sacrifice a Cleric creature: You gain life equal to the sacrificed creature's toughness. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StarlitSanctumWhiteEffect(), new ManaCostsImpl<>("{W}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); // {B}, {T}, Sacrifice a Cleric creature: Target player loses life equal to the sacrificed creature's power. ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StarlitSanctumBlackEffect(), new ManaCostsImpl<>("{B}")); ability.addTarget(new TargetPlayer()); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StormwatchEagle.java b/Mage.Sets/src/mage/cards/s/StormwatchEagle.java index 3f5bcb14024..a744cef048c 100644 --- a/Mage.Sets/src/mage/cards/s/StormwatchEagle.java +++ b/Mage.Sets/src/mage/cards/s/StormwatchEagle.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,7 +34,7 @@ public final class StormwatchEagle extends CardImpl { // Sacrifice a land: Return Stormwatch Eagle to its owner's hand. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND))); } private StormwatchEagle(final StormwatchEagle card) { diff --git a/Mage.Sets/src/mage/cards/s/StrandsOfNight.java b/Mage.Sets/src/mage/cards/s/StrandsOfNight.java index f507cf8325a..25614ec56c7 100644 --- a/Mage.Sets/src/mage/cards/s/StrandsOfNight.java +++ b/Mage.Sets/src/mage/cards/s/StrandsOfNight.java @@ -36,7 +36,7 @@ public final class StrandsOfNight extends CardImpl { // {B}{B}, Pay 2 life, Sacrifice a Swamp: Return target creature card from your graveyard to the battlefield. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{B}{B}")); ability.addCost(new PayLifeCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StrefanMaurerProgenitor.java b/Mage.Sets/src/mage/cards/s/StrefanMaurerProgenitor.java index 9c2c08faf3d..2d46b449fdb 100644 --- a/Mage.Sets/src/mage/cards/s/StrefanMaurerProgenitor.java +++ b/Mage.Sets/src/mage/cards/s/StrefanMaurerProgenitor.java @@ -78,14 +78,8 @@ public class StrefanMaurerProgenitor extends CardImpl { this.addAbility(new AttacksTriggeredAbility( new DoIfCostPaid( new StrefanMaurerProgenitorPlayVampireEffect(), - new SacrificeTargetCost(new TargetControlledPermanent( - 2, - 2, - bloodTokenFilter, - true) - )), - false - ) + new SacrificeTargetCost(2, bloodTokenFilter) + ), false) ); } diff --git a/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java b/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java index d4eb12a3916..813b550c63a 100644 --- a/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java +++ b/Mage.Sets/src/mage/cards/s/StrongholdAssassin.java @@ -34,7 +34,7 @@ public final class StrongholdAssassin extends CardImpl { // {tap}, Sacrifice a creature: Destroy target nonblack creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); Target target = new TargetCreaturePermanent(StaticFilters.FILTER_PERMANENT_CREATURE_NON_BLACK); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/s/Sunstone.java b/Mage.Sets/src/mage/cards/s/Sunstone.java index 0f526ac5684..f6454431ee5 100644 --- a/Mage.Sets/src/mage/cards/s/Sunstone.java +++ b/Mage.Sets/src/mage/cards/s/Sunstone.java @@ -36,7 +36,7 @@ public final class Sunstone extends CardImpl { Effect effect = new PreventAllDamageByAllPermanentsEffect(Duration.EndOfTurn, true); effect.setText("Prevent all combat damage that would be dealt this turn"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/Sustenance.java b/Mage.Sets/src/mage/cards/s/Sustenance.java index 2cbe843c8e7..19b9b3fb427 100644 --- a/Mage.Sets/src/mage/cards/s/Sustenance.java +++ b/Mage.Sets/src/mage/cards/s/Sustenance.java @@ -12,6 +12,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; @@ -27,7 +28,7 @@ public final class Sustenance extends CardImpl { // {1}, Sacrifice a land: Target creature gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl<>("{1}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land")))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SwordOfTheAges.java b/Mage.Sets/src/mage/cards/s/SwordOfTheAges.java index 59702e2fca8..8e42b7456d9 100644 --- a/Mage.Sets/src/mage/cards/s/SwordOfTheAges.java +++ b/Mage.Sets/src/mage/cards/s/SwordOfTheAges.java @@ -14,12 +14,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.HashSet; import java.util.Set; @@ -39,7 +41,7 @@ public final class SwordOfTheAges extends CardImpl { // {T}, Sacrifice Sword of the Ages and any number of creatures you control: Sword of the Ages deals X damage to any target, where X is the total power of the creatures sacrificed this way, then exile Sword of the Ages and those creature cards. Cost cost = new SacrificeSourceCost(); cost.setText("Sacrifice {this} and any number of creatures you control"); - Cost cost2 = new SacrificeTargetCost(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, new FilterControlledCreaturePermanent(), true)); + Cost cost2 = new SacrificeTargetCost(new TargetSacrifice(0, Integer.MAX_VALUE, StaticFilters.FILTER_PERMANENT_CREATURES)); cost2.setText(""); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SwordOfTheAgesEffect(), new TapSourceCost()); ability.addCost(cost); diff --git a/Mage.Sets/src/mage/cards/s/SylvanSafekeeper.java b/Mage.Sets/src/mage/cards/s/SylvanSafekeeper.java index adbcd77a4a2..d812973f995 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanSafekeeper.java +++ b/Mage.Sets/src/mage/cards/s/SylvanSafekeeper.java @@ -14,6 +14,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledPermanent; @@ -35,7 +36,7 @@ public final class SylvanSafekeeper extends CardImpl { // Sacrifice a land: Target creature you control gains shroud until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SyndicateTrafficker.java b/Mage.Sets/src/mage/cards/s/SyndicateTrafficker.java index d83a217ea9e..365baed6ce6 100644 --- a/Mage.Sets/src/mage/cards/s/SyndicateTrafficker.java +++ b/Mage.Sets/src/mage/cards/s/SyndicateTrafficker.java @@ -35,7 +35,7 @@ public final class SyndicateTrafficker extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); ability.addEffect(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn ).setText("It gains indestructible until end of turn")); diff --git a/Mage.Sets/src/mage/cards/s/SyphonFlesh.java b/Mage.Sets/src/mage/cards/s/SyphonFlesh.java index c45b458966f..634aea9bc64 100644 --- a/Mage.Sets/src/mage/cards/s/SyphonFlesh.java +++ b/Mage.Sets/src/mage/cards/s/SyphonFlesh.java @@ -10,11 +10,13 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -63,10 +65,9 @@ class SyphonFleshEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null && !playerId.equals(source.getControllerId())) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } @@ -87,4 +88,4 @@ class SyphonFleshEffect extends OneShotEffect { } return false; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TamiyosJournal.java b/Mage.Sets/src/mage/cards/t/TamiyosJournal.java index 6a36d15458b..0a14bb74bb5 100644 --- a/Mage.Sets/src/mage/cards/t/TamiyosJournal.java +++ b/Mage.Sets/src/mage/cards/t/TamiyosJournal.java @@ -37,7 +37,7 @@ public final class TamiyosJournal extends CardImpl { // {T}, Sacrifice three Clues: Search your library for a card and put that card into your hand. Then shuffle your library. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(), false, true), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, false))); + ability.addCost(new SacrificeTargetCost(3, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TarPitcher.java b/Mage.Sets/src/mage/cards/t/TarPitcher.java index 12c977184d7..d48bf240c71 100644 --- a/Mage.Sets/src/mage/cards/t/TarPitcher.java +++ b/Mage.Sets/src/mage/cards/t/TarPitcher.java @@ -38,7 +38,7 @@ public final class TarPitcher extends CardImpl { this.toughness = new MageInt(2); // {tap}, Sacrifice a Goblin: Tar Pitcher deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TavernScoundrel.java b/Mage.Sets/src/mage/cards/t/TavernScoundrel.java index 986956ba18d..cb37ed04daf 100644 --- a/Mage.Sets/src/mage/cards/t/TavernScoundrel.java +++ b/Mage.Sets/src/mage/cards/t/TavernScoundrel.java @@ -49,7 +49,7 @@ public final class TavernScoundrel extends CardImpl { // {1}, {T}, Sacrifice another permanent: Flip a coin. Ability ability = new SimpleActivatedAbility(new FlipCoinEffect(), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TawnosSolemnSurvivor.java b/Mage.Sets/src/mage/cards/t/TawnosSolemnSurvivor.java index 70e78176397..234c3807704 100644 --- a/Mage.Sets/src/mage/cards/t/TawnosSolemnSurvivor.java +++ b/Mage.Sets/src/mage/cards/t/TawnosSolemnSurvivor.java @@ -71,7 +71,7 @@ public final class TawnosSolemnSurvivor extends CardImpl { new TawnosSolemnSurvivorEffect(), new ManaCostsImpl<>("{1}{W}{U}{B}") ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter2))); + ability.addCost(new SacrificeTargetCost(2, filter2)); ability.addCost(new ExileFromGraveCost( new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_ARTIFACT_OR_CREATURE) )); diff --git a/Mage.Sets/src/mage/cards/t/TeferisCare.java b/Mage.Sets/src/mage/cards/t/TeferisCare.java index 4cf7414b443..1cd6a9ae295 100644 --- a/Mage.Sets/src/mage/cards/t/TeferisCare.java +++ b/Mage.Sets/src/mage/cards/t/TeferisCare.java @@ -38,7 +38,7 @@ public final class TeferisCare extends CardImpl { // {W}, Sacrifice an enchantment: Destroy target enchantment. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl<>("{W}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetEnchantmentPermanent()); this.addAbility(ability); // {3}{U}{U}: Counter target enchantment spell. diff --git a/Mage.Sets/src/mage/cards/t/TelJiladLifebreather.java b/Mage.Sets/src/mage/cards/t/TelJiladLifebreather.java index 5b96f77dcd1..f3b1689ffd2 100644 --- a/Mage.Sets/src/mage/cards/t/TelJiladLifebreather.java +++ b/Mage.Sets/src/mage/cards/t/TelJiladLifebreather.java @@ -40,7 +40,7 @@ public final class TelJiladLifebreather extends CardImpl { // {G}, {tap}, Sacrifice a Forest: Regenerate target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ManaCostsImpl<>("{G}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TemptingWitch.java b/Mage.Sets/src/mage/cards/t/TemptingWitch.java index a48d400cf81..4860185494d 100644 --- a/Mage.Sets/src/mage/cards/t/TemptingWitch.java +++ b/Mage.Sets/src/mage/cards/t/TemptingWitch.java @@ -41,7 +41,7 @@ public final class TemptingWitch extends CardImpl { new LoseLifeTargetEffect(3), new GenericManaCost(2) ); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD)); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TendThePests.java b/Mage.Sets/src/mage/cards/t/TendThePests.java index 266e96064d7..a1399c77b5d 100644 --- a/Mage.Sets/src/mage/cards/t/TendThePests.java +++ b/Mage.Sets/src/mage/cards/t/TendThePests.java @@ -21,9 +21,7 @@ public final class TendThePests extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{G}"); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Create X 1/1 black and green Pest creature tokens with "When this creature dies, you gain 1 life," where X is the sacrificed creature's power. this.getSpellAbility().addEffect(new CreateTokenEffect( diff --git a/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java b/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java index 53289404e1a..c184d21630d 100644 --- a/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java +++ b/Mage.Sets/src/mage/cards/t/TergridGodOfFright.java @@ -22,6 +22,7 @@ import mage.game.permanent.PermanentToken; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.TargetPlayer; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.HashSet; @@ -219,8 +220,7 @@ class TergridsLaternEffect extends OneShotEffect { } switch (chosen) { case SACRIFICE_CHOICE: - TargetPermanent target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND); targetedPlayer.choose(Outcome.Sacrifice, target, source, game); Permanent chosenLand = game.getPermanent(target.getFirstTarget()); return chosenLand != null && chosenLand.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/t/TerritorialDispute.java b/Mage.Sets/src/mage/cards/t/TerritorialDispute.java index 088859697c9..0cabc952808 100644 --- a/Mage.Sets/src/mage/cards/t/TerritorialDispute.java +++ b/Mage.Sets/src/mage/cards/t/TerritorialDispute.java @@ -15,6 +15,7 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -31,7 +32,7 @@ public final class TerritorialDispute extends CardImpl { // At the beginning of your upkeep, sacrifice Territorial Dispute unless you sacrifice a land. this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, - new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land")))), + new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(StaticFilters.FILTER_LAND)), TargetController.YOU, false)); @@ -75,4 +76,4 @@ class TerritorialDisputeEffect extends ContinuousRuleModifyingEffectImpl { return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TeysaOrzhovScion.java b/Mage.Sets/src/mage/cards/t/TeysaOrzhovScion.java index 26d8e6488a9..32e44b5bd5c 100644 --- a/Mage.Sets/src/mage/cards/t/TeysaOrzhovScion.java +++ b/Mage.Sets/src/mage/cards/t/TeysaOrzhovScion.java @@ -46,7 +46,7 @@ public final class TeysaOrzhovScion extends CardImpl { this.toughness = new MageInt(3); // Sacrifice three white creatures: Exile target creature. - Ability ability = new SimpleActivatedAbility(new ExileTargetEffect(), new SacrificeTargetCost(new TargetControlledCreaturePermanent(3, 3, filterWhite, true))); + Ability ability = new SimpleActivatedAbility(new ExileTargetEffect(), new SacrificeTargetCost(3, filterWhite)); ability.addTarget(new TargetCreaturePermanent().withChooseHint("to exile")); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/ThaliasGeistcaller.java b/Mage.Sets/src/mage/cards/t/ThaliasGeistcaller.java index bf9d33a6c50..ebb9fb4da6e 100644 --- a/Mage.Sets/src/mage/cards/t/ThaliasGeistcaller.java +++ b/Mage.Sets/src/mage/cards/t/ThaliasGeistcaller.java @@ -47,7 +47,7 @@ public final class ThaliasGeistcaller extends CardImpl { // Sacrifice a Spirit: Thalia's Geistcaller gains indestructible until end of turn. this.addAbility(new SimpleActivatedAbility(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn - ), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + ), new SacrificeTargetCost(filter))); } private ThaliasGeistcaller(final ThaliasGeistcaller card) { diff --git a/Mage.Sets/src/mage/cards/t/ThallidDevourer.java b/Mage.Sets/src/mage/cards/t/ThallidDevourer.java index fabf37dc208..0f727aa27b4 100644 --- a/Mage.Sets/src/mage/cards/t/ThallidDevourer.java +++ b/Mage.Sets/src/mage/cards/t/ThallidDevourer.java @@ -44,7 +44,7 @@ public final class ThallidDevourer extends CardImpl { // Sacrifice a Saproling: Thallid Devourer gets +1/+2 until end of turn. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 2, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, false)))); + new SacrificeTargetCost(filter))); } private ThallidDevourer(final ThallidDevourer card) { diff --git a/Mage.Sets/src/mage/cards/t/ThallidGerminator.java b/Mage.Sets/src/mage/cards/t/ThallidGerminator.java index 430dd3400fd..6e19f3d1a5f 100644 --- a/Mage.Sets/src/mage/cards/t/ThallidGerminator.java +++ b/Mage.Sets/src/mage/cards/t/ThallidGerminator.java @@ -45,7 +45,7 @@ public final class ThallidGerminator extends CardImpl { // Sacrifice a Saproling: Target creature gets +1/+1 until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, false))); + new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/ThallidOmnivore.java b/Mage.Sets/src/mage/cards/t/ThallidOmnivore.java index 04f0f988d36..0520cb3df57 100644 --- a/Mage.Sets/src/mage/cards/t/ThallidOmnivore.java +++ b/Mage.Sets/src/mage/cards/t/ThallidOmnivore.java @@ -41,7 +41,7 @@ public final class ThallidOmnivore extends CardImpl { // {1}, Sacrifice another creature: Thallid Omnivore gets +2/+2 until end of turn. If a saproling was sacrificed in this way you gain 2 life. Effect effect = new BoostSourceEffect(2, 2, Duration.EndOfTurn); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addEffect(new ThallidOmnivoreEffect()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/t/Thaumatog.java b/Mage.Sets/src/mage/cards/t/Thaumatog.java index c7d69d80948..f86ae95db5a 100644 --- a/Mage.Sets/src/mage/cards/t/Thaumatog.java +++ b/Mage.Sets/src/mage/cards/t/Thaumatog.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -33,12 +34,12 @@ public final class Thaumatog extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land"))))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND))); // Sacrifice an enchantment: Thaumatog gets +1/+1 until end of turn. this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(1,1, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledEnchantmentPermanent("enchantment"))))); + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ENCHANTMENT))); } private Thaumatog(final Thaumatog card) { diff --git a/Mage.Sets/src/mage/cards/t/TheBookOfVileDarkness.java b/Mage.Sets/src/mage/cards/t/TheBookOfVileDarkness.java index 16646ce8684..6305bdda7fc 100644 --- a/Mage.Sets/src/mage/cards/t/TheBookOfVileDarkness.java +++ b/Mage.Sets/src/mage/cards/t/TheBookOfVileDarkness.java @@ -26,6 +26,7 @@ import mage.game.permanent.token.VecnaToken; import mage.game.permanent.token.ZombieToken; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.watchers.common.PlayerLostLifeWatcher; import java.util.Arrays; @@ -144,8 +145,7 @@ class TheBookOfVileDarknessCost extends CostImpl { default: break; } - TargetPermanent target = new TargetPermanent(filter); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(filter); controller.choose(Outcome.Sacrifice, target, source, game); return game.getPermanent(target.getFirstTarget()); } diff --git a/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java b/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java index 0add64c9982..0efea166e64 100644 --- a/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java +++ b/Mage.Sets/src/mage/cards/t/TheDalekEmperor.java @@ -24,6 +24,7 @@ import mage.game.permanent.token.DalekToken; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -111,8 +112,7 @@ class TheDalekEmperorFirstChoice extends VillainousChoice { )) { return false; } - TargetPermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); return permanent != null && permanent.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/t/TheFirstEruption.java b/Mage.Sets/src/mage/cards/t/TheFirstEruption.java index 40ec0dbf407..789a9be3b63 100644 --- a/Mage.Sets/src/mage/cards/t/TheFirstEruption.java +++ b/Mage.Sets/src/mage/cards/t/TheFirstEruption.java @@ -25,6 +25,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -97,11 +98,11 @@ class TheFirstEruptionEffect extends OneShotEffect { return false; } - Target target = new TargetControlledPermanent(1, 1, filter, false); + Target target = new TargetSacrifice(filter); boolean sacrificed = false; if (target.canChoose(controller.getId(), source, game)) { while (controller.canRespond() && !target.isChosen() && target.canChoose(controller.getId(), source, game)) { - controller.chooseTarget(Outcome.Sacrifice, target, source, game); + controller.choose(Outcome.Sacrifice, target, source, game); } for (int idx = 0; idx < target.getTargets().size(); idx++) { diff --git a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java index 9be68a77a2a..e84c2af039c 100644 --- a/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java +++ b/Mage.Sets/src/mage/cards/t/TheGitrogMonster.java @@ -14,6 +14,7 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -38,7 +39,7 @@ public final class TheGitrogMonster extends CardImpl { this.addAbility(DeathtouchAbility.getInstance()); // At the beginning of your upkeep, sacrifice The Gitrog Monster unless you sacrifice a land. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect( - new SacrificeTargetCost(new TargetControlledPermanent(1, 1, new FilterControlledLandPermanent("a land"), true))), TargetController.YOU, false)); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)), TargetController.YOU, false)); // You may play an additional land on each of your turns. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayAdditionalLandsControllerEffect(1, Duration.WhileOnBattlefield))); diff --git a/Mage.Sets/src/mage/cards/t/TheloniteMonk.java b/Mage.Sets/src/mage/cards/t/TheloniteMonk.java index b3fbb9c545e..bd5cd2bb8ea 100644 --- a/Mage.Sets/src/mage/cards/t/TheloniteMonk.java +++ b/Mage.Sets/src/mage/cards/t/TheloniteMonk.java @@ -43,7 +43,7 @@ public final class TheloniteMonk extends CardImpl { // {tap}, Sacrifice a green creature: Target land becomes a Forest. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesBasicLandTargetEffect(Duration.WhileOnBattlefield, SubType.FOREST), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetLandPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/ThermalNavigator.java b/Mage.Sets/src/mage/cards/t/ThermalNavigator.java index 6260e3c1410..5bceb752496 100644 --- a/Mage.Sets/src/mage/cards/t/ThermalNavigator.java +++ b/Mage.Sets/src/mage/cards/t/ThermalNavigator.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetControlledPermanent; @@ -30,7 +31,7 @@ public final class ThermalNavigator extends CardImpl { this.toughness = new MageInt(2); // Sacrifice an artifact: Thermal Navigator gains flying until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact"))))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT))); } private ThermalNavigator(final ThermalNavigator card) { diff --git a/Mage.Sets/src/mage/cards/t/ThingFromTheDeep.java b/Mage.Sets/src/mage/cards/t/ThingFromTheDeep.java index 86dc9161d5f..96b9828bf0f 100644 --- a/Mage.Sets/src/mage/cards/t/ThingFromTheDeep.java +++ b/Mage.Sets/src/mage/cards/t/ThingFromTheDeep.java @@ -33,7 +33,7 @@ public final class ThingFromTheDeep extends CardImpl { this.toughness = new MageInt(9); // Whenever Thing from the Deep attacks, sacrifice it unless you sacrifice an Island. - Effect effect = new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + Effect effect = new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)); effect.setText("sacrifice it unless you sacrifice an Island"); this.addAbility(new AttacksTriggeredAbility(effect, false)); } diff --git a/Mage.Sets/src/mage/cards/t/ThopterFoundry.java b/Mage.Sets/src/mage/cards/t/ThopterFoundry.java index f17ac4ae2a6..faad63ac16a 100644 --- a/Mage.Sets/src/mage/cards/t/ThopterFoundry.java +++ b/Mage.Sets/src/mage/cards/t/ThopterFoundry.java @@ -36,7 +36,7 @@ public final class ThopterFoundry extends CardImpl { // {1}, Sacrifice a nontoken artifact: Create a 1/1 blue Thopter artifact creature token with flying. You gain 1 life. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new ThopterToken()), new GenericManaCost(1)); ability.addEffect(new GainLifeEffect(1)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/ThopterSquadron.java b/Mage.Sets/src/mage/cards/t/ThopterSquadron.java index e1e5f97091d..1a5934274b9 100644 --- a/Mage.Sets/src/mage/cards/t/ThopterSquadron.java +++ b/Mage.Sets/src/mage/cards/t/ThopterSquadron.java @@ -55,7 +55,7 @@ public final class ThopterSquadron extends CardImpl { // {1}, Sacrifice another Thopter: Put a +1/+1 counter on Thopter Squadron. Activate this secondAbility only any time you could cast a sorcery. Ability secondAbility = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true), new ManaCostsImpl<>("{1}")); - secondAbility.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + secondAbility.addCost(new SacrificeTargetCost(filter)); this.addAbility(secondAbility); } diff --git a/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java b/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java index e67c173d284..4d9e74d896b 100644 --- a/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java +++ b/Mage.Sets/src/mage/cards/t/ThroneOfGeth.java @@ -31,7 +31,7 @@ public final class ThroneOfGeth extends CardImpl { // {T}, Sacrifice an artifact: Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.) Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ProliferateEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/Thunderclap.java b/Mage.Sets/src/mage/cards/t/Thunderclap.java index 52e979947b4..b5111deb19c 100644 --- a/Mage.Sets/src/mage/cards/t/Thunderclap.java +++ b/Mage.Sets/src/mage/cards/t/Thunderclap.java @@ -29,7 +29,7 @@ public final class Thunderclap extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}"); // You may sacrifice a Mountain rather than pay Thunderclap's mana cost. - this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new AlternativeCostSourceAbility(new SacrificeTargetCost(filter))); // Thunderclap deals 3 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(3)); diff --git a/Mage.Sets/src/mage/cards/t/TimeSieve.java b/Mage.Sets/src/mage/cards/t/TimeSieve.java index 13a1ca613e7..052c1f83154 100644 --- a/Mage.Sets/src/mage/cards/t/TimeSieve.java +++ b/Mage.Sets/src/mage/cards/t/TimeSieve.java @@ -28,7 +28,7 @@ public final class TimeSieve extends CardImpl { // {tap}, Sacrifice five artifacts: Take an extra turn after this one. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddExtraTurnControllerEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(5, filter))); + ability.addCost(new SacrificeTargetCost(5, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/Tinker.java b/Mage.Sets/src/mage/cards/t/Tinker.java index e823a93ac47..746403fbbe0 100644 --- a/Mage.Sets/src/mage/cards/t/Tinker.java +++ b/Mage.Sets/src/mage/cards/t/Tinker.java @@ -7,6 +7,7 @@ import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.filter.StaticFilters; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; import mage.target.common.TargetCardInLibrary; @@ -22,7 +23,7 @@ public final class Tinker extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // As an additional cost to cast Tinker, sacrifice an artifact. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_ARTIFACT)); // Search your library for an artifact card and put that card onto the battlefield. Then shuffle your library. this.getSpellAbility().addEffect(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(new FilterArtifactCard("an artifact card")), false, true)); diff --git a/Mage.Sets/src/mage/cards/t/TitanHunter.java b/Mage.Sets/src/mage/cards/t/TitanHunter.java index 7a5ea1105a7..9d8fe6bf68c 100644 --- a/Mage.Sets/src/mage/cards/t/TitanHunter.java +++ b/Mage.Sets/src/mage/cards/t/TitanHunter.java @@ -50,7 +50,7 @@ public final class TitanHunter extends CardImpl { // {1}{B}, Sacrifice a creature: You gain 4 life. Ability ability = new SimpleActivatedAbility(new GainLifeEffect(4), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } @@ -86,4 +86,4 @@ class TitanHunterEffect extends OneShotEffect { source, game, false, true ) > 0; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TombBlade.java b/Mage.Sets/src/mage/cards/t/TombBlade.java index 691077ae654..493e6bd0ca3 100644 --- a/Mage.Sets/src/mage/cards/t/TombBlade.java +++ b/Mage.Sets/src/mage/cards/t/TombBlade.java @@ -82,7 +82,7 @@ class TombBladeEffect extends OneShotEffect { StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game ); - Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent()); + Cost cost = new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE); if (cost.canPay(source, source, player.getId(), game) && player.chooseUse(outcome, "Sacrifice a creature?", "If you don't you lose " + creatureCount + " life", diff --git a/Mage.Sets/src/mage/cards/t/ToothAndClaw.java b/Mage.Sets/src/mage/cards/t/ToothAndClaw.java index 0907b63681c..c441f0418b4 100644 --- a/Mage.Sets/src/mage/cards/t/ToothAndClaw.java +++ b/Mage.Sets/src/mage/cards/t/ToothAndClaw.java @@ -9,6 +9,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.permanent.token.CarnivoreToken; import mage.target.common.TargetControlledCreaturePermanent; @@ -21,7 +22,9 @@ public final class ToothAndClaw extends CardImpl { public ToothAndClaw(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new CarnivoreToken(), 1), new SacrificeTargetCost(new TargetControlledCreaturePermanent(2)))); + // Sacrifice two creatures: Create a 3/1 red Beast creature token named Carnivore. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new CarnivoreToken(), 1), + new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_CREATURES))); } private ToothAndClaw(final ToothAndClaw card) { diff --git a/Mage.Sets/src/mage/cards/t/TormentedThoughts.java b/Mage.Sets/src/mage/cards/t/TormentedThoughts.java index dd12fdd3dcd..4801a748f14 100644 --- a/Mage.Sets/src/mage/cards/t/TormentedThoughts.java +++ b/Mage.Sets/src/mage/cards/t/TormentedThoughts.java @@ -26,9 +26,8 @@ public final class TormentedThoughts extends CardImpl { public TormentedThoughts(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); - // As an additional cost to cast Tormented Thoughts, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT, false))); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Target player discards a number of cards equal to the sacrificed creature's power. this.getSpellAbility().addEffect(new TormentedThoughtsDiscardEffect()); diff --git a/Mage.Sets/src/mage/cards/t/TorpidMoloch.java b/Mage.Sets/src/mage/cards/t/TorpidMoloch.java index fdd28b51717..731be19aea9 100644 --- a/Mage.Sets/src/mage/cards/t/TorpidMoloch.java +++ b/Mage.Sets/src/mage/cards/t/TorpidMoloch.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -35,7 +36,7 @@ public final class TorpidMoloch extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(3, 3, new FilterControlledLandPermanent("lands"), true)))); + new SacrificeTargetCost(3, StaticFilters.FILTER_LANDS))); } private TorpidMoloch(final TorpidMoloch card) { diff --git a/Mage.Sets/src/mage/cards/t/TorrentOfStone.java b/Mage.Sets/src/mage/cards/t/TorrentOfStone.java index 2cf4bc83226..61c10ce25a6 100644 --- a/Mage.Sets/src/mage/cards/t/TorrentOfStone.java +++ b/Mage.Sets/src/mage/cards/t/TorrentOfStone.java @@ -31,7 +31,7 @@ public final class TorrentOfStone extends CardImpl { this.getSpellAbility().addEffect(new DamageTargetEffect(4)); this.getSpellAbility().addTarget(new TargetCreaturePermanent().withChooseHint("4 damage")); // Splice onto Arcane-Sacrifice two Mountains. - this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new SacrificeTargetCost(new TargetControlledPermanent(2,2, filterSacrifice, false)))); + this.addAbility(new SpliceAbility(SpliceAbility.ARCANE, new SacrificeTargetCost(2, filterSacrifice))); } private TorrentOfStone(final TorrentOfStone card) { diff --git a/Mage.Sets/src/mage/cards/t/TourachsGate.java b/Mage.Sets/src/mage/cards/t/TourachsGate.java index dc44661bf34..1978b0f5519 100644 --- a/Mage.Sets/src/mage/cards/t/TourachsGate.java +++ b/Mage.Sets/src/mage/cards/t/TourachsGate.java @@ -76,7 +76,7 @@ public final class TourachsGate extends CardImpl { // Sacrifice a Thrull: Put three time counters on Tourach's Gate. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.TIME.createInstance(3)), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filterThrull, true)))); + new SacrificeTargetCost(filterThrull))); // At the beginning of your upkeep, remove a time counter from Tourach's Gate. If there are no time counters on Tourach's Gate, sacrifice it. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new TourachsGateUpkeepEffect(), TargetController.YOU, false)); diff --git a/Mage.Sets/src/mage/cards/t/ToweringTitan.java b/Mage.Sets/src/mage/cards/t/ToweringTitan.java index 4b1549af15d..d0f804d412f 100644 --- a/Mage.Sets/src/mage/cards/t/ToweringTitan.java +++ b/Mage.Sets/src/mage/cards/t/ToweringTitan.java @@ -58,7 +58,7 @@ public final class ToweringTitan extends CardImpl { TrampleAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE ).setText("All creatures gain trample until end of turn"), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) )); } @@ -97,4 +97,4 @@ enum ToweringTitanCount implements DynamicValue { public String getMessage() { return ""; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/ToxrillTheCorrosive.java b/Mage.Sets/src/mage/cards/t/ToxrillTheCorrosive.java index 013eb52147d..b0bd01b7580 100644 --- a/Mage.Sets/src/mage/cards/t/ToxrillTheCorrosive.java +++ b/Mage.Sets/src/mage/cards/t/ToxrillTheCorrosive.java @@ -68,7 +68,7 @@ public final class ToxrillTheCorrosive extends CardImpl { Ability ability = new SimpleActivatedAbility( new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{U}{B}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability.addCost(new SacrificeTargetCost(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TradingPost.java b/Mage.Sets/src/mage/cards/t/TradingPost.java index 61e395b49ac..b22cd4ae6fe 100644 --- a/Mage.Sets/src/mage/cards/t/TradingPost.java +++ b/Mage.Sets/src/mage/cards/t/TradingPost.java @@ -54,7 +54,7 @@ public final class TradingPost extends CardImpl { // {1}, {T}, Sacrifice an artifact: Draw a card. Ability ability4 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new GenericManaCost(1)); ability4.addCost(new TapSourceCost()); - ability4.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN))); + ability4.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN)); this.addAbility(ability4); } diff --git a/Mage.Sets/src/mage/cards/t/TransmuteArtifact.java b/Mage.Sets/src/mage/cards/t/TransmuteArtifact.java index 078911d4d6e..cc16a0071a3 100644 --- a/Mage.Sets/src/mage/cards/t/TransmuteArtifact.java +++ b/Mage.Sets/src/mage/cards/t/TransmuteArtifact.java @@ -9,6 +9,7 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; import mage.game.Game; @@ -16,6 +17,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.ManaUtil; import java.util.UUID; @@ -67,8 +69,8 @@ class TransmuteArtifactEffect extends SearchEffect { //Sacrifice an artifact. int manaValue = 0; boolean sacrifice = false; - TargetControlledPermanent targetArtifact = new TargetControlledPermanent(new FilterControlledArtifactPermanent()); - if (controller.chooseTarget(Outcome.Sacrifice, targetArtifact, source, game)) { + TargetSacrifice targetArtifact = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_ARTIFACT); + if (controller.choose(Outcome.Sacrifice, targetArtifact, source, game)) { Permanent permanent = game.getPermanent(targetArtifact.getFirstTarget()); if (permanent != null) { manaValue = permanent.getManaValue(); diff --git a/Mage.Sets/src/mage/cards/t/TrapDigger.java b/Mage.Sets/src/mage/cards/t/TrapDigger.java index 0d14144936f..d9c909ce0b6 100644 --- a/Mage.Sets/src/mage/cards/t/TrapDigger.java +++ b/Mage.Sets/src/mage/cards/t/TrapDigger.java @@ -51,7 +51,7 @@ public final class TrapDigger extends CardImpl { ability.addTarget(new TargetControlledPermanent(new FilterControlledLandPermanent())); this.addAbility(ability); // Sacrifice a land with a trap counter on it: Trap Digger deals 3 damage to target attacking creature without flying. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new SacrificeTargetCost(new TargetControlledPermanent(filter1))); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new SacrificeTargetCost(filter1)); ability.addTarget(new TargetPermanent(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TrashForTreasure.java b/Mage.Sets/src/mage/cards/t/TrashForTreasure.java index 6bb5e2119f9..5bf89a43049 100644 --- a/Mage.Sets/src/mage/cards/t/TrashForTreasure.java +++ b/Mage.Sets/src/mage/cards/t/TrashForTreasure.java @@ -29,7 +29,7 @@ public final class TrashForTreasure extends CardImpl { public TrashForTreasure(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(filterPermanent))); + this.getSpellAbility().addCost(new SacrificeTargetCost(filterPermanent)); this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect()); this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(filterCard)); } diff --git a/Mage.Sets/src/mage/cards/t/TreasureCove.java b/Mage.Sets/src/mage/cards/t/TreasureCove.java index 10d9ad28df3..1c0f5f6ff51 100644 --- a/Mage.Sets/src/mage/cards/t/TreasureCove.java +++ b/Mage.Sets/src/mage/cards/t/TreasureCove.java @@ -38,7 +38,7 @@ public final class TreasureCove extends CardImpl { // {T}, Sacrifice a Treasure: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TrenchingSteed.java b/Mage.Sets/src/mage/cards/t/TrenchingSteed.java index 0a3fa5a1e8b..e657f9c3162 100644 --- a/Mage.Sets/src/mage/cards/t/TrenchingSteed.java +++ b/Mage.Sets/src/mage/cards/t/TrenchingSteed.java @@ -12,6 +12,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; @@ -32,7 +33,7 @@ public final class TrenchingSteed extends CardImpl { this.addAbility(new SimpleActivatedAbility( Zone.BATTLEFIELD, new BoostSourceEffect(0, 3, Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land"))))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND))); } private TrenchingSteed(final TrenchingSteed card) { diff --git a/Mage.Sets/src/mage/cards/t/TributeToHunger.java b/Mage.Sets/src/mage/cards/t/TributeToHunger.java index b87b6235853..51bdb528490 100644 --- a/Mage.Sets/src/mage/cards/t/TributeToHunger.java +++ b/Mage.Sets/src/mage/cards/t/TributeToHunger.java @@ -8,12 +8,14 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetOpponent; +import mage.target.common.TargetSacrifice; /** * @@ -60,9 +62,9 @@ class TributeToHungerEffect extends OneShotEffect { Player opponent = game.getPlayer(source.getTargets().getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && opponent != null) { - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, new FilterControlledCreaturePermanent(), true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(opponent.getId(), source, game)) { - opponent.chooseTarget(Outcome.Sacrifice, target, source, game); + opponent.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { permanent.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/t/TroubledHealer.java b/Mage.Sets/src/mage/cards/t/TroubledHealer.java index a3aaae665bb..c33be544bed 100644 --- a/Mage.Sets/src/mage/cards/t/TroubledHealer.java +++ b/Mage.Sets/src/mage/cards/t/TroubledHealer.java @@ -13,6 +13,7 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetAnyTarget; @@ -34,7 +35,7 @@ public final class TroubledHealer extends CardImpl { Ability ability = new SimpleActivatedAbility( Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn, 2), - new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("land")))); + new SacrificeTargetCost(StaticFilters.FILTER_LAND)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TurntimberSower.java b/Mage.Sets/src/mage/cards/t/TurntimberSower.java index a2b42773217..3d5e040111e 100644 --- a/Mage.Sets/src/mage/cards/t/TurntimberSower.java +++ b/Mage.Sets/src/mage/cards/t/TurntimberSower.java @@ -48,7 +48,7 @@ public final class TurntimberSower extends CardImpl { Ability ability = new SimpleActivatedAbility( new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl<>("{G}") ); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(3, filter))); + ability.addCost(new SacrificeTargetCost(3, filter)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_LAND)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TwistedJustice.java b/Mage.Sets/src/mage/cards/t/TwistedJustice.java index 7472681d90e..2ba54b369e7 100644 --- a/Mage.Sets/src/mage/cards/t/TwistedJustice.java +++ b/Mage.Sets/src/mage/cards/t/TwistedJustice.java @@ -9,12 +9,14 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -56,10 +58,7 @@ class TwistedJusticeEffect extends OneShotEffect { Player player = game.getPlayer(source.getTargets().getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - FilterControlledPermanent filter = new FilterControlledPermanent("creature"); - filter.add(CardType.CREATURE.getPredicate()); - filter.add(TargetController.YOU.getControllerPredicate()); - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); //A spell or ability could have removed the only legal target this player //had, if thats the case this ability should fizzle. diff --git a/Mage.Sets/src/mage/cards/t/TymaretTheMurderKing.java b/Mage.Sets/src/mage/cards/t/TymaretTheMurderKing.java index 80fb22538f8..b5c3289fe5f 100644 --- a/Mage.Sets/src/mage/cards/t/TymaretTheMurderKing.java +++ b/Mage.Sets/src/mage/cards/t/TymaretTheMurderKing.java @@ -37,7 +37,7 @@ public final class TymaretTheMurderKing extends CardImpl { // {1}{R}, Sacrifice another creature: Tymaret, the Murder King deals 2 damage to target player. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl<>("{1}{R}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addTarget(new TargetPlayerOrPlaneswalker()); this.addAbility(ability); // {1}{B}, Sacrifice a creature: Return Tymaret from your graveyard to your hand. diff --git a/Mage.Sets/src/mage/cards/u/UktabiWildcats.java b/Mage.Sets/src/mage/cards/u/UktabiWildcats.java index 37a2175de0c..1cf617b9cfc 100644 --- a/Mage.Sets/src/mage/cards/u/UktabiWildcats.java +++ b/Mage.Sets/src/mage/cards/u/UktabiWildcats.java @@ -45,7 +45,7 @@ public final class UktabiWildcats extends CardImpl { // {G}, Sacrifice a Forest: Regenerate Uktabi Wildcats. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl<>("{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(1, 1, sacrificeFilter, true))); + ability.addCost(new SacrificeTargetCost(sacrificeFilter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/u/UndercityNecrolisk.java b/Mage.Sets/src/mage/cards/u/UndercityNecrolisk.java index 7373f1eac1e..8ff9f4b2b73 100644 --- a/Mage.Sets/src/mage/cards/u/UndercityNecrolisk.java +++ b/Mage.Sets/src/mage/cards/u/UndercityNecrolisk.java @@ -39,9 +39,7 @@ public final class UndercityNecrolisk extends CardImpl { new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(1) ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); // It gains menace until end of turn. Activate this ability only any time you could cast a sorcery. ability.addEffect(new GainAbilitySourceEffect( new MenaceAbility(), @@ -79,4 +77,4 @@ class SilencedActivateAsSorceryActivatedAbility extends ActivatedAbilityImpl { @Override public String getRule() { return super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/u/UndercityScavenger.java b/Mage.Sets/src/mage/cards/u/UndercityScavenger.java index f430dbf5010..584c6988d12 100644 --- a/Mage.Sets/src/mage/cards/u/UndercityScavenger.java +++ b/Mage.Sets/src/mage/cards/u/UndercityScavenger.java @@ -32,7 +32,7 @@ public final class UndercityScavenger extends CardImpl { // When Undercity Scavenger enters the battlefield, you may sacrifice another creature. If you do, put two +1/+1 counters on Undercity Scavenger, then scry 2. this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid( new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) ).addEffect(new ScryEffect(2).concatBy(", then")))); } diff --git a/Mage.Sets/src/mage/cards/u/UnnaturalHunger.java b/Mage.Sets/src/mage/cards/u/UnnaturalHunger.java index 413de477d0a..5858efe53cc 100644 --- a/Mage.Sets/src/mage/cards/u/UnnaturalHunger.java +++ b/Mage.Sets/src/mage/cards/u/UnnaturalHunger.java @@ -76,7 +76,7 @@ class UnnaturalHungerEffect extends OneShotEffect { if (attachedTo != null) { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); filter.add(Predicates.not(new PermanentIdPredicate(aura.getAttachedTo()))); // not attached permanent - Cost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)); + Cost cost = new SacrificeTargetCost(filter); Player enchantedCreatureController = game.getPlayer(attachedTo.getControllerId()); if (enchantedCreatureController != null && cost.canPay(source, source, enchantedCreatureController.getId(), game) diff --git a/Mage.Sets/src/mage/cards/u/UrborgPanther.java b/Mage.Sets/src/mage/cards/u/UrborgPanther.java index c629c87cd30..faef0f94d21 100644 --- a/Mage.Sets/src/mage/cards/u/UrborgPanther.java +++ b/Mage.Sets/src/mage/cards/u/UrborgPanther.java @@ -67,8 +67,8 @@ public class UrborgPanther extends CardImpl { 1, 1, filterCard ), false, true), new CompositeCost(new CompositeCost( - new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter1)), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter2)), + new SacrificeTargetCost(filter1), + new SacrificeTargetCost(filter2), "" ), new SacrificeSourceCost(), "sacrifice a creature named Feral Shadow, " + "a creature named Breathstealer, and {this}") diff --git a/Mage.Sets/src/mage/cards/u/UtopiaMycon.java b/Mage.Sets/src/mage/cards/u/UtopiaMycon.java index 66e7863d1d8..57e5e5efacb 100644 --- a/Mage.Sets/src/mage/cards/u/UtopiaMycon.java +++ b/Mage.Sets/src/mage/cards/u/UtopiaMycon.java @@ -47,7 +47,7 @@ public final class UtopiaMycon extends CardImpl { this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken()), new RemoveCountersSourceCost(CounterType.SPORE.createInstance(3)))); // Sacrifice a Saproling: Add one mana of any color. - Ability ability = new AnyColorManaAbility(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false)), + Ability ability = new AnyColorManaAbility(new SacrificeTargetCost(filter), new PermanentsOnBattlefieldCount(filter), false); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/Valleymaker.java b/Mage.Sets/src/mage/cards/v/Valleymaker.java index 1bf5611ef09..e3a84c3fe5d 100644 --- a/Mage.Sets/src/mage/cards/v/Valleymaker.java +++ b/Mage.Sets/src/mage/cards/v/Valleymaker.java @@ -43,14 +43,14 @@ public final class Valleymaker extends CardImpl { // {tap}, Sacrifice a Mountain: Valleymaker deals 3 damage to target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(3), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); // {tap}, Sacrifice a Forest: Choose a player. That player adds {G}{G}{G}. Ability ability2 = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaToManaPoolTargetControllerEffect(Mana.GreenMana(3), "chosen player") .setText("choose a player. That player adds {G}{G}{G}"), new TapSourceCost()); - ability2.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter2))); + ability2.addCost(new SacrificeTargetCost(filter2)); ability2.addTarget(new TargetPlayer(1, 1, true)); this.addAbility(ability2); } diff --git a/Mage.Sets/src/mage/cards/v/VampireAristocrat.java b/Mage.Sets/src/mage/cards/v/VampireAristocrat.java index dc6fc9f9e01..55c14feb5f1 100644 --- a/Mage.Sets/src/mage/cards/v/VampireAristocrat.java +++ b/Mage.Sets/src/mage/cards/v/VampireAristocrat.java @@ -1,10 +1,8 @@ package mage.cards.v; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -12,8 +10,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; import mage.constants.Zone; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.target.common.TargetControlledCreaturePermanent; +import mage.filter.StaticFilters; import java.util.UUID; @@ -28,9 +25,12 @@ public final class VampireAristocrat extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 2, Duration.EndOfTurn), new ManaCostsImpl<>("")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("creature")))); - this.addAbility(ability); + + // Sacrifice a creature: Vampire Aristocrat gets +2/+2 until end of turn. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BoostSourceEffect(2, 2, Duration.EndOfTurn), + new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT_CREATURE))); } private VampireAristocrat(final VampireAristocrat card) { diff --git a/Mage.Sets/src/mage/cards/v/VampireWarlord.java b/Mage.Sets/src/mage/cards/v/VampireWarlord.java index 63fc98d2201..c31ef893e83 100644 --- a/Mage.Sets/src/mage/cards/v/VampireWarlord.java +++ b/Mage.Sets/src/mage/cards/v/VampireWarlord.java @@ -29,8 +29,8 @@ public final class VampireWarlord extends CardImpl { this.toughness = new MageInt(2); // Sacrifice another creature: Regenerate Vampire Warlord. - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false); - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new SacrificeTargetCost(target))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } diff --git a/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java b/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java index dc83c77ed4a..a790c8740de 100644 --- a/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java +++ b/Mage.Sets/src/mage/cards/v/VarolzTheScarStriped.java @@ -40,7 +40,7 @@ public final class VarolzTheScarStriped extends CardImpl { // Sacrifice another creature: Regenerate Varolz, the Scar-Striped. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true)))); + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); } private VarolzTheScarStriped(final VarolzTheScarStriped card) { diff --git a/Mage.Sets/src/mage/cards/v/VerminGorger.java b/Mage.Sets/src/mage/cards/v/VerminGorger.java index bd04209696c..0bdb681e71f 100644 --- a/Mage.Sets/src/mage/cards/v/VerminGorger.java +++ b/Mage.Sets/src/mage/cards/v/VerminGorger.java @@ -31,7 +31,7 @@ public final class VerminGorger extends CardImpl { // {T}, Sacrifice another creature: Each opponent loses 2 life and you gain 2 life. Ability ability = new SimpleActivatedAbility(new LoseLifeOpponentsEffect(2), new TapSourceCost()); ability.addEffect(new GainLifeEffect(2).concatBy("and")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VillageElder.java b/Mage.Sets/src/mage/cards/v/VillageElder.java index 8565df58b74..89b347d5cb6 100644 --- a/Mage.Sets/src/mage/cards/v/VillageElder.java +++ b/Mage.Sets/src/mage/cards/v/VillageElder.java @@ -39,7 +39,7 @@ public final class VillageElder extends CardImpl { // {G}, {tap}, Sacrifice a Forest: Regenerate target creature. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateTargetEffect(), new ManaCostsImpl<>("{G}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VillageRites.java b/Mage.Sets/src/mage/cards/v/VillageRites.java index 3217fc3d6eb..9de9785e39b 100644 --- a/Mage.Sets/src/mage/cards/v/VillageRites.java +++ b/Mage.Sets/src/mage/cards/v/VillageRites.java @@ -19,9 +19,7 @@ public final class VillageRites extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // As an additional cost to cast this spell, sacrifice a creature. - this.getSpellAbility().addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + this.getSpellAbility().addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); // Draw two cards. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); diff --git a/Mage.Sets/src/mage/cards/v/VirtussManeuver.java b/Mage.Sets/src/mage/cards/v/VirtussManeuver.java index 740e0bd2f0b..65268d2ab7b 100644 --- a/Mage.Sets/src/mage/cards/v/VirtussManeuver.java +++ b/Mage.Sets/src/mage/cards/v/VirtussManeuver.java @@ -23,6 +23,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -100,7 +101,7 @@ class VirtussManeuverEffect extends OneShotEffect { if (player == null) { continue; } - TargetControlledPermanent target = new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_CONTROLLED_A_CREATURE); player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } diff --git a/Mage.Sets/src/mage/cards/v/VisceridDrone.java b/Mage.Sets/src/mage/cards/v/VisceridDrone.java index 2ac1e69c0d6..1b2e359826d 100644 --- a/Mage.Sets/src/mage/cards/v/VisceridDrone.java +++ b/Mage.Sets/src/mage/cards/v/VisceridDrone.java @@ -51,7 +51,7 @@ public final class VisceridDrone extends CardImpl { Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(true), new TapSourceCost()); ability.addCost(new CompositeCost( new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), - new SacrificeTargetCost(new TargetControlledPermanent(filter2)), + new SacrificeTargetCost(filter2), "Sacrifice a creature and a Swamp" )); ability.addTarget(new TargetCreaturePermanent(filter1)); @@ -61,7 +61,7 @@ public final class VisceridDrone extends CardImpl { ability = new SimpleActivatedAbility(new DestroyTargetEffect(true), new TapSourceCost()); ability.addCost(new CompositeCost( new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT), - new SacrificeTargetCost(new TargetControlledPermanent(filter3)), + new SacrificeTargetCost(filter3), "Sacrifice a creature and a snow Swamp" )); ability.addTarget(new TargetCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/v/VitasporeThallid.java b/Mage.Sets/src/mage/cards/v/VitasporeThallid.java index fafc9a953bc..2b382dfe69d 100644 --- a/Mage.Sets/src/mage/cards/v/VitasporeThallid.java +++ b/Mage.Sets/src/mage/cards/v/VitasporeThallid.java @@ -47,7 +47,7 @@ public final class VitasporeThallid extends CardImpl { // Sacrifice a Saproling: Target creature gains haste until end of turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1, filter, false))); + new SacrificeTargetCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VivienOnTheHunt.java b/Mage.Sets/src/mage/cards/v/VivienOnTheHunt.java index f99c42df5df..8536ae43ded 100644 --- a/Mage.Sets/src/mage/cards/v/VivienOnTheHunt.java +++ b/Mage.Sets/src/mage/cards/v/VivienOnTheHunt.java @@ -17,6 +17,7 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPermanent; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -75,9 +76,7 @@ class VivienOnTheHuntSacrificeEffect extends OneShotEffect { if (player == null) { return false; } - TargetPermanent target = new TargetPermanent( - 0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true - ); + TargetSacrifice target = new TargetSacrifice(0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent == null || !permanent.sacrifice(source, game)) { diff --git a/Mage.Sets/src/mage/cards/v/VoidmageProdigy.java b/Mage.Sets/src/mage/cards/v/VoidmageProdigy.java index 4596bea3968..8dc6f028a0c 100644 --- a/Mage.Sets/src/mage/cards/v/VoidmageProdigy.java +++ b/Mage.Sets/src/mage/cards/v/VoidmageProdigy.java @@ -41,7 +41,7 @@ public final class VoidmageProdigy extends CardImpl { // {U}{U}, Sacrifice a Wizard: Counter target spell. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl<>("{U}{U}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, false))); + ability.addCost(new SacrificeTargetCost(filter)); Target target = new TargetSpell(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java index 8fd00e0beb2..120ab99bad4 100644 --- a/Mage.Sets/src/mage/cards/v/VoldarenPariah.java +++ b/Mage.Sets/src/mage/cards/v/VoldarenPariah.java @@ -46,7 +46,7 @@ public final class VoldarenPariah extends CardImpl { // Sacrifice three other creatures: Transform Voldaren Pariah. this.addAbility(new TransformAbility()); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(3, 3, filter, false)))); + new SacrificeTargetCost(3, filter))); // Madness {B}{B}{B} this.addAbility(new MadnessAbility(new ManaCostsImpl<>("{B}{B}{B}"))); diff --git a/Mage.Sets/src/mage/cards/v/VolrathsCurse.java b/Mage.Sets/src/mage/cards/v/VolrathsCurse.java index 4bd242be624..7d4d5419641 100644 --- a/Mage.Sets/src/mage/cards/v/VolrathsCurse.java +++ b/Mage.Sets/src/mage/cards/v/VolrathsCurse.java @@ -16,11 +16,11 @@ import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; -import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -145,7 +145,7 @@ class VolrathsCurseSpecialAction extends SpecialAction { public VolrathsCurseSpecialAction() { super(Zone.BATTLEFIELD); - this.addCost(new SacrificeTargetCost(new TargetControlledPermanent(), true)); + this.addCost(new SacrificeTargetCost(StaticFilters.FILTER_PERMANENT)); this.addEffect(new VolrathsCurseIgnoreEffect(keyString)); this.setMayActivate(TargetController.CONTROLLER_ATTACHED_TO); } diff --git a/Mage.Sets/src/mage/cards/v/VoltageSurge.java b/Mage.Sets/src/mage/cards/v/VoltageSurge.java index ca2d7c391c2..554a7680e6f 100644 --- a/Mage.Sets/src/mage/cards/v/VoltageSurge.java +++ b/Mage.Sets/src/mage/cards/v/VoltageSurge.java @@ -12,6 +12,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetCreatureOrPlaneswalker; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.Collection; @@ -26,8 +27,8 @@ public final class VoltageSurge extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); // As an additional cost to cast this spell, you may sacrifice an artifact. - this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent( - 0, 1, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN, true + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetSacrifice( + 0, 1, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN )).setText("you may sacrifice an artifact")); // Voltage Surge deals 2 damage to target creature or planeswalker. If this spell's additional cost was paid, Voltage Surge deals 4 damage instead. diff --git a/Mage.Sets/src/mage/cards/v/VonasHunger.java b/Mage.Sets/src/mage/cards/v/VonasHunger.java index 1cf757136d5..556bddc412f 100644 --- a/Mage.Sets/src/mage/cards/v/VonasHunger.java +++ b/Mage.Sets/src/mage/cards/v/VonasHunger.java @@ -18,6 +18,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import java.util.ArrayList; import java.util.List; @@ -81,9 +82,9 @@ class VonasHungerEffect extends OneShotEffect { if (player != null) { int numTargets = (game.getBattlefield().countAll(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), game) + 1) / 2; if (numTargets > 0) { - TargetPermanent target = new TargetPermanent(numTargets, numTargets, StaticFilters.FILTER_CONTROLLED_CREATURE, true); + TargetSacrifice target = new TargetSacrifice(numTargets, StaticFilters.FILTER_CONTROLLED_CREATURE); if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + player.choose(Outcome.Sacrifice, target, source, game); perms.addAll(target.getTargets()); } } diff --git a/Mage.Sets/src/mage/cards/v/VoraciousFellBeast.java b/Mage.Sets/src/mage/cards/v/VoraciousFellBeast.java index 21a9833d15f..d608b9b44e1 100644 --- a/Mage.Sets/src/mage/cards/v/VoraciousFellBeast.java +++ b/Mage.Sets/src/mage/cards/v/VoraciousFellBeast.java @@ -10,13 +10,16 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SetTargetPointer; import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.FoodToken; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import java.util.ArrayList; import java.util.List; @@ -86,8 +89,7 @@ class VoraciousFellBeastEffect extends OneShotEffect { continue; } - TargetControlledCreaturePermanent target = - new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent(), true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(player.getId(), source, game)) { while (!target.isChosen() && player.canRespond()) { player.choose(Outcome.Sacrifice, target, source, game); diff --git a/Mage.Sets/src/mage/cards/v/VoraciousNull.java b/Mage.Sets/src/mage/cards/v/VoraciousNull.java index 7528eb6e0f6..0121c2ec642 100644 --- a/Mage.Sets/src/mage/cards/v/VoraciousNull.java +++ b/Mage.Sets/src/mage/cards/v/VoraciousNull.java @@ -31,7 +31,7 @@ public final class VoraciousNull extends CardImpl { // {1}{B}, Sacrifice another creature: Put two +1/+1 counters on Voracious Null. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), new ManaCostsImpl<>("{1}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/VraskaGolgariQueen.java b/Mage.Sets/src/mage/cards/v/VraskaGolgariQueen.java index 55a32bd6e10..d9c942009f6 100644 --- a/Mage.Sets/src/mage/cards/v/VraskaGolgariQueen.java +++ b/Mage.Sets/src/mage/cards/v/VraskaGolgariQueen.java @@ -50,7 +50,7 @@ public final class VraskaGolgariQueen extends CardImpl { // +2: You may sacrifice another permanent. If you do, you gain 1 life and draw a card. DoIfCostPaid effect = new DoIfCostPaid( new GainLifeEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(filter1)) + new SacrificeTargetCost(filter1) ); effect.addEffect(new DrawCardSourceControllerEffect(1).setText("and draw a card")); this.addAbility(new LoyaltyAbility(effect, 2)); diff --git a/Mage.Sets/src/mage/cards/v/VulshokWarBoar.java b/Mage.Sets/src/mage/cards/v/VulshokWarBoar.java index aa1dc0cbf4a..7798095a676 100644 --- a/Mage.Sets/src/mage/cards/v/VulshokWarBoar.java +++ b/Mage.Sets/src/mage/cards/v/VulshokWarBoar.java @@ -30,7 +30,7 @@ public final class VulshokWarBoar extends CardImpl { this.toughness = new MageInt(5); // When Vulshok War Boar enters the battlefield, sacrifice it unless you sacrifice an artifact. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(new TargetControlledPermanent(filter))))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new SacrificeTargetCost(filter)))); } private VulshokWarBoar(final VulshokWarBoar card) { diff --git a/Mage.Sets/src/mage/cards/w/WalkTheAeons.java b/Mage.Sets/src/mage/cards/w/WalkTheAeons.java index f9608b5dc93..0fe964a7869 100644 --- a/Mage.Sets/src/mage/cards/w/WalkTheAeons.java +++ b/Mage.Sets/src/mage/cards/w/WalkTheAeons.java @@ -28,7 +28,7 @@ public final class WalkTheAeons extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}"); // Buyback—Sacrifice three Islands. (You may sacrifice three Islands in addition to any other costs as you cast this spell. If you do, put this card into your hand as it resolves.) - this.addAbility(new BuybackAbility(new SacrificeTargetCost(new TargetControlledPermanent(3, filter)))); + this.addAbility(new BuybackAbility(new SacrificeTargetCost(3, filter))); // Target player takes an extra turn after this one. this.getSpellAbility().addEffect(new AddExtraTurnTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/w/WallOfMulch.java b/Mage.Sets/src/mage/cards/w/WallOfMulch.java index c9f999c3443..ff985086f09 100644 --- a/Mage.Sets/src/mage/cards/w/WallOfMulch.java +++ b/Mage.Sets/src/mage/cards/w/WallOfMulch.java @@ -42,7 +42,7 @@ public final class WallOfMulch extends CardImpl { this.addAbility(DefenderAbility.getInstance()); // {G}, Sacrifice a Wall: Draw a card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{G}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WandOfTheElements.java b/Mage.Sets/src/mage/cards/w/WandOfTheElements.java index 8c086af4e75..0a6f6564422 100644 --- a/Mage.Sets/src/mage/cards/w/WandOfTheElements.java +++ b/Mage.Sets/src/mage/cards/w/WandOfTheElements.java @@ -35,12 +35,12 @@ public final class WandOfTheElements extends CardImpl { // {T}, Sacrifice an Island: Create a 2/2 blue Elemental creature token with flying. Ability firstAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WandOfTheElementsFirstToken()), new TapSourceCost()); - firstAbility.addCost(new SacrificeTargetCost(new TargetControlledPermanent(islandFilter))); + firstAbility.addCost(new SacrificeTargetCost(islandFilter)); this.addAbility(firstAbility); // {T}, Sacrifice a Mountain: Create a 3/3 red Elemental creature token. Ability secondAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new WandOfTheElementsSecondToken()), new TapSourceCost()); - secondAbility.addCost(new SacrificeTargetCost(new TargetControlledPermanent(mountainFilter))); + secondAbility.addCost(new SacrificeTargetCost(mountainFilter)); this.addAbility(secondAbility); } diff --git a/Mage.Sets/src/mage/cards/w/WanderwineProphets.java b/Mage.Sets/src/mage/cards/w/WanderwineProphets.java index ed1ab990f6e..d3f430467f5 100644 --- a/Mage.Sets/src/mage/cards/w/WanderwineProphets.java +++ b/Mage.Sets/src/mage/cards/w/WanderwineProphets.java @@ -39,7 +39,7 @@ public final class WanderwineProphets extends CardImpl { // Whenever Wanderwine Prophets deals combat damage to a player, you may sacrifice a Merfolk. If you do, take an extra turn after this one. Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new DoIfCostPaid( new AddExtraTurnControllerEffect(), - new SacrificeTargetCost(new TargetControlledPermanent(1, 1, filter, true)) + new SacrificeTargetCost(filter) ), false); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java b/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java index 93433328965..799239517f7 100644 --- a/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java +++ b/Mage.Sets/src/mage/cards/w/WasitoraNekoruQueen.java @@ -15,12 +15,14 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.SuperType; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.game.permanent.token.WasitoraCatDragonToken; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; /** * @@ -78,9 +80,7 @@ class WasitoraNekoruQueenEffect extends OneShotEffect { Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (damagedPlayer != null && controller != null) { - FilterControlledPermanent filter = new FilterControlledPermanent("creature"); - filter.add(CardType.CREATURE.getPredicate()); - TargetPermanent target = new TargetPermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (damagedPlayer.choose(Outcome.Sacrifice, target, source, game)) { Permanent objectToBeSacrificed = game.getPermanent(target.getFirstTarget()); if (objectToBeSacrificed != null) { diff --git a/Mage.Sets/src/mage/cards/w/WeaponizeTheMonsters.java b/Mage.Sets/src/mage/cards/w/WeaponizeTheMonsters.java index 34ac6e63418..e7b1e34d203 100644 --- a/Mage.Sets/src/mage/cards/w/WeaponizeTheMonsters.java +++ b/Mage.Sets/src/mage/cards/w/WeaponizeTheMonsters.java @@ -24,9 +24,7 @@ public final class WeaponizeTheMonsters extends CardImpl { // {2}, Sacrifice a creature: Weaponize the Monsters deals 2 damage to any target. Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(2), new GenericManaCost(2)); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent( - StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT - ))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WeddingSecurity.java b/Mage.Sets/src/mage/cards/w/WeddingSecurity.java index afbd7fffea1..7c4ea3e4484 100644 --- a/Mage.Sets/src/mage/cards/w/WeddingSecurity.java +++ b/Mage.Sets/src/mage/cards/w/WeddingSecurity.java @@ -40,7 +40,7 @@ public final class WeddingSecurity extends CardImpl { // Whenever Wedding Security attacks, you may sacrifice a Blood token. If you do, put a +1/+1 counter on Wedding Security and draw a card. this.addAbility(new AttacksTriggeredAbility(new DoIfCostPaid( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(filter)) + new SacrificeTargetCost(filter) ).addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")))); } diff --git a/Mage.Sets/src/mage/cards/w/WeirdingShaman.java b/Mage.Sets/src/mage/cards/w/WeirdingShaman.java index 96e76a8b1e8..3075ef11b4e 100644 --- a/Mage.Sets/src/mage/cards/w/WeirdingShaman.java +++ b/Mage.Sets/src/mage/cards/w/WeirdingShaman.java @@ -37,7 +37,7 @@ public final class WeirdingShaman extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(1); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new GoblinRogueToken(), 2), new ManaCostsImpl<>("{3}{B}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(filter))); + ability.addCost(new SacrificeTargetCost(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java index 0fa4ecf9468..de24c77c826 100644 --- a/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java +++ b/Mage.Sets/src/mage/cards/w/WestvaleAbbey.java @@ -18,6 +18,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; import mage.game.permanent.token.HumanClericToken; import mage.target.common.TargetControlledPermanent; @@ -45,7 +46,7 @@ public final class WestvaleAbbey extends CardImpl { this.addAbility(new TransformAbility()); ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(), new GenericManaCost(5)); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(5, 5, new FilterControlledCreaturePermanent("creatures"), true))); + ability.addCost(new SacrificeTargetCost(5, StaticFilters.FILTER_PERMANENT_CREATURES)); ability.addEffect(new UntapSourceEffect().setText("untap it").concatBy(", then")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WhisperBloodLiturgist.java b/Mage.Sets/src/mage/cards/w/WhisperBloodLiturgist.java index 55ee46285fd..2555e0094d1 100644 --- a/Mage.Sets/src/mage/cards/w/WhisperBloodLiturgist.java +++ b/Mage.Sets/src/mage/cards/w/WhisperBloodLiturgist.java @@ -38,7 +38,7 @@ public final class WhisperBloodLiturgist extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToBattlefieldTargetEffect() .setText("Return target creature card from your graveyard to the battlefield"), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(2, 2, new FilterControlledCreaturePermanent("creatures"), true))); + ability.addCost(new SacrificeTargetCost(2, StaticFilters.FILTER_PERMANENT_CREATURES)); ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/Whiteout.java b/Mage.Sets/src/mage/cards/w/Whiteout.java index 9ad84efe1ad..595df1ff16e 100644 --- a/Mage.Sets/src/mage/cards/w/Whiteout.java +++ b/Mage.Sets/src/mage/cards/w/Whiteout.java @@ -39,7 +39,7 @@ public final class Whiteout extends CardImpl { this.getSpellAbility().addEffect(effect); // Sacrifice a snow land: Return Whiteout from your graveyard to your hand. - this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new SacrificeTargetCost(new TargetControlledPermanent(filter)))); + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new SacrificeTargetCost(filter))); } private Whiteout(final Whiteout card) { diff --git a/Mage.Sets/src/mage/cards/w/WickedWolf.java b/Mage.Sets/src/mage/cards/w/WickedWolf.java index 1a9670c1aa6..afd1a03b7f3 100644 --- a/Mage.Sets/src/mage/cards/w/WickedWolf.java +++ b/Mage.Sets/src/mage/cards/w/WickedWolf.java @@ -44,7 +44,7 @@ public final class WickedWolf extends CardImpl { // Sacrifice a Food: Put a +1/+1 counter on Wicked Wolf. It gains indestructible until end of turn. Tap it. ability = new SimpleActivatedAbility( new AddCountersSourceEffect(CounterType.P1P1.createInstance()), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_FOOD)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_FOOD) ); ability.addEffect(new GainAbilitySourceEffect( IndestructibleAbility.getInstance(), Duration.EndOfTurn diff --git a/Mage.Sets/src/mage/cards/w/WilheltTheRotcleaver.java b/Mage.Sets/src/mage/cards/w/WilheltTheRotcleaver.java index 0cf0f5d4342..c9daa885fa4 100644 --- a/Mage.Sets/src/mage/cards/w/WilheltTheRotcleaver.java +++ b/Mage.Sets/src/mage/cards/w/WilheltTheRotcleaver.java @@ -58,7 +58,7 @@ public final class WilheltTheRotcleaver extends CardImpl { // At the beginning of your end step, you may sacrifice a Zombie. If you do, draw a card. this.addAbility(new BeginningOfEndStepTriggeredAbility(new DoIfCostPaid( new DrawCardSourceControllerEffect(1), - new SacrificeTargetCost(new TargetControlledPermanent(filter2)) + new SacrificeTargetCost(filter2) ), TargetController.YOU, false)); } diff --git a/Mage.Sets/src/mage/cards/w/WitchsCauldron.java b/Mage.Sets/src/mage/cards/w/WitchsCauldron.java index 0ce941ea54d..8cc9ddaef18 100644 --- a/Mage.Sets/src/mage/cards/w/WitchsCauldron.java +++ b/Mage.Sets/src/mage/cards/w/WitchsCauldron.java @@ -26,7 +26,7 @@ public final class WitchsCauldron extends CardImpl { // {1}{B}, {T}, Sacrifice a creature: You gain 1 life and draw a card. Ability ability = new SimpleActivatedAbility(new GainLifeEffect(1), new ManaCostsImpl<>("{1}{B}")); ability.addCost(new TapSourceCost()); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WitchsOven.java b/Mage.Sets/src/mage/cards/w/WitchsOven.java index aa1d4807d89..4807ecb8357 100644 --- a/Mage.Sets/src/mage/cards/w/WitchsOven.java +++ b/Mage.Sets/src/mage/cards/w/WitchsOven.java @@ -31,9 +31,7 @@ public final class WitchsOven extends CardImpl { // {T}, Sacrifice a creature: Create a Food token. If the sacrificed creature's toughness was 4 or greater, create two Food tokens instead. Ability ability = new SimpleActivatedAbility(new WitchsOvenEffect(), new TapSourceCost()); - ability.addCost(new SacrificeTargetCost( - new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WoeStrider.java b/Mage.Sets/src/mage/cards/w/WoeStrider.java index 12bcbb0949c..931665584e6 100644 --- a/Mage.Sets/src/mage/cards/w/WoeStrider.java +++ b/Mage.Sets/src/mage/cards/w/WoeStrider.java @@ -35,7 +35,7 @@ public final class WoeStrider extends CardImpl { // Sacrifice another creature: Scry 1. this.addAbility(new SimpleActivatedAbility( - new ScryEffect(1, false), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new ScryEffect(1, false), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) )); // Escape—{3}{B}{B}, Exile four other cards from your graveyard. diff --git a/Mage.Sets/src/mage/cards/w/WoebringerDemon.java b/Mage.Sets/src/mage/cards/w/WoebringerDemon.java index 7c587cbee98..125c99ba66d 100644 --- a/Mage.Sets/src/mage/cards/w/WoebringerDemon.java +++ b/Mage.Sets/src/mage/cards/w/WoebringerDemon.java @@ -14,10 +14,12 @@ import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -73,10 +75,9 @@ class WoebringerDemonEffect extends OneShotEffect { if (controller != null) { Player currentPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); if (currentPlayer != null) { - TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent(); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_CREATURE); if (target.canChoose(currentPlayer.getId(), source, game)) { - currentPlayer.chooseTarget(Outcome.Sacrifice, target, source, game); + currentPlayer.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { permanent.sacrifice(source, game); diff --git a/Mage.Sets/src/mage/cards/w/WorldBreaker.java b/Mage.Sets/src/mage/cards/w/WorldBreaker.java index 75c26d34a20..18d3912bfef 100644 --- a/Mage.Sets/src/mage/cards/w/WorldBreaker.java +++ b/Mage.Sets/src/mage/cards/w/WorldBreaker.java @@ -57,7 +57,7 @@ public final class WorldBreaker extends CardImpl { // {2}{C}, Sacrifice a land: Return World Breaker from your graveyard to your hand. ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), new ManaCostsImpl<>("{2}{C}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/w/WorldQueller.java b/Mage.Sets/src/mage/cards/w/WorldQueller.java index e41c1288e48..8e04aee4cbf 100644 --- a/Mage.Sets/src/mage/cards/w/WorldQueller.java +++ b/Mage.Sets/src/mage/cards/w/WorldQueller.java @@ -20,6 +20,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.*; @@ -113,14 +114,13 @@ class WorldQuellerEffect extends OneShotEffect { FilterControlledPermanent filter = new FilterControlledPermanent("permanent you control of type " + type.toString()); filter.add(type.getPredicate()); - TargetPermanent target = new TargetControlledPermanent(1, 1, filter, false); - target.withNotTarget(true); + TargetSacrifice target = new TargetSacrifice(filter); for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player2 = game.getPlayer(playerId); if (player2 != null && target.canChoose(playerId, source, game)) { while (player2.canRespond() && !target.isChosen() && target.canChoose(playerId, source, game)) { - player2.chooseTarget(Outcome.Sacrifice, target, source, game); + player2.choose(Outcome.Sacrifice, target, source, game); } Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { diff --git a/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java b/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java index ce2713e34ac..0c492545917 100644 --- a/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java +++ b/Mage.Sets/src/mage/cards/w/WormsOfTheEarth.java @@ -11,6 +11,7 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.game.Game; import mage.game.events.GameEvent; @@ -124,7 +125,7 @@ class WormsOfTheEarthDestroyEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) { - Cost cost = new SacrificeTargetCost(new TargetControlledPermanent(2, 2, new FilterControlledLandPermanent("lands"), false)); + Cost cost = new SacrificeTargetCost(2, StaticFilters.FILTER_LANDS); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { diff --git a/Mage.Sets/src/mage/cards/x/XathridDemon.java b/Mage.Sets/src/mage/cards/x/XathridDemon.java index 37bbf66fe73..5d8f2dfaa21 100644 --- a/Mage.Sets/src/mage/cards/x/XathridDemon.java +++ b/Mage.Sets/src/mage/cards/x/XathridDemon.java @@ -23,6 +23,7 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; /** * @@ -83,7 +84,7 @@ class XathridDemonEffect extends OneShotEffect { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature other than " + sourcePermanent.getName()); filter.add(AnotherPredicate.instance); - Target target = new TargetControlledCreaturePermanent(1, 1, filter, true); + TargetSacrifice target = new TargetSacrifice(filter); if (target.canChoose(controller.getId(), source, game)) { controller.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/y/YahenniUndyingPartisan.java b/Mage.Sets/src/mage/cards/y/YahenniUndyingPartisan.java index de83521644a..2c17b102a77 100644 --- a/Mage.Sets/src/mage/cards/y/YahenniUndyingPartisan.java +++ b/Mage.Sets/src/mage/cards/y/YahenniUndyingPartisan.java @@ -46,7 +46,7 @@ public final class YahenniUndyingPartisan extends CardImpl { // Sacrifice another creature: Yahenni gains indestructible until end of turn. this.addAbility(new SimpleActivatedAbility( new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), - new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)) + new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) )); } diff --git a/Mage.Sets/src/mage/cards/y/YawgmothThranPhysician.java b/Mage.Sets/src/mage/cards/y/YawgmothThranPhysician.java index a55b45a7d6f..44d76c0750b 100644 --- a/Mage.Sets/src/mage/cards/y/YawgmothThranPhysician.java +++ b/Mage.Sets/src/mage/cards/y/YawgmothThranPhysician.java @@ -48,9 +48,7 @@ public final class YawgmothThranPhysician extends CardImpl { Ability ability = new SimpleActivatedAbility( new AddCountersTargetEffect(CounterType.M1M1.createInstance()), new PayLifeCost(1) ); - ability.addCost(new SacrificeTargetCost( - new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) - )); + ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)); ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and")); ability.addTarget(new TargetCreaturePermanent(0, 1)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/z/ZiatoraTheIncinerator.java b/Mage.Sets/src/mage/cards/z/ZiatoraTheIncinerator.java index 98a9175a705..29f452a61a2 100644 --- a/Mage.Sets/src/mage/cards/z/ZiatoraTheIncinerator.java +++ b/Mage.Sets/src/mage/cards/z/ZiatoraTheIncinerator.java @@ -19,6 +19,7 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetAnyTarget; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import java.util.UUID; @@ -78,8 +79,8 @@ class ZiatoraTheIncineratorEffect extends OneShotEffect { if (player == null) { return false; } - TargetPermanent target = new TargetControlledPermanent( - 0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true + TargetSacrifice target = new TargetSacrifice( + 0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE ); player.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/z/ZopandrelHungerDominus.java b/Mage.Sets/src/mage/cards/z/ZopandrelHungerDominus.java index d06c98e5f48..89b9f26897d 100644 --- a/Mage.Sets/src/mage/cards/z/ZopandrelHungerDominus.java +++ b/Mage.Sets/src/mage/cards/z/ZopandrelHungerDominus.java @@ -20,6 +20,7 @@ import mage.filter.predicate.mageobject.AnotherPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -54,7 +55,7 @@ public final class ZopandrelHungerDominus extends CardImpl { // {G/P}{G/P}, Sacrifice two other creatures: Put an indestructible counter on Zopandrel, Hunger Dominus. Ability ability = new SimpleActivatedAbility(new AddCountersSourceEffect(CounterType.INDESTRUCTIBLE.createInstance()), new ManaCostsImpl<>("{G/P}{G/P}")); - ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(2, filter))); + ability.addCost(new SacrificeTargetCost(2, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/z/ZuranOrb.java b/Mage.Sets/src/mage/cards/z/ZuranOrb.java index 84beb4f4b7f..aab1e030bfa 100644 --- a/Mage.Sets/src/mage/cards/z/ZuranOrb.java +++ b/Mage.Sets/src/mage/cards/z/ZuranOrb.java @@ -22,7 +22,7 @@ public final class ZuranOrb extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{0}"); // Sacrifice a land: You gain 2 life. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT)))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new SacrificeTargetCost(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))); } private ZuranOrb(final ZuranOrb card) { diff --git a/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java b/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java index 69fc0e12abb..37f1e7a33e9 100644 --- a/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java +++ b/Mage.Sets/src/mage/sets/CommanderLegendsBattleForBaldursGate.java @@ -338,6 +338,9 @@ public final class CommanderLegendsBattleForBaldursGate extends ExpansionSet { cards.add(new SetCardInfo("Javelin of Lightning", 185, Rarity.COMMON, mage.cards.j.JavelinOfLightning.class)); cards.add(new SetCardInfo("Jazal Goldmane", 697, Rarity.MYTHIC, mage.cards.j.JazalGoldmane.class)); cards.add(new SetCardInfo("Jeska's Will", 799, Rarity.RARE, mage.cards.j.JeskasWill.class)); + cards.add(new SetCardInfo("Jon Irenicus, Shattered One", 278, Rarity.RARE, mage.cards.j.JonIrenicusShatteredOne.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jon Irenicus, Shattered One", 425, Rarity.RARE, mage.cards.j.JonIrenicusShatteredOne.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Jon Irenicus, Shattered One", 536, Rarity.RARE, mage.cards.j.JonIrenicusShatteredOne.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Journey to the Lost City", 681, Rarity.RARE, mage.cards.j.JourneyToTheLostCity.class)); cards.add(new SetCardInfo("Juvenile Mist Dragon", 79, Rarity.UNCOMMON, mage.cards.j.JuvenileMistDragon.class)); cards.add(new SetCardInfo("Kagha, Shadow Archdruid", 279, Rarity.UNCOMMON, mage.cards.k.KaghaShadowArchdruid.class)); diff --git a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java index 48bfbe816c6..17affc69706 100644 --- a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java +++ b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java @@ -164,6 +164,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Herald's Horn", 280, Rarity.UNCOMMON, mage.cards.h.HeraldsHorn.class)); cards.add(new SetCardInfo("Heroic Intervention", 249, Rarity.RARE, mage.cards.h.HeroicIntervention.class)); cards.add(new SetCardInfo("Hinterland Harbor", 317, Rarity.RARE, mage.cards.h.HinterlandHarbor.class)); + cards.add(new SetCardInfo("Hithlain Rope", 76, Rarity.RARE, mage.cards.h.HithlainRope.class)); cards.add(new SetCardInfo("Homeward Path", 365, Rarity.MYTHIC, mage.cards.h.HomewardPath.class)); cards.add(new SetCardInfo("Horizon Canopy", 366, Rarity.MYTHIC, mage.cards.h.HorizonCanopy.class)); cards.add(new SetCardInfo("Hornet Queen", 250, Rarity.RARE, mage.cards.h.HornetQueen.class)); diff --git a/Mage.Tests/src/test/java/org/mage/test/AI/basic/TargetRequiredTest.java b/Mage.Tests/src/test/java/org/mage/test/AI/basic/TargetRequiredTest.java index 07f5e52f403..6ccaf8b8cdf 100644 --- a/Mage.Tests/src/test/java/org/mage/test/AI/basic/TargetRequiredTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/AI/basic/TargetRequiredTest.java @@ -24,7 +24,7 @@ public class TargetRequiredTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion"); - addTarget(playerA, "Mountain"); + setChoice(playerA, "Mountain"); setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ValakutTheMoltenPinnacleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ValakutTheMoltenPinnacleTest.java index fb5bb477975..22134c0ab5e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ValakutTheMoltenPinnacleTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/ValakutTheMoltenPinnacleTest.java @@ -65,7 +65,7 @@ public class ValakutTheMoltenPinnacleTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Scapeshift"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scapeshift"); - addTarget(playerA, "Forest^Forest^Forest^Forest^Forest^Forest"); + setChoice(playerA, "Forest^Forest^Forest^Forest^Forest^Forest"); setStopAt(3, PhaseStep.BEGIN_COMBAT); execute(); @@ -88,7 +88,7 @@ public class ValakutTheMoltenPinnacleTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Scapeshift"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scapeshift"); - addTarget(playerA, "Forest^Forest^Forest^Forest^Forest^Forest^Forest"); + setChoice(playerA, "Forest^Forest^Forest^Forest^Forest^Forest^Forest"); setStopAt(3, PhaseStep.BEGIN_COMBAT); execute(); @@ -113,7 +113,7 @@ public class ValakutTheMoltenPinnacleTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Scapeshift"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scapeshift"); - addTarget(playerA, "Forest^Forest^Forest^Forest^Forest^Forest^Forest"); + setChoice(playerA, "Forest^Forest^Forest^Forest^Forest^Forest^Forest"); setChoice(playerA, false); // Stomping Ground can be tapped setChoice(playerA, false); // Stomping Ground can be tapped setChoice(playerA, false); // Stomping Ground can be tapped diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java index 17b7b20ecdf..8ec0d1b5119 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/BestowTest.java @@ -217,7 +217,7 @@ public class BestowTest extends CardTestPlayerBase { castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "fused Far // Away"); addTarget(playerB, "Cyclops of One-Eyed Pass"); // Far addTarget(playerB, playerA); // Away - addTarget(playerA, "Nyxborn Rollicker"); + setChoice(playerA, "Nyxborn Rollicker"); setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExploitTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExploitTest.java index ce7939331ff..941fcf4ab14 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExploitTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ExploitTest.java @@ -33,7 +33,7 @@ public class ExploitTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Butcher"); setChoice(playerA, true); - addTarget(playerA, "Silvercoat Lion"); // sacrifice to Exploit + setChoice(playerA, "Silvercoat Lion"); // sacrifice to Exploit addTarget(playerA, "Thundering Giant"); // Target for the -3/-3 setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -66,7 +66,7 @@ public class ExploitTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Butcher"); waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1); setChoice(playerA, true); // Choose to exploit - addTarget(playerA, "Silvercoat Lion"); // sacrifice to Exploit + setChoice(playerA, "Silvercoat Lion"); // sacrifice to Exploit castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silumgar Butcher"); @@ -94,7 +94,7 @@ public class ExploitTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Qarsi Sadist"); setChoice(playerA, true); - addTarget(playerA, "Qarsi Sadist"); // sacrifice to Exploit + setChoice(playerA, "Qarsi Sadist"); // sacrifice to Exploit // Player B is auto-chosen to lose two life since only option setStopAt(1, PhaseStep.BEGIN_COMBAT); @@ -105,4 +105,4 @@ public class ExploitTest extends CardTestPlayerBase { assertLife(playerA, 22); assertLife(playerB, 18); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/KickerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/KickerTest.java index 3dc32d51f62..062b522cd9c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/KickerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/KickerTest.java @@ -324,7 +324,7 @@ public class KickerTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Gatekeeper of Malakir"); setChoice(playerA, true); // use kicker addTarget(playerA, playerB); // trigger's target - addTarget(playerB, "Birds of Paradise"); // sacrifice + setChoice(playerB, "Birds of Paradise"); // sacrifice // return to hand castSpell(1, PhaseStep.BEGIN_COMBAT, playerB, "Boomerang", "Gatekeeper of Malakir"); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java index abcadc83272..0d77fa756e3 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/OfferingTest.java @@ -19,7 +19,7 @@ public class OfferingTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nezumiPatron); setChoice(playerA, true); - addTarget(playerA, kurosTaken); + setChoice(playerA, kurosTaken); setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); @@ -64,7 +64,7 @@ public class OfferingTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, patron); setChoice(playerA, true); - addTarget(playerA, "Akki Drillmaster"); + setChoice(playerA, "Akki Drillmaster"); setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); @@ -90,7 +90,7 @@ public class OfferingTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, patron); setChoice(playerA, true); - addTarget(playerA, "Boros Recruit"); + setChoice(playerA, "Boros Recruit"); setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); @@ -117,7 +117,7 @@ public class OfferingTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, patron); setChoice(playerA, true); - addTarget(playerA, "Boggart Ram-Gang"); + setChoice(playerA, "Boggart Ram-Gang"); setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); @@ -138,7 +138,7 @@ public class OfferingTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blast-Furnace Hellkite"); setChoice(playerA, true); // use offering - addTarget(playerA, "Ancient Den"); + setChoice(playerA, "Ancient Den"); setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/CastFromHandWithoutPayingManaCostTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/CastFromHandWithoutPayingManaCostTest.java index 24d63b19f1f..4872925abde 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/CastFromHandWithoutPayingManaCostTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/alternate/CastFromHandWithoutPayingManaCostTest.java @@ -27,7 +27,7 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { /** * Omniscience only lets you cast spells for free from your hand. * Haakon lets you cast knights from your graveyard. - * + *

* If you control both, you must still pay costs to cast knights from your graveyard. */ @Test @@ -196,14 +196,14 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { /** * Omniscience is not allowing me to cast spells for free. I'm playing a * Commander game against the Computer, if that helps. - * + *

* Edit: It's not letting me cast fused spells for free. Others seems to be * working. */ @Test public void testCastingFusedSpell() { setStrictChooseMode(true); - + addCard(Zone.BATTLEFIELD, playerA, "Omniscience"); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); @@ -221,7 +221,7 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { setChoice(playerA, true); // Cast without paying its mana cost? addTarget(playerA, "Silvercoat Lion"); addTarget(playerA, playerB); - playerB.addTarget("Pillarfield Ox"); + setChoice(playerB, "Pillarfield Ox"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -234,7 +234,7 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { assertPermanentCount(playerB, "Pillarfield Ox", 0); assertGraveyardCount(playerB, "Pillarfield Ox", 1); } - + /** * Omniscience only lets you cast spells from your hand without paying their mana costs. @@ -312,11 +312,11 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { * If a spell has an unpayable cost (e.g. Ancestral Vision, which has no mana cost), * Omniscience should allow you to cast that spell without paying its mana cost. * In the case of Ancestral Vision, for example, Xmage only gives you the option to suspend Ancestral Vision. - * + *

* 118.6a If an unpayable cost is increased by an effect or an additional cost is imposed, - * the cost is still unpayable. - * If an alternative cost is applied to an unpayable cost, including an effect that allows a player - * to cast a spell without paying its mana cost, the alternative cost may be paid. + * the cost is still unpayable. + * If an alternative cost is applied to an unpayable cost, including an effect that allows a player + * to cast a spell without paying its mana cost, the alternative cost may be paid. */ @Test public void testCastingUnpayableCost() { @@ -343,30 +343,30 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase { // Not sure what the exact interaction is, but when Omniscience is on the field with Jodah, // if you say "no" to the Jodah cast option to get to the Omniscience option, then the game will initiate a rollback. - + @Test public void test_OmniscienceAndJodah() { setStrictChooseMode(true); - + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); - + // Flying // You may pay WUBRG rather than pay the mana cost for spells that you cast. addCard(Zone.BATTLEFIELD, playerA, "Jodah, Archmage Eternal"); // Creature {1}{U}{R}{W} (4/3) // You may cast nonland cards from your hand without paying their mana costs. addCard(Zone.HAND, playerA, "Omniscience"); // Enchantment {7}{U}{U}{U} - + // Creature - 3/3 Swampwalk addCard(Zone.HAND, playerA, "Bog Wraith", 1); // Creature {3}{B} (3/3) castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Omniscience", true); setChoice(playerA, true); // Pay alternative costs? ({W}{U}{B}{R}{G}) - + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bog Wraith"); // The order of the two alternate casting abilities is not fixed, so it's not clear which ability is asked for first setChoice(playerA, false); // Pay alternative costs? ({W}{U}{B}{R}{G}) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeSacrificedTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeSacrificedTest.java new file mode 100644 index 00000000000..f0dd48bbd56 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeSacrificedTest.java @@ -0,0 +1,117 @@ +package org.mage.test.cards.rules; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class CantBeSacrificedTest extends CardTestPlayerBase { + + private static final String assaultSuit = "Assault Suit"; + /* + Assault Suit {4} + Artifact — Equipment + Equipped creature gets +2/+2, has haste, can’t attack you or planeswalkers you control, and can’t be sacrificed. + At the beginning of each opponent’s upkeep, you may have that player gain control of equipped creature until end of turn. If you do, untap it. + Equip {3} + */ + + private static final String allSac = "Innocent Blood"; + // Sorcery {B} Each player sacrifices a creature. + + private static final String urchin = "Bile Urchin"; + // Creature — Spirit {B} Sacrifice Bile Urchin: Target player loses 1 life. + + private static final String zombie = "Walking Corpse"; // 2/2 vanilla + private static final String vampire = "Barony Vampire"; // 3/2 vanilla + + private static final String bairn = "Blood Bairn"; // Sacrifice another creature: ~ gets +2/+2 until EOT + + private static final String jonIren = "Jon Irenicus, Shattered One"; + // At the beginning of your end step, target opponent gains control of up to one target creature you control. + // Put two +1/+1 counters on it and tap it. It’s goaded for the rest of the game and it gains “This creature can’t be sacrificed.” + + @Test + public void testAssaultSuitWithSacEffect() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + addCard(Zone.BATTLEFIELD, playerA, zombie); + addCard(Zone.BATTLEFIELD, playerA, assaultSuit); + addCard(Zone.BATTLEFIELD, playerB, vampire); + addCard(Zone.HAND, playerA, allSac); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", zombie); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, allSac); + setChoice(playerB, vampire); // to sacrifice (player A can't) + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, zombie, 1); + assertGraveyardCount(playerB, vampire, 1); + } + + @Test + public void testAssaultSuitWithSacSourceCost() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.BATTLEFIELD, playerA, urchin); + addCard(Zone.BATTLEFIELD, playerA, assaultSuit); + + checkPlayableAbility("Can sacrifice", 1, PhaseStep.UPKEEP, playerA, "Sacrifice ", true); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", urchin); + checkPlayableAbility("Can't sacrifice", 1, PhaseStep.BEGIN_COMBAT, playerA, "Sacrifice ", false); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAttachedTo(playerA, assaultSuit, urchin, true); + } + + @Test + public void testAssaultSuitWithSacAnotherCost() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.BATTLEFIELD, playerA, zombie); + addCard(Zone.BATTLEFIELD, playerA, bairn); + addCard(Zone.BATTLEFIELD, playerA, assaultSuit); + + checkPlayableAbility("Can sacrifice", 1, PhaseStep.UPKEEP, playerA, "Sacrifice another", true); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", zombie); + checkPlayableAbility("Can't sacrifice", 1, PhaseStep.BEGIN_COMBAT, playerA, "Sacrifice another", false); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertAttachedTo(playerA, assaultSuit, zombie, true); + assertPowerToughness(playerA, bairn, 2, 2); + } + + @Test + public void testJonIrenicusWithSacSourceCost() { + addCard(Zone.BATTLEFIELD, playerA, urchin); + addCard(Zone.BATTLEFIELD, playerA, jonIren); + + checkPlayableAbility("Can sacrifice", 1, PhaseStep.UPKEEP, playerA, "Sacrifice ", true); + checkPlayableAbility("Can't sacrifice", 1, PhaseStep.UPKEEP, playerB, "Sacrifice ", false); + + addTarget(playerA, playerB); // target opponent gains control + addTarget(playerA, urchin); // of up to one target creature you control + + checkPlayableAbility("Can't sacrifice", 2, PhaseStep.UPKEEP, playerA, "Sacrifice ", false); + checkPlayableAbility("Can't sacrifice", 2, PhaseStep.UPKEEP, playerB, "Sacrifice ", false); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPermanentCount(playerB, urchin, 1); + assertCounterCount(urchin, CounterType.P1P1, 2); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/MyrkulsEdictTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/MyrkulsEdictTest.java index a20c04add20..f033375c4f4 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/MyrkulsEdictTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/MyrkulsEdictTest.java @@ -38,7 +38,7 @@ public class MyrkulsEdictTest extends CardTestPlayerBase { setDieRollResult(playerA, 1); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, myrkulsEdict); addTarget(playerA, playerB); - addTarget(playerB, "Silvercoat Lion"); + setChoice(playerB, "Silvercoat Lion"); execute(); @@ -56,7 +56,7 @@ public class MyrkulsEdictTest extends CardTestPlayerBase { setDieRollResult(playerA, 11); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, myrkulsEdict); - addTarget(playerB, "Silvercoat Lion"); + setChoice(playerB, "Silvercoat Lion"); execute(); @@ -76,7 +76,7 @@ public class MyrkulsEdictTest extends CardTestPlayerBase { setDieRollResult(playerA, 20); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, myrkulsEdict); - addTarget(playerB, "Aesi, Tyrant of Gyre Strait"); + setChoice(playerB, "Aesi, Tyrant of Gyre Strait"); execute(); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ltr/WitchKingOfAngmarTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ltr/WitchKingOfAngmarTest.java index 19a83cdcf20..46930ca643c 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ltr/WitchKingOfAngmarTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ltr/WitchKingOfAngmarTest.java @@ -31,7 +31,7 @@ public class WitchKingOfAngmarTest extends CardTestPlayerBase { attack(2, playerB, watchwolf); attack(2, playerB, swallower); checkStackObject("Sacrifice trigger check", 2, PhaseStep.COMBAT_DAMAGE, playerB, "Whenever one or more creatures deal combat damage to you", 1); - addTarget(playerB, watchwolf); // choose which creature to sacrifice + setChoice(playerB, watchwolf); // choose which creature to sacrifice runCode("check ring bear", 2, PhaseStep.POSTCOMBAT_MAIN, playerA, (info, player, game) -> { Assert.assertNotNull(playerA.getRingBearer(game)); @@ -67,4 +67,4 @@ public class WitchKingOfAngmarTest extends CardTestPlayerBase { assertAbility(playerA, witchKing, IndestructibleAbility.getInstance(), false); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/stx/DaemogothTitanTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/stx/DaemogothTitanTest.java index 5e41c55700a..2f4be6b1f2e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/stx/DaemogothTitanTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/stx/DaemogothTitanTest.java @@ -17,7 +17,7 @@ public class DaemogothTitanTest extends CardTestPlayerBaseWithAIHelps { addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1); attack(1, playerA, "Daemogoth Titan"); - addTarget(playerA, "Grizzly Bears"); + setChoice(playerA, "Grizzly Bears"); setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/DealsCombatDamageTriggerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/DealsCombatDamageTriggerTest.java index ec876e631e0..d510e9d9880 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/DealsCombatDamageTriggerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/damage/DealsCombatDamageTriggerTest.java @@ -21,7 +21,7 @@ public class DealsCombatDamageTriggerTest extends CardTestPlayerBase { attack(1, playerA, drinker, playerB); - addTarget(playerA, memnite); // to sacrifice + setChoice(playerA, memnite); // to sacrifice setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); @@ -56,8 +56,8 @@ public class DealsCombatDamageTriggerTest extends CardTestPlayerBase { attack(1, playerA, drinker, playerB); setChoice(playerA, "Whenever"); // order identical triggers - addTarget(playerA, drinker); // to sacrifice - addTarget(playerA, drinker); // to sacrifice + setChoice(playerA, drinker); // to sacrifice + setChoice(playerA, drinker); // to sacrifice setStrictChooseMode(true); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/OmnathLocusOfRageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/OmnathLocusOfRageTest.java index 2997367001d..a3392ccdf90 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/OmnathLocusOfRageTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/OmnathLocusOfRageTest.java @@ -29,7 +29,7 @@ public class OmnathLocusOfRageTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Diabolic Edict"); addTarget(playerB, playerA); - addTarget(playerA, "Omnath, Locus of Rage"); // sacrifice target + setChoice(playerA, "Omnath, Locus of Rage"); // sacrifice target addTarget(playerA, playerB); // target for dies trigger with damage setStrictChooseMode(true); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SilumgarScavengerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SilumgarScavengerTest.java index 13d33efbeb0..b72d221f481 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SilumgarScavengerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/SilumgarScavengerTest.java @@ -24,7 +24,7 @@ public class SilumgarScavengerTest extends CardTestPlayerBase { // cast and exploit castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silumgar Scavenger"); setChoice(playerA, true); // yes, exploit - addTarget(playerA, "Balduvian Bears"); + setChoice(playerA, "Balduvian Bears"); checkPermanentCounters("boost", 1, PhaseStep.BEGIN_COMBAT, playerA, "Silumgar Scavenger", CounterType.P1P1, 1); checkAbility("boost", 1, PhaseStep.BEGIN_COMBAT, playerA, "Silumgar Scavenger", HasteAbility.class, true); diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java index 0ddbc8d049b..973349efcf7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CastCommanderTest.java @@ -77,7 +77,7 @@ public class CastCommanderTest extends CardTestCommanderDuelBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Patron of the Orochi"); setChoice(playerA, true); - addTarget(playerA, "Coiled Tinviper"); + setChoice(playerA, "Coiled Tinviper"); setStrictChooseMode(true); diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java index 82f0b0bd2b4..bdf27bf3f44 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAllCost.java @@ -50,10 +50,7 @@ public class SacrificeAllCost extends CostImpl implements SacrificeCost { if (ability.getAbilityType() == AbilityType.ACTIVATED || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { if (((ActivatedAbilityImpl) ability).getActivatorId() != null) { activator = ((ActivatedAbilityImpl) ability).getActivatorId(); - } else { - // Aktivator not filled? - activator = controllerId; - } + } // else, Activator not filled? } for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controllerId, game)) { diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachmentCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachmentCost.java index 68f15f360c0..1764caf2bba 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachmentCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeAttachmentCost.java @@ -47,6 +47,14 @@ public class SacrificeAttachmentCost extends UseAttachedCost implements Sacrific return paid; } + @Override + public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) { + if (!super.canPay(ability, source, controllerId, game)) { + return false; + } + return game.getPermanent(source.getSourceId()).canBeSacrificed(); + } + @Override public SacrificeAttachmentCost copy() { return new SacrificeAttachmentCost(this); diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java index 9e11530ab48..a03e672b220 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java @@ -7,10 +7,12 @@ import mage.abilities.costs.CostImpl; import mage.abilities.costs.SacrificeCost; import mage.constants.AbilityType; import mage.constants.Outcome; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.ArrayList; @@ -24,20 +26,32 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost { private final List permanents = new ArrayList<>(); - public SacrificeTargetCost(FilterControlledPermanent filter) { - this(new TargetControlledPermanent(filter)); + /** + * Sacrifice a permanent matching the filter: + * @param filter can be generic, will automatically add article and sacrifice predicates + */ + public SacrificeTargetCost(FilterPermanent filter) { + this(1, filter); } + /** + * Sacrifice N permanents matching the filter: + * @param filter can be generic, will automatically add sacrifice predicates + */ + public SacrificeTargetCost(int numToSac, FilterPermanent filter) { + this(new TargetSacrifice(numToSac, filter)); + } + + // remove once merge complete + @Deprecated public SacrificeTargetCost(TargetControlledPermanent target) { + throw new UnsupportedOperationException("Wrong code usage, refactor to TargetSacrifice"); + } + + public SacrificeTargetCost(TargetSacrifice target) { this.addTarget(target); - target.withNotTarget(true); // sacrifice is never targeted target.setRequired(false); // can be canceled this.text = "sacrifice " + makeText(target); - target.setTargetName(target.getTargetName() + " (to sacrifice)"); - } - - public SacrificeTargetCost(TargetControlledPermanent target, boolean noText) { - this.addTarget(target); } public SacrificeTargetCost(SacrificeTargetCost cost) { @@ -70,6 +84,9 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost { return paid; } + /** + * For storing additional info upon selecting permanents to sacrifice + */ protected void addSacrificeTarget(Game game, Permanent permanent) { permanents.add(permanent.copy()); } @@ -80,18 +97,15 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost { if (ability.getAbilityType() == AbilityType.ACTIVATED || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) { if (((ActivatedAbilityImpl) ability).getActivatorId() != null) { activator = ((ActivatedAbilityImpl) ability).getActivatorId(); - } else { - // Activator not filled? - activator = controllerId; - } + } // else, Activator not filled? } int validTargets = 0; - int neededtargets = this.getTargets().get(0).getNumberOfTargets(); - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(((TargetControlledPermanent) this.getTargets().get(0)).getFilter(), controllerId, game)) { + int neededTargets = this.getTargets().get(0).getNumberOfTargets(); + for (Permanent permanent : game.getBattlefield().getActivePermanents(((TargetPermanent) this.getTargets().get(0)).getFilter(), controllerId, source, game)) { if (game.getPlayer(activator).canPaySacrificeCost(permanent, source, controllerId, game)) { validTargets++; - if (validTargets >= neededtargets) { + if (validTargets >= neededTargets) { return true; } } @@ -112,7 +126,7 @@ public class SacrificeTargetCost extends CostImpl implements SacrificeCost { return permanents; } - private static String makeText(TargetControlledPermanent target) { + private static String makeText(TargetSacrifice target) { if (target.getMinNumberOfTargets() != target.getMaxNumberOfTargets()) { return target.getTargetName(); } diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeXTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeXTargetCost.java index 08ed86ae02a..816abe9b534 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeXTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeXTargetCost.java @@ -5,28 +5,27 @@ import mage.abilities.costs.Cost; import mage.abilities.costs.SacrificeCost; import mage.abilities.costs.VariableCostImpl; import mage.abilities.costs.VariableCostType; -import mage.filter.Filter; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterPermanent; import mage.game.Game; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @author LevelX2 */ public class SacrificeXTargetCost extends VariableCostImpl implements SacrificeCost { - protected final FilterControlledPermanent filter; + protected final FilterPermanent filter; private final int minValue; - public SacrificeXTargetCost(FilterControlledPermanent filter) { + public SacrificeXTargetCost(FilterPermanent filter) { this(filter, false); } - public SacrificeXTargetCost(FilterControlledPermanent filter, boolean useAsAdditionalCost) { + public SacrificeXTargetCost(FilterPermanent filter, boolean useAsAdditionalCost) { this(filter, useAsAdditionalCost, 0); } - public SacrificeXTargetCost(FilterControlledPermanent filter, boolean useAsAdditionalCost, int minValue) { + public SacrificeXTargetCost(FilterPermanent filter, boolean useAsAdditionalCost, int minValue) { super(useAsAdditionalCost ? VariableCostType.ADDITIONAL : VariableCostType.NORMAL, filter.getMessage() + " to sacrifice"); this.text = (useAsAdditionalCost ? "as an additional cost to cast this spell, sacrifice " : "Sacrifice ") + xText + ' ' + filter.getMessage(); @@ -57,11 +56,10 @@ public class SacrificeXTargetCost extends VariableCostImpl implements SacrificeC @Override public Cost getFixedCostsFromAnnouncedValue(int xValue) { - TargetControlledPermanent target = new TargetControlledPermanent(xValue, xValue, filter, true); - return new SacrificeTargetCost(target); + return new SacrificeTargetCost(new TargetSacrifice(xValue, filter)); } - public Filter getFilter() { + public FilterPermanent getFilter() { return filter; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java index 690241b659f..f1981ced017 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/DevourEffect.java @@ -15,7 +15,7 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.ArrayList; @@ -88,8 +88,7 @@ public class DevourEffect extends ReplacementEffectImpl { } filter.add(AnotherPredicate.instance); - Target target = new TargetControlledPermanent(1, Integer.MAX_VALUE, filter, true); - target.setRequired(false); + Target target = new TargetSacrifice(1, Integer.MAX_VALUE, filter); if (!target.canChoose(source.getControllerId(), source, game)) { return false; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PlayerToRightGainsControlOfSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PlayerToRightGainsControlOfSourceEffect.java new file mode 100644 index 00000000000..713c61fb410 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/PlayerToRightGainsControlOfSourceEffect.java @@ -0,0 +1,53 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author xenohedron + */ +public class PlayerToRightGainsControlOfSourceEffect extends OneShotEffect { + + public PlayerToRightGainsControlOfSourceEffect() { + super(Outcome.Detriment); + this.staticText = "the player to your right gains control of {this}"; + } + + protected PlayerToRightGainsControlOfSourceEffect(final PlayerToRightGainsControlOfSourceEffect effect) { + super(effect); + } + + @Override + public PlayerToRightGainsControlOfSourceEffect copy() { + return new PlayerToRightGainsControlOfSourceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = source.getSourcePermanentIfItStillExists(game); + if (permanent == null) { + return true; + } + UUID playerToRightId = game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .reduce((u1, u2) -> u2) + .orElse(null); + if (playerToRightId == null) { + return false; + } + game.addEffect(new GainControlTargetEffect( + Duration.Custom, true, playerToRightId + ).setTargetPointer(new FixedTarget(permanent, game)), source); + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeAllEffect.java index 71c2247c6d3..02eaf42c17d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeAllEffect.java @@ -5,15 +5,15 @@ import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; /** @@ -21,21 +21,42 @@ import java.util.UUID; */ public class SacrificeAllEffect extends OneShotEffect { - protected DynamicValue amount; - protected FilterControlledPermanent filter; + private final DynamicValue amount; + private final FilterPermanent filter; + private final boolean onlyOpponents; - public SacrificeAllEffect(FilterControlledPermanent filter) { + /** + * Each player sacrifices a permanent + * @param filter can be generic, will automatically add article and necessary sacrifice predicates + */ + public SacrificeAllEffect(FilterPermanent filter) { this(1, filter); } - public SacrificeAllEffect(int amount, FilterControlledPermanent filter) { + /** + * Each player sacrifices N permanents + * @param filter can be generic, will automatically add necessary sacrifice predicates + */ + public SacrificeAllEffect(int amount, FilterPermanent filter) { this(StaticValue.get(amount), filter); } - public SacrificeAllEffect(DynamicValue amount, FilterControlledPermanent filter) { + /** + * Each player sacrifices X permanents + * @param filter can be generic, will automatically add necessary sacrifice predicates + */ + public SacrificeAllEffect(DynamicValue amount, FilterPermanent filter) { + this(amount, filter, false); + } + + /** + * Internal use for this and SacrificeOpponentsEffect + */ + protected SacrificeAllEffect(DynamicValue amount, FilterPermanent filter, boolean onlyOpponents) { super(Outcome.Sacrifice); this.amount = amount; this.filter = filter; + this.onlyOpponents = onlyOpponents; setText(); } @@ -43,6 +64,7 @@ public class SacrificeAllEffect extends OneShotEffect { super(effect); this.amount = effect.amount; this.filter = effect.filter.copy(); + this.onlyOpponents = effect.onlyOpponents; } @Override @@ -52,24 +74,27 @@ public class SacrificeAllEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { + int num = amount.calculate(game, source, this); + if (num < 1) { return false; } - - List perms = new ArrayList<>(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Set perms = new HashSet<>(); + for (UUID playerId : onlyOpponents ? + game.getOpponents(source.getControllerId()) : + game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - if (player != null) { - int numTargets = Math.min(amount.calculate(game, source, this), game.getBattlefield().countAll(filter, player.getId(), game)); - TargetControlledPermanent target = new TargetControlledPermanent(numTargets, numTargets, filter, true); - if (target.canChoose(player.getId(), source, game)) { - while (!target.isChosen() && player.canRespond()) { - player.choose(Outcome.Sacrifice, target, source, game); - } - perms.addAll(target.getTargets()); - } + if (player == null) { + continue; } + int numTargets = Math.min(num, game.getBattlefield().count(TargetSacrifice.makeFilter(filter), player.getId(), source, game)); + if (numTargets < 1) { + continue; + } + TargetSacrifice target = new TargetSacrifice(numTargets, filter); + while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) { + player.choose(Outcome.Sacrifice, target, source, game); + } + perms.addAll(target.getTargets()); } for (UUID permID : perms) { Permanent permanent = game.getPermanent(permID); @@ -82,17 +107,20 @@ public class SacrificeAllEffect extends OneShotEffect { private void setText() { StringBuilder sb = new StringBuilder(); - sb.append("each player sacrifices "); - if (amount.toString().equals("X")) { - sb.append(amount.toString()); - sb.append(' '); - sb.append(filter.getMessage()); - } else if (amount.toString().equals("1")) { - sb.append(CardUtil.addArticle(filter.getMessage())); - } else { - sb.append(CardUtil.numberToText(amount.toString(), "a")); - sb.append(' '); - sb.append(filter.getMessage()); + sb.append(onlyOpponents ? "each opponent sacrifices " : "each player sacrifices "); + switch (amount.toString()) { + case "X": + sb.append(amount.toString()); + sb.append(' '); + sb.append(filter.getMessage()); + break; + case "1": + sb.append(CardUtil.addArticle(filter.getMessage())); + break; + default: + sb.append(CardUtil.numberToText(amount.toString(), "a")); + sb.append(' '); + sb.append(filter.getMessage()); } staticText = sb.toString(); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeEffect.java index 9fd9f97968e..8da2ede2e05 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeEffect.java @@ -6,12 +6,10 @@ import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; import mage.filter.FilterPermanent; -import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; -import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.UUID; @@ -21,14 +19,20 @@ import java.util.UUID; */ public class SacrificeEffect extends OneShotEffect { - private FilterPermanent filter; - private String preText; + private final FilterPermanent filter; + private final String preText; private DynamicValue count; + /** + * Target player sacrifices N permanents matching the filter + */ public SacrificeEffect(FilterPermanent filter, int count, String preText) { this(filter, StaticValue.get(count), preText); } + /** + * Target player sacrifices X permanents matching the filter + */ public SacrificeEffect(FilterPermanent filter, DynamicValue count, String preText) { super(Outcome.Sacrifice); this.filter = filter; @@ -49,26 +53,24 @@ public class SacrificeEffect extends OneShotEffect { boolean applied = false; for (UUID playerId : targetPointer.getTargets(game, source)) { Player player = game.getPlayer(playerId); - if (player != null) { - FilterPermanent newFilter = filter.copy(); // filter can be static, so it's important to copy here - newFilter.add(new ControllerIdPredicate(player.getId())); - int amount = count.calculate(game, source, this); - int realCount = game.getBattlefield().countAll(newFilter, player.getId(), game); - amount = Math.min(amount, realCount); - Target target = new TargetPermanent(amount, amount, newFilter, true); - if (amount > 0 && target.canChoose(player.getId(), source, game)) { - while (!target.isChosen() - && target.canChoose(player.getId(), source, game) - && player.canRespond()) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); - } - for (int idx = 0; idx < target.getTargets().size(); idx++) { - Permanent permanent = game.getPermanent(target.getTargets().get(idx)); - if (permanent != null - && permanent.sacrifice(source, game)) { - applied = true; - } - } + if (player == null) { + continue; + } + int amount = Math.min( + count.calculate(game, source, this), + game.getBattlefield().count(TargetSacrifice.makeFilter(filter), player.getId(), source, game) + ); + if (amount < 1) { + continue; + } + TargetSacrifice target = new TargetSacrifice(amount, filter); + while (!target.isChosen() && target.canChoose(player.getId(), source, game) && player.canRespond()) { + player.choose(Outcome.Sacrifice, target, source, game); + } + for (UUID targetId : target.getTargets()) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null && permanent.sacrifice(source, game)) { + applied = true; } } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsEffect.java index 6e5d6dd04e7..4dbb5e0628a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsEffect.java @@ -1,52 +1,37 @@ package mage.abilities.effects.common; -import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Outcome; -import mage.constants.TargetController; import mage.filter.FilterPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.TargetPermanent; -import mage.util.CardUtil; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * All opponents have to sacrifice [amount] permanents that match the [filter]. - * - * @author LevelX2 - */ -public class SacrificeOpponentsEffect extends OneShotEffect { - - protected DynamicValue amount; - protected FilterPermanent filter; +public class SacrificeOpponentsEffect extends SacrificeAllEffect { + /** + * Each opponent sacrifices a permanent + * @param filter can be generic, will automatically add article and necessary sacrifice predicates + */ public SacrificeOpponentsEffect(FilterPermanent filter) { this(1, filter); } + /** + * Each opponent sacrifices N permanents + * @param filter can be generic, will automatically add necessary sacrifice predicates + */ public SacrificeOpponentsEffect(int amount, FilterPermanent filter) { this(StaticValue.get(amount), filter); } + /** + * Each opponent sacrifices X permanents + * @param filter can be generic, will automatically add necessary sacrifice predicates + */ public SacrificeOpponentsEffect(DynamicValue amount, FilterPermanent filter) { - super(Outcome.Sacrifice); - this.amount = amount; - this.filter = filter.copy(); - this.filter.add(TargetController.YOU.getControllerPredicate()); + super(amount, filter, true); } protected SacrificeOpponentsEffect(final SacrificeOpponentsEffect effect) { super(effect); - this.amount = effect.amount; - this.filter = effect.filter.copy(); } @Override @@ -54,48 +39,4 @@ public class SacrificeOpponentsEffect extends OneShotEffect { return new SacrificeOpponentsEffect(this); } - @Override - public boolean apply(Game game, Ability source) { - List perms = new ArrayList<>(); - for (UUID playerId : game.getOpponents(source.getControllerId())) { - Player player = game.getPlayer(playerId); - if (player != null) { - int numTargets = Math.min(amount.calculate(game, source, this), game.getBattlefield().countAll(filter, player.getId(), game)); - if (numTargets > 0) { - TargetPermanent target = new TargetPermanent(numTargets, numTargets, filter, true); - if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); - perms.addAll(target.getTargets()); - } - } - } - } - for (UUID permID : perms) { - Permanent permanent = game.getPermanent(permID); - if (permanent != null) { - permanent.sacrifice(source, game); - } - } - return true; - } - - @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { - return staticText; - } - StringBuilder sb = new StringBuilder(); - sb.append("each opponent sacrifices "); - switch (amount.toString()) { - case "X": - sb.append(amount.toString()).append(' '); - break; - case "1": - sb.append(CardUtil.addArticle(filter.getMessage())); - break; - default: - sb.append(CardUtil.numberToText(amount.toString())).append(' ').append(filter.getMessage()); - } - return sb.toString(); - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsUnlessPayEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsUnlessPayEffect.java index 54755902e96..841164a7b29 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsUnlessPayEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeOpponentsUnlessPayEffect.java @@ -1,26 +1,21 @@ package mage.abilities.effects.common; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCost; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; -import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; -import mage.util.ManaUtil; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; /** @@ -60,45 +55,41 @@ public class SacrificeOpponentsUnlessPayEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - List permsToSacrifice = new ArrayList<>(); - filter.add(TargetController.YOU.getControllerPredicate()); + Set permsToSacrifice = new HashSet<>(); for (UUID playerId : game.getOpponents(source.getControllerId())) { Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } - if (player != null) { - Cost costToPay = cost.copy(); - String costValueMessage = costToPay.getText(); - String message = ((costToPay instanceof ManaCost) ? "Pay " : "") + costValueMessage + '?'; + Cost costToPay = cost.copy(); + String costValueMessage = costToPay.getText(); + String message = ((costToPay instanceof ManaCost) ? "Pay " : "") + costValueMessage + '?'; - costToPay.clearPaid(); - if (!(player.chooseUse(Outcome.Benefit, message, source, game) - && costToPay.pay(source, game, source, player.getId(), false, null))) { - game.informPlayers(player.getLogName() + " chooses not to pay " + costValueMessage + " to prevent the sacrifice effect"); + costToPay.clearPaid(); + if (!(player.chooseUse(Outcome.Benefit, message, source, game) + && costToPay.pay(source, game, source, player.getId(), false, null))) { + game.informPlayers(player.getLogName() + " chooses not to pay " + costValueMessage + " to prevent the sacrifice effect"); - int numTargets = Math.min(1, game.getBattlefield().countAll(filter, player.getId(), game)); - if (numTargets > 0) { - TargetPermanent target = new TargetPermanent(numTargets, numTargets, filter, true); - - if (target.canChoose(player.getId(), source, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); - permsToSacrifice.addAll(target.getTargets()); - } + if (game.getBattlefield().count(TargetSacrifice.makeFilter(filter), player.getId(), source, game) > 0) { + TargetSacrifice target = new TargetSacrifice(1, filter); + if (target.canChoose(player.getId(), source, game)) { + player.choose(Outcome.Sacrifice, target, source, game); + permsToSacrifice.addAll(target.getTargets()); } - } else { - game.informPlayers(player.getLogName() + " chooses to pay " + costValueMessage + " to prevent the sacrifice effect"); } + } else { + game.informPlayers(player.getLogName() + " chooses to pay " + costValueMessage + " to prevent the sacrifice effect"); } } for (UUID permID : permsToSacrifice) { Permanent permanent = game.getPermanent(permID); - if (permanent != null) { permanent.sacrifice(source, game); } } - return true; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessConditionEffect.java b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessConditionEffect.java index 70f9272ee42..5ba8950f127 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessConditionEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/SacrificeSourceUnlessConditionEffect.java @@ -1,8 +1,6 @@ - package mage.abilities.effects.common; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.condition.Condition; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; @@ -20,6 +18,7 @@ public class SacrificeSourceUnlessConditionEffect extends OneShotEffect { public SacrificeSourceUnlessConditionEffect(Condition condition) { super(Outcome.Sacrifice); this.condition = condition; + this.staticText = "sacrifice {this} unless " + condition.toString(); } protected SacrificeSourceUnlessConditionEffect(final SacrificeSourceUnlessConditionEffect effect) { @@ -46,13 +45,4 @@ public class SacrificeSourceUnlessConditionEffect extends OneShotEffect { return new SacrificeSourceUnlessConditionEffect(this); } - @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { - return staticText; - } - StringBuilder sb = new StringBuilder("sacrifice {this} unless "); - sb.append(condition.toString()); - return sb.toString(); - } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java new file mode 100644 index 00000000000..447767db12a --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/CantBeSacrificedSourceEffect.java @@ -0,0 +1,45 @@ +package mage.abilities.effects.common.continuous; + +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * @author xenohedron + */ +public class CantBeSacrificedSourceEffect extends ContinuousEffectImpl { + + public CantBeSacrificedSourceEffect() { + super(Duration.WhileOnBattlefield, Layer.RulesEffects, SubLayer.NA, Outcome.Benefit); + staticText = "{this} can't be sacrificed"; + } + + protected CantBeSacrificedSourceEffect(final CantBeSacrificedSourceEffect effect) { + super(effect); + } + + @Override + public CantBeSacrificedSourceEffect copy() { + return new CantBeSacrificedSourceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentEntering(source.getSourceId()); + if (permanent == null) { + permanent = source.getSourcePermanentIfItStillExists(game); + } + if (permanent == null) { + discard(); + return false; + } + permanent.setCanBeSacrificed(false); + return true; + } + +} diff --git a/Mage/src/main/java/mage/abilities/keyword/AnnihilatorAbility.java b/Mage/src/main/java/mage/abilities/keyword/AnnihilatorAbility.java index a7d7799292d..343f17f0a8a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/AnnihilatorAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/AnnihilatorAbility.java @@ -1,20 +1,14 @@ - package mage.abilities.keyword; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Outcome; +import mage.abilities.effects.common.SacrificeEffect; import mage.constants.Zone; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; -import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetControlledPermanent; +import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; -import java.util.Objects; import java.util.UUID; /** @@ -29,16 +23,17 @@ import java.util.UUID; */ public class AnnihilatorAbility extends TriggeredAbilityImpl { - int count; + String rule; public AnnihilatorAbility(int count) { - super(Zone.BATTLEFIELD, new AnnihilatorEffect(count), false); - this.count = count; + super(Zone.BATTLEFIELD, new SacrificeEffect(StaticFilters.FILTER_CONTROLLED_PERMANENTS, count, ""), false); + this.rule = "Annihilator " + count + " (Whenever this creature attacks, defending player sacrifices " + + (count == 1 ? "a permanent" : CardUtil.numberToText(count) + " permanents") + ".)"; } protected AnnihilatorAbility(final AnnihilatorAbility ability) { super(ability); - this.count = ability.count; + this.rule = ability.rule; } @Override @@ -52,9 +47,7 @@ public class AnnihilatorAbility extends TriggeredAbilityImpl { UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(sourceId, game); if (defendingPlayerId != null) { // the id has to be set here because the source can be leave battlefield - getEffects().forEach((effect) -> { - effect.setValue("defendingPlayerId", defendingPlayerId); - }); + getEffects().setTargetPointer(new FixedTarget(defendingPlayerId)); return true; } } @@ -63,8 +56,7 @@ public class AnnihilatorAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Annihilator " + count + " (Whenever this creature attacks, defending player sacrifices " - + (count == 1 ? "a permanent" : CardUtil.numberToText(count) + " permanents") + ".)"; + return rule; } @Override @@ -73,52 +65,3 @@ public class AnnihilatorAbility extends TriggeredAbilityImpl { } } - -class AnnihilatorEffect extends OneShotEffect { - - private final int count; - - AnnihilatorEffect(int count) { - super(Outcome.Sacrifice); - this.count = count; - } - - AnnihilatorEffect(AnnihilatorEffect effect) { - super(effect); - this.count = effect.count; - } - - @Override - public boolean apply(Game game, Ability source) { - UUID defendingPlayerId = (UUID) getValue("defendingPlayerId"); - Player player = null; - if (defendingPlayerId != null) { - player = game.getPlayer(defendingPlayerId); - } - if (player != null) { - int amount = Math.min(count, game.getBattlefield().countAll(new FilterControlledPermanent(), player.getId(), game)); - if (amount > 0) { - Target target = new TargetControlledPermanent(amount, amount, new FilterControlledPermanent(), true); - if (target.canChoose(player.getId(), source, game)) { - while (player.canRespond() - && target.canChoose(player.getId(), source, game) - && !target.isChosen()) { - player.choose(Outcome.Sacrifice, target, source, game); - } - target.getTargets().stream() - .map(game::getPermanent) - .filter(Objects::nonNull) - .forEach(permanent -> permanent.sacrifice(source, game)); - } - return true; - } - } - return false; - } - - @Override - public AnnihilatorEffect copy() { - return new AnnihilatorEffect(this); - } - -} diff --git a/Mage/src/main/java/mage/abilities/keyword/CasualtyAbility.java b/Mage/src/main/java/mage/abilities/keyword/CasualtyAbility.java index 34db19115d9..367895d55b8 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CasualtyAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CasualtyAbility.java @@ -15,7 +15,7 @@ import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.PowerPredicate; import mage.game.Game; import mage.players.Player; -import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetSacrifice; /** * @author TheElk801, Alex-Vasile @@ -28,12 +28,12 @@ public class CasualtyAbility extends StaticAbility implements OptionalAdditional protected OptionalAdditionalCost additionalCost; - private static TargetControlledPermanent makeFilter(int number) { + private static TargetSacrifice makeFilter(int number) { FilterControlledPermanent filter = new FilterControlledCreaturePermanent( "creature with power " + number + " or greater" ); filter.add(new PowerPredicate(ComparisonType.MORE_THAN, number - 1)); - return new TargetControlledPermanent(1, 1, filter, true); + return new TargetSacrifice(1, filter); } public CasualtyAbility(int number) { diff --git a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java index edca1496a78..9ef64914e17 100644 --- a/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/EmergeAbility.java @@ -12,12 +12,14 @@ import mage.cards.Card; import mage.constants.Outcome; import mage.constants.SpellAbilityType; import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.CanBeSacrificedPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetPermanent; -import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetSacrifice; import mage.util.CardUtil; import java.util.UUID; @@ -30,6 +32,11 @@ public class EmergeAbility extends SpellAbility { private final ManaCosts emergeCost; public static final String EMERGE_ACTIVATION_CREATURE_REFERENCE = "emergeActivationMOR"; + private static final FilterPermanent SAC_FILTER = new FilterControlledCreaturePermanent(); + static { + SAC_FILTER.add(CanBeSacrificedPredicate.instance); + } + public EmergeAbility(Card card, String emergeString) { super(card.getSpellAbility()); this.emergeCost = new ManaCostsImpl<>(emergeString); @@ -56,7 +63,7 @@ public class EmergeAbility extends SpellAbility { Player controller = game.getPlayer(this.getControllerId()); if (controller != null) { for (Permanent creature : game.getBattlefield().getActivePermanents( - new FilterControlledCreaturePermanent(), this.getControllerId(), this, game)) { + SAC_FILTER, this.getControllerId(), this, game)) { ManaCost costToPay = CardUtil.reduceCost(emergeCost.copy(), creature.getManaValue()); if (costToPay.canPay(this, this, this.getControllerId(), game)) { return new ActivationStatus(new ApprovingObject(this, game)); @@ -91,7 +98,8 @@ public class EmergeAbility extends SpellAbility { public boolean activate(Game game, boolean noMana) { Player controller = game.getPlayer(this.getControllerId()); if (controller != null) { - TargetPermanent target = new TargetControlledCreaturePermanent(new FilterControlledCreaturePermanent("creature to sacrifice for emerge")); + TargetSacrifice target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE); + target.withChooseHint("to sacrifice for emerge"); if (controller.choose(Outcome.Sacrifice, target, this, game)) { Permanent creature = game.getPermanent(target.getFirstTarget()); if (creature != null) { diff --git a/Mage/src/main/java/mage/abilities/keyword/ExploitAbility.java b/Mage/src/main/java/mage/abilities/keyword/ExploitAbility.java index 6da15f0b19c..7f186a9670a 100644 --- a/Mage/src/main/java/mage/abilities/keyword/ExploitAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/ExploitAbility.java @@ -5,13 +5,13 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; -import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; -import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; /** * Exploit is the signature ability of the blue-black Silumgar clan. When a creature with exploit @@ -71,14 +71,13 @@ class ExploitEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Target target = new TargetPermanent(1, 1, new FilterControlledCreaturePermanent("creature to exploit"), true); + Target target = new TargetSacrifice(StaticFilters.FILTER_PERMANENT_A_CREATURE); + target.withChooseHint("to exploit"); if (target.canChoose(controller.getId(), source, game)) { - controller.chooseTarget(Outcome.Sacrifice, target, source, game); + controller.choose(Outcome.Sacrifice, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - if (permanent.sacrifice(source, game)) { - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLOITED_CREATURE, permanent.getId(), source, controller.getId())); - } + if (permanent != null && (permanent.sacrifice(source, game))) { + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLOITED_CREATURE, permanent.getId(), source, controller.getId())); } } return true; diff --git a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java index 055a616fd27..cd7ac510f7f 100644 --- a/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/OfferingAbility.java @@ -17,7 +17,7 @@ import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; -import mage.target.TargetPermanent; +import mage.target.common.TargetSacrifice; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; import mage.util.GameLog; @@ -175,8 +175,8 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl { Player player = game.getPlayer(source.getControllerId()); if (player != null && player.chooseUse(Outcome.Benefit, "Offer a " + filter.getMessage() + " to cast " + spellToCast.getName() + '?', source, game)) { - Target target = new TargetPermanent(1, 1, filter, true); - player.chooseTarget(Outcome.Sacrifice, target, source, game); + Target target = new TargetSacrifice(filter); + player.choose(Outcome.Sacrifice, target, source, game); if (!target.isChosen()) { return false; } diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/CanBeSacrificedPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/CanBeSacrificedPredicate.java new file mode 100644 index 00000000000..69bf72005d4 --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/CanBeSacrificedPredicate.java @@ -0,0 +1,17 @@ +package mage.filter.predicate.permanent; + +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * @author TheElk801 + */ +public enum CanBeSacrificedPredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.canBeSacrificed(); + } +} diff --git a/Mage/src/main/java/mage/game/command/dungeons/TombOfAnnihilationDungeon.java b/Mage/src/main/java/mage/game/command/dungeons/TombOfAnnihilationDungeon.java index 4ee8e01e808..c8760325509 100644 --- a/Mage/src/main/java/mage/game/command/dungeons/TombOfAnnihilationDungeon.java +++ b/Mage/src/main/java/mage/game/command/dungeons/TombOfAnnihilationDungeon.java @@ -22,6 +22,7 @@ import mage.players.Player; import mage.target.TargetPermanent; import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetDiscard; +import mage.target.common.TargetSacrifice; import java.util.*; @@ -162,7 +163,7 @@ class OublietteEffect extends OneShotEffect { } } -class OublietteTarget extends TargetControlledPermanent { +class OublietteTarget extends TargetSacrifice { private static final CardTypeAssignment cardTypeAssigner = new CardTypeAssignment( CardType.ARTIFACT, @@ -176,7 +177,7 @@ class OublietteTarget extends TargetControlledPermanent { } OublietteTarget(int numTargets) { - super(numTargets, numTargets, filter, true); + super(numTargets, filter); } private OublietteTarget(final OublietteTarget target) { @@ -263,4 +264,3 @@ class SandfallCellEffect extends OneShotEffect { return true; } } - diff --git a/Mage/src/main/java/mage/game/permanent/Permanent.java b/Mage/src/main/java/mage/game/permanent/Permanent.java index 3bc89050c19..b0d9696d4c8 100644 --- a/Mage/src/main/java/mage/game/permanent/Permanent.java +++ b/Mage/src/main/java/mage/game/permanent/Permanent.java @@ -101,6 +101,10 @@ public interface Permanent extends Card, Controllable { boolean isProtectedBy(UUID playerId); + void setCanBeSacrificed(boolean canBeSacrificed); + + boolean canBeSacrificed(); + void setCardNumber(String cid); void setExpansionSetCode(String expansionSetCode); diff --git a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java index 49282d45295..372d718588f 100644 --- a/Mage/src/main/java/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/main/java/mage/game/permanent/PermanentImpl.java @@ -72,6 +72,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { protected boolean manifested = false; protected boolean morphed = false; protected boolean ringBearerFlag = false; + protected boolean canBeSacrificed = true; protected int classLevel = 1; protected final Set goadingPlayers = new HashSet<>(); protected UUID originalControllerId; @@ -176,6 +177,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.manifested = permanent.manifested; this.createOrder = permanent.createOrder; this.prototyped = permanent.prototyped; + this.canBeSacrificed = permanent.canBeSacrificed; } @Override @@ -215,6 +217,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { this.goadingPlayers.clear(); this.loyaltyActivationsAvailable = 1; this.legendRuleApplies = true; + this.canBeSacrificed = true; } @Override @@ -1361,7 +1364,7 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { @Override public boolean sacrifice(Ability source, Game game) { //20091005 - 701.13 - if (isPhasedIn() && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SACRIFICE_PERMANENT, objectId, source, controllerId))) { + if (isPhasedIn() && canBeSacrificed && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SACRIFICE_PERMANENT, objectId, source, controllerId))) { // Commander replacement effect or Rest in Peace (exile instead of graveyard) in play does not prevent successful sacrifice // so the return value of the moveToZone is not taken into account here moveToZone(Zone.GRAVEYARD, source, game, false); @@ -1773,6 +1776,16 @@ public abstract class PermanentImpl extends CardImpl implements Permanent { return protectorId != null && protectorId.equals(playerId); } + @Override + public void setCanBeSacrificed(boolean canBeSacrificed) { + this.canBeSacrificed = canBeSacrificed; + } + + @Override + public boolean canBeSacrificed() { + return canBeSacrificed; + } + @Override public void setPairedCard(MageObjectReference pairedCard) { this.pairedPermanent = pairedCard; diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index b3b939d3295..1a8f3c3b0d9 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -4437,7 +4437,8 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public boolean canPaySacrificeCost(Permanent permanent, Ability source, UUID controllerId, Game game) { - return sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, controllerId, source, game); + return permanent.canBeSacrificed() && + (sacrificeCostFilter == null || !sacrificeCostFilter.match(permanent, controllerId, source, game)); } @Override diff --git a/Mage/src/main/java/mage/target/common/TargetSacrifice.java b/Mage/src/main/java/mage/target/common/TargetSacrifice.java new file mode 100644 index 00000000000..5316e9cfbd8 --- /dev/null +++ b/Mage/src/main/java/mage/target/common/TargetSacrifice.java @@ -0,0 +1,49 @@ +package mage.target.common; + +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.permanent.CanBeSacrificedPredicate; +import mage.target.TargetPermanent; + +/** + * @author TheElk801 + */ +public class TargetSacrifice extends TargetPermanent { + + public TargetSacrifice(FilterPermanent filter) { + this(1, filter); + } + + public TargetSacrifice(int numTargets, FilterPermanent filter) { + this(numTargets, numTargets, filter); + } + + public TargetSacrifice(int minNumTargets, int maxNumTargets, FilterPermanent filter) { + super(minNumTargets, maxNumTargets, makeFilter(filter), true); + this.withChooseHint("to sacrifice"); + } + + protected TargetSacrifice(final TargetSacrifice target) { + super(target); + } + + @Override + public TargetSacrifice copy() { + return new TargetSacrifice(this); + } + + /** + * Creates a new filter with necessary constraints for sacrificing + * @param filter input generic filter + * @return new filter with "you control" and CanBeSacrificedPredicate added + */ + public static FilterPermanent makeFilter(FilterPermanent filter) { + FilterPermanent newFilter = filter.copy(); + newFilter.add(TargetController.YOU.getControllerPredicate()); + newFilter.add(CanBeSacrificedPredicate.instance); + if (filter.getMessage().contains(" you control")) { + newFilter.setMessage(filter.getMessage().replace(" you control", "")); + } + return newFilter; + } +} diff --git a/Mage/src/main/java/mage/target/common/TargetControlledCreatureEachColor.java b/Mage/src/main/java/mage/target/common/TargetSacrificeCreatureEachColor.java similarity index 83% rename from Mage/src/main/java/mage/target/common/TargetControlledCreatureEachColor.java rename to Mage/src/main/java/mage/target/common/TargetSacrificeCreatureEachColor.java index e47df1e4de9..76b1ef0edf5 100644 --- a/Mage/src/main/java/mage/target/common/TargetControlledCreatureEachColor.java +++ b/Mage/src/main/java/mage/target/common/TargetSacrificeCreatureEachColor.java @@ -21,11 +21,11 @@ import java.util.stream.Collectors; /** * @author TheElk801 */ -public class TargetControlledCreatureEachColor extends TargetControlledPermanent { +public class TargetSacrificeCreatureEachColor extends TargetSacrifice { private final ColorAssignment colorAssigner; - private static final FilterControlledPermanent makeFilter(String colors) { + private static FilterControlledPermanent makeFilter(String colors) { List objectColors = Arrays.stream(colors.split("")) .map(ObjectColor::new) @@ -42,12 +42,12 @@ public class TargetControlledCreatureEachColor extends TargetControlledPermanent return filter; } - public TargetControlledCreatureEachColor(String colors) { + public TargetSacrificeCreatureEachColor(String colors) { super(colors.length(), makeFilter(colors)); colorAssigner = new ColorAssignment(colors.split("")); } - private TargetControlledCreatureEachColor(final TargetControlledCreatureEachColor target) { + private TargetSacrificeCreatureEachColor(final TargetSacrificeCreatureEachColor target) { super(target); this.colorAssigner = target.colorAssigner; } @@ -70,7 +70,7 @@ public class TargetControlledCreatureEachColor extends TargetControlledPermanent } @Override - public TargetControlledCreatureEachColor copy() { - return new TargetControlledCreatureEachColor(this); + public TargetSacrificeCreatureEachColor copy() { + return new TargetSacrificeCreatureEachColor(this); } }