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 <theelk801@gmail.com>
Co-authored-by: PurpleCrowbar <26198472+PurpleCrowbar@users.noreply.github.com>
This commit is contained in:
xenohedron 2023-12-31 14:10:37 -05:00 committed by GitHub
parent f28c5c4fc5
commit 9b3ff32a33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
699 changed files with 1837 additions and 1619 deletions

View file

@ -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<Permanent> 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<Permanent> targets;
targets = threats(abilityControllerId, source, origTarget.getFilter(), game, target.getTargets());
if (!outcome.isGood()) {

View file

@ -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

View file

@ -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());

View file

@ -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)) {

View file

@ -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);
}
}
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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());

View file

@ -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);
}

View file

@ -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());

View file

@ -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));
}

View file

@ -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);

View file

@ -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));
}

View file

@ -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);

View file

@ -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.

View file

@ -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;
}
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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
));

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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)
));
}

View file

@ -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)));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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<CardType> sacrificeTypes = new HashSet<>();
private final Set<CardType> 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");
}

View file

@ -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.

View file

@ -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()));

View file

@ -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));

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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)
));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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.

View file

@ -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);
}
}
}

View file

@ -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)
));
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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}.";
}
}
}

View file

@ -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)));
}

View file

@ -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);

View file

@ -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");

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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),

View file

@ -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));
}

View file

@ -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);
}
}
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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()
));

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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
));
}

View file

@ -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.

View file

@ -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));

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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
));
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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)
));
}

View file

@ -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?"
)));

View file

@ -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);
}

View file

@ -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)) {

View file

@ -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)) {

View file

@ -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);
}

View file

@ -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

View file

@ -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) {

View file

@ -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);

View file

@ -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) {

View file

@ -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
));
}

View file

@ -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);
}

View file

@ -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);

Some files were not shown because too many files have changed in this diff Show more