refactor: sacrifice permanent triggered abilities (#11655)

* refactor constructors in SacrificePermanentTriggeredAbility

enables general use

* refactor some custom classes

* reorder method signature, add docs

* refactor another batch of custom classes

* cleanup remaining custom classes
This commit is contained in:
xenohedron 2024-01-14 19:57:11 -05:00 committed by GitHub
parent d35fd4aa29
commit aa642324d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 320 additions and 1127 deletions

View file

@ -13,9 +13,7 @@ import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
@ -26,7 +24,6 @@ import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInExile;
import mage.target.common.TargetControlledPermanent;
import mage.util.CardUtil;
import java.util.UUID;
@ -59,7 +56,9 @@ public final class BagOfDevouring extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{B}");
// Whenever you sacrifice another nontoken artifact or creature, exile it.
this.addAbility(new SacrificePermanentTriggeredAbility(new ExileTargetForSourceEffect().setText("exile it"), filter, true));
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new ExileTargetForSourceEffect().setText("exile it"), filter,
TargetController.YOU, SetTargetPointer.PERMANENT, false));
// {2}, {T}, Sacrifice another artifact or creature: Draw a card.
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(2));

View file

@ -2,7 +2,7 @@ package mage.cards.b;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.common.TapSourceCost;
@ -15,13 +15,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -49,7 +46,10 @@ public final class BloodAspirant extends CardImpl {
this.toughness = new MageInt(1);
// Whenever you sacrifice a permanent, put a +1/+1 counter on Blood Aspirant.
this.addAbility(new BloodAspirantAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_PERMANENT
));
// {1}{R}, {T}, Sacrifice a creature or enchantment: Blood Aspirant deals 1 damage to target creature. That creature can't block this turn.
Ability ability = new SimpleActivatedAbility(
@ -72,34 +72,3 @@ public final class BloodAspirant extends CardImpl {
return new BloodAspirant(this);
}
}
class BloodAspirantAbility extends TriggeredAbilityImpl {
BloodAspirantAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
}
private BloodAspirantAbility(final BloodAspirantAbility ability) {
super(ability);
}
@Override
public BloodAspirantAbility copy() {
return new BloodAspirantAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId());
}
@Override
public String getRule() {
return "Whenever you sacrifice a permanent, put a +1/+1 counter on {this}.";
}
}

View file

@ -1,19 +1,19 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SacrificeAllTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
/**
*
* @author LevelX2
@ -23,7 +23,6 @@ public final class Bloodbriar extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(TargetController.YOU.getControllerPredicate());
filter.add(AnotherPredicate.instance);
}
@ -34,7 +33,9 @@ public final class Bloodbriar extends CardImpl {
this.toughness = new MageInt(3);
// Whenever you sacrifice another permanent, put a +1/+1 counter on Bloodbriar.
this.addAbility(new SacrificeAllTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter, TargetController.YOU, false));
this.addAbility(new SacrificePermanentTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter
));
}
private Bloodbriar(final Bloodbriar card) {

View file

@ -2,24 +2,20 @@ package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.card.ManaValueLessThanOrEqualToSourcePowerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
@ -48,7 +44,11 @@ public final class CarmenCruelSkymarcher extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever a player sacrifices a permanent, put a +1/+1 counter on Carmen, Cruel Skymarcher and you gain 1 life.
this.addAbility(new CarmenTriggeredAbility());
Ability sacTrigger = new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_PERMANENT, TargetController.ANY, SetTargetPointer.NONE, false);
sacTrigger.addEffect(new GainLifeEffect(1).concatBy("and"));
this.addAbility(sacTrigger);
// Whenever Carmen attacks, return up to one target permanent card with mana value less than or equal to Carmen's power from your graveyard to the battlefield.
Ability ability = new AttacksTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect());
@ -65,35 +65,3 @@ public final class CarmenCruelSkymarcher extends CardImpl {
return new CarmenCruelSkymarcher(this);
}
}
class CarmenTriggeredAbility extends TriggeredAbilityImpl {
CarmenTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
this.addEffect(new GainLifeEffect(1));
}
private CarmenTriggeredAbility(final CarmenTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public CarmenTriggeredAbility copy() {
return new CarmenTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever a player sacrifices a permanent, put a +1/+1 counter on {this} and you gain 1 life.";
}
}

View file

@ -6,9 +6,7 @@ import mage.abilities.effects.common.ReturnSourceFromGraveyardToHandEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
@ -34,7 +32,8 @@ public final class CuriousCadaver extends CardImpl {
// When you sacrifice a Clue, return Curious Cadaver from your graveyard to your hand.
this.addAbility(new SacrificePermanentTriggeredAbility(
Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), filter, false, false
Zone.GRAVEYARD, new ReturnSourceFromGraveyardToHandEffect(), filter,
TargetController.YOU, SetTargetPointer.NONE, false
));
}

View file

@ -1,17 +1,14 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.FilterPermanent;
import java.util.UUID;
@ -20,6 +17,8 @@ import java.util.UUID;
*/
public final class DaringSleuth extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.CLUE, "a Clue");
public DaringSleuth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.HUMAN);
@ -31,7 +30,8 @@ public final class DaringSleuth extends CardImpl {
// When you sacrifice a Clue, transform Daring Sleuth.
this.addAbility(new TransformAbility());
this.addAbility(new DaringSleuthTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(new TransformSourceEffect(), filter)
.setTriggerPhrase("When you sacrifice a Clue, "));
}
private DaringSleuth(final DaringSleuth card) {
@ -43,31 +43,3 @@ public final class DaringSleuth extends CardImpl {
return new DaringSleuth(this);
}
}
class DaringSleuthTriggeredAbility extends TriggeredAbilityImpl {
public DaringSleuthTriggeredAbility() {
super(Zone.BATTLEFIELD, new TransformSourceEffect());
setTriggerPhrase("When you sacrifice a Clue, ");
}
private DaringSleuthTriggeredAbility(final DaringSleuthTriggeredAbility ability) {
super(ability);
}
@Override
public DaringSleuthTriggeredAbility copy() {
return new DaringSleuthTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).hasSubtype(SubType.CLUE, game);
}
}

View file

@ -1,17 +1,18 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.SkipDrawStepEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
@ -26,7 +27,9 @@ public final class DragonAppeasement extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SkipDrawStepEffect()));
// Whenever you sacrifice a creature, you may draw a card.
this.addAbility(new DragonAppeasementTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_PERMANENT_CREATURE,
TargetController.YOU, SetTargetPointer.NONE, true));
}
@ -39,32 +42,3 @@ public final class DragonAppeasement extends CardImpl {
return new DragonAppeasement(this);
}
}
class DragonAppeasementTriggeredAbility extends TriggeredAbilityImpl {
public DragonAppeasementTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), true);
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a creature, ");
}
private DragonAppeasementTriggeredAbility(final DragonAppeasementTriggeredAbility ability) {
super(ability);
}
@Override
public DragonAppeasementTriggeredAbility copy() {
return new DragonAppeasementTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game);
}
}

View file

@ -1,23 +1,19 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.MillCardsTargetEffect;
import mage.abilities.effects.keyword.InvestigateEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
*
* @author LevelX2
@ -37,7 +33,7 @@ public final class FleetingMemories extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new InvestigateEffect(), false));
// Whenever you sacrifice a Clue, target player puts the top three cards of their graveyard into their graveyard.
Ability ability = new FleetingMemoriesTriggeredAbility();
Ability ability = new SacrificePermanentTriggeredAbility(new MillCardsTargetEffect(3), filter);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
@ -51,32 +47,3 @@ public final class FleetingMemories extends CardImpl {
return new FleetingMemories(this);
}
}
class FleetingMemoriesTriggeredAbility extends TriggeredAbilityImpl {
public FleetingMemoriesTriggeredAbility() {
super(Zone.BATTLEFIELD, new MillCardsTargetEffect(3));
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a Clue, ");
}
private FleetingMemoriesTriggeredAbility(final FleetingMemoriesTriggeredAbility ability) {
super(ability);
}
@Override
public FleetingMemoriesTriggeredAbility copy() {
return new FleetingMemoriesTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).hasSubtype(SubType.CLUE, game);
}
}

View file

@ -1,17 +1,18 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SacrificeAllTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
/**
*
* @author weirddan455
@ -33,9 +34,8 @@ public final class ForgeBoss extends CardImpl {
this.toughness = new MageInt(4);
// Whenever you sacrifice one or more other creatures, Forge Boss deals 2 damage to each opponent. This ability triggers only once each turn.
this.addAbility(new SacrificeAllTriggeredAbility(
new DamagePlayersEffect(2, TargetController.OPPONENT),
filter, TargetController.YOU, false
this.addAbility(new SacrificePermanentTriggeredAbility(
new DamagePlayersEffect(2, TargetController.OPPONENT), filter
).setTriggersOnceEachTurn(true));
}

View file

@ -1,7 +1,7 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.common.SacrificeAllTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.dynamicvalue.DynamicValue;
@ -53,9 +53,9 @@ public final class ForgeNeverwinterCharlatan extends CardImpl {
).setText("{this} gets +2/+0 for each Treasure you control")).addHint(hint));
// Whenever one or more players sacrifice one or more creatures, you create a tapped Treasure token. This ability triggers only once each turn.
this.addAbility(new SacrificeAllTriggeredAbility(
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new CreateTokenEffect(new TreasureToken(), 1, true),
StaticFilters.FILTER_PERMANENT_CREATURE, TargetController.ANY, false
StaticFilters.FILTER_PERMANENT_CREATURE, TargetController.ANY, SetTargetPointer.NONE, false
).setTriggersOnceEachTurn(true).setTriggerPhrase("Whenever one or more players sacrifice one or more creatures, "));
}

View file

@ -1,30 +1,39 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.Ability;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public final class FurnaceCelebration extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public FurnaceCelebration(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}{R}");
this.addAbility(new FurnaceCelebrationAbility());
// Whenever you sacrifice another permanent, you may pay {2}. If you do, Furnace Celebration deals 2 damage to any target.
Ability ability = new SacrificePermanentTriggeredAbility(new DoIfCostPaid(
new DamageTargetEffect(2), new GenericManaCost(2)), filter);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private FurnaceCelebration(final FurnaceCelebration card) {
@ -37,31 +46,3 @@ public final class FurnaceCelebration extends CardImpl {
}
}
class FurnaceCelebrationAbility extends TriggeredAbilityImpl {
public FurnaceCelebrationAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new DamageTargetEffect(2), new ManaCostsImpl<>("{2}")));
this.addTarget(new TargetAnyTarget());
setTriggerPhrase("Whenever you sacrifice another permanent, ");
}
private FurnaceCelebrationAbility(final FurnaceCelebrationAbility ability) {
super(ability);
}
@Override
public FurnaceCelebrationAbility copy() {
return new FurnaceCelebrationAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId()) && !event.getTargetId().equals(sourceId);
}
}

View file

@ -1,18 +1,15 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.filter.FilterPermanent;
import java.util.UUID;
/**
*
@ -20,6 +17,8 @@ import mage.game.events.GameEvent.EventType;
*/
public final class GrafMole extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.CLUE, "a Clue");
public GrafMole(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}");
this.subtype.add(SubType.MOLE);
@ -28,7 +27,7 @@ public final class GrafMole extends CardImpl {
this.toughness = new MageInt(4);
// Whenever you sacrifice a Clue, you gain 3 life.
this.addAbility(new GrafMoleTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(new GainLifeEffect(3), filter));
}
private GrafMole(final GrafMole card) {
@ -40,32 +39,3 @@ public final class GrafMole extends CardImpl {
return new GrafMole(this);
}
}
class GrafMoleTriggeredAbility extends TriggeredAbilityImpl {
public GrafMoleTriggeredAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(3));
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a Clue, ");
}
private GrafMoleTriggeredAbility(final GrafMoleTriggeredAbility ability) {
super(ability);
}
@Override
public GrafMoleTriggeredAbility copy() {
return new GrafMoleTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).hasSubtype(SubType.CLUE, game);
}
}

View file

@ -1,15 +1,14 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.StaticFilters;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
@ -27,7 +26,9 @@ public final class HavocJester extends CardImpl {
this.toughness = new MageInt(5);
// Whenever you sacrifice a permanent, Havoc Jester deals 1 damage to any target.
this.addAbility(new HavocJesterTriggeredAbility());
Ability ability = new SacrificePermanentTriggeredAbility(new DamageTargetEffect(1), StaticFilters.FILTER_PERMANENT);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private HavocJester(final HavocJester card) {
@ -39,35 +40,3 @@ public final class HavocJester extends CardImpl {
return new HavocJester(this);
}
}
class HavocJesterTriggeredAbility extends TriggeredAbilityImpl {
HavocJesterTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(1));
this.addTarget(new TargetAnyTarget());
}
private HavocJesterTriggeredAbility(final HavocJesterTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(getControllerId());
}
@Override
public HavocJesterTriggeredAbility copy() {
return new HavocJesterTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever you sacrifice a permanent, {this} deals 1 damage to any target.";
}
}

View file

@ -1,13 +1,12 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.common.OpponentSacrificesNonTokenPermanentTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
import mage.abilities.keyword.AnnihilatorAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
@ -18,10 +17,10 @@ import java.util.UUID;
*/
public final class ItThatBetrays extends CardImpl {
private static final FilterPermanent FILTER = new FilterPermanent("nontoken permanent");
private static final FilterPermanent filter = new FilterPermanent("nontoken permanent");
static {
FILTER.add(TokenPredicate.FALSE);
filter.add(TokenPredicate.FALSE);
}
public ItThatBetrays(UUID ownerId, CardSetInfo setInfo) {
@ -35,9 +34,10 @@ public final class ItThatBetrays extends CardImpl {
this.addAbility(new AnnihilatorAbility(2));
// Whenever an opponent sacrifices a nontoken permanent, put that card onto the battlefield under your control.
this.addAbility(new OpponentSacrificesNonTokenPermanentTriggeredAbility(
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new ReturnToBattlefieldUnderYourControlTargetEffect()
.setText("put that card onto the battlefield under your control")
.setText("put that card onto the battlefield under your control"),
filter, TargetController.OPPONENT, SetTargetPointer.PERMANENT, false
));
}

View file

@ -14,6 +14,7 @@ import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetAnyTarget;
@ -36,7 +37,7 @@ public final class JuriMasterOfTheRevue extends CardImpl {
// Whenever you sacrifice a permanent, put a +1/+1 counter on Juri, Master of the Revue.
this.addAbility(new SacrificePermanentTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance())
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_PERMANENT_A
));
// When Juri dies, it deals damage equal its power to any target.

View file

@ -2,7 +2,7 @@ package mage.cards.k;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.GenericManaCost;
@ -14,11 +14,11 @@ import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
@ -40,7 +40,10 @@ public final class KelsFightFixer extends CardImpl {
this.addAbility(new MenaceAbility(false));
// Whenever you sacrifice a creature, you may pay {U/B}. If you do, draw a card.
this.addAbility(new KelsFightFixerTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{U/B}")),
StaticFilters.FILTER_PERMANENT_CREATURE
));
// {1}, Sacrifice a creature: Kels, Fight Fixer gains indestructible until end of turn.
Ability ability = new SimpleActivatedAbility(new GainAbilitySourceEffect(
@ -59,32 +62,3 @@ public final class KelsFightFixer extends CardImpl {
return new KelsFightFixer(this);
}
}
class KelsFightFixerTriggeredAbility extends TriggeredAbilityImpl {
KelsFightFixerTriggeredAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{U/B}")), false);
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a creature, ");
}
private KelsFightFixerTriggeredAbility(final KelsFightFixerTriggeredAbility ability) {
super(ability);
}
@Override
public KelsFightFixerTriggeredAbility copy() {
return new KelsFightFixerTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game);
}
}

View file

@ -1,8 +1,9 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@ -12,12 +13,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
@ -50,7 +49,11 @@ public final class KorvoldFaeCursedKing extends CardImpl {
));
// Whenever you sacrifice a permanent, put a +1/+1 counter on Korvold and draw a card.
this.addAbility(new KorvoldFaeCursedKingAbility());
Ability ability = new SacrificePermanentTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()),
StaticFilters.FILTER_PERMANENT);
ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
this.addAbility(ability);
}
private KorvoldFaeCursedKing(final KorvoldFaeCursedKing card) {
@ -62,35 +65,3 @@ public final class KorvoldFaeCursedKing extends CardImpl {
return new KorvoldFaeCursedKing(this);
}
}
class KorvoldFaeCursedKingAbility extends TriggeredAbilityImpl {
KorvoldFaeCursedKingAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
this.addEffect(new DrawCardSourceControllerEffect(1));
}
private KorvoldFaeCursedKingAbility(final KorvoldFaeCursedKingAbility ability) {
super(ability);
}
@Override
public KorvoldFaeCursedKingAbility copy() {
return new KorvoldFaeCursedKingAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return this.isControlledBy(event.getPlayerId());
}
@Override
public String getRule() {
return "Whenever you sacrifice a permanent, put a +1/+1 counter on {this} and draw a card.";
}
}

View file

@ -3,7 +3,7 @@ package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SacrificeAllTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
@ -20,7 +20,10 @@ import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
import java.util.*;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801
@ -42,10 +45,10 @@ public final class MalikGrimManipulator extends CardImpl {
this.addAbility(ability);
// Whenever an opponent sacrifices a creature, you create a Treasure token.
this.addAbility(new SacrificeAllTriggeredAbility(
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new CreateTokenEffect(new TreasureToken()).setText("you create a Treasure token"),
StaticFilters.FILTER_PERMANENT_A_CREATURE,
TargetController.OPPONENT, false
TargetController.OPPONENT, SetTargetPointer.NONE, false
));
}

View file

@ -1,15 +1,13 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
@ -27,7 +25,11 @@ public final class MayhemDevil extends CardImpl {
this.toughness = new MageInt(3);
// Whenever a player sacrifices a permanent, Mayhem Devil deals 1 damage to any target.
this.addAbility(new MayhemDevilTriggeredAbility());
Ability ability = new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new DamageTargetEffect(1), StaticFilters.FILTER_PERMANENT,
TargetController.ANY, SetTargetPointer.NONE, false);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private MayhemDevil(final MayhemDevil card) {
@ -39,35 +41,3 @@ public final class MayhemDevil extends CardImpl {
return new MayhemDevil(this);
}
}
class MayhemDevilTriggeredAbility extends TriggeredAbilityImpl {
MayhemDevilTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(1));
this.addTarget(new TargetAnyTarget());
}
private MayhemDevilTriggeredAbility(final MayhemDevilTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return true;
}
@Override
public MayhemDevilTriggeredAbility copy() {
return new MayhemDevilTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever a player sacrifices a permanent, {this} deals 1 damage to any target.";
}
}

View file

@ -1,24 +1,18 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
/**
*
@ -26,6 +20,12 @@ import mage.game.events.GameEvent.EventType;
*/
public final class MazirekKraulDeathPriest extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public MazirekKraulDeathPriest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{G}");
this.supertype.add(SuperType.LEGENDARY);
@ -38,7 +38,9 @@ public final class MazirekKraulDeathPriest extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever a player sacrifices another permanent, put a +1/+1 counter on each creature you control.
this.addAbility(new PlayerSacrificesPermanentTriggeredAbility(new AddCountersAllEffect(CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent()), false));
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersAllEffect(CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE),
filter, TargetController.ANY, SetTargetPointer.NONE, false));
}
private MazirekKraulDeathPriest(final MazirekKraulDeathPriest card) {
@ -50,31 +52,3 @@ public final class MazirekKraulDeathPriest extends CardImpl {
return new MazirekKraulDeathPriest(this);
}
}
class PlayerSacrificesPermanentTriggeredAbility extends TriggeredAbilityImpl {
public PlayerSacrificesPermanentTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
setTriggerPhrase("Whenever a player sacrifices another permanent, ");
}
private PlayerSacrificesPermanentTriggeredAbility(final PlayerSacrificesPermanentTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject mageObject = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
return mageObject != null && !event.getTargetId().equals(this.getSourceId());
}
@Override
public PlayerSacrificesPermanentTriggeredAbility copy() {
return new PlayerSacrificesPermanentTriggeredAbility(this);
}
}

View file

@ -1,20 +1,15 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
@ -30,7 +25,9 @@ public final class MorticianBeetle extends CardImpl {
this.toughness = new MageInt(1);
// Whenever a player sacrifices a creature, you may put a +1/+1 counter on Mortician Beetle.
this.addAbility(new PlayerSacrificesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true));
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_PERMANENT_CREATURE,
TargetController.ANY, SetTargetPointer.NONE, true));
}
private MorticianBeetle(final MorticianBeetle card) {
@ -42,34 +39,3 @@ public final class MorticianBeetle extends CardImpl {
return new MorticianBeetle(this);
}
}
class PlayerSacrificesCreatureTriggeredAbility extends TriggeredAbilityImpl {
public PlayerSacrificesCreatureTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
setTriggerPhrase("Whenever a player sacrifices a creature, ");
}
private PlayerSacrificesCreatureTriggeredAbility(final PlayerSacrificesCreatureTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject mageObject = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (mageObject != null && mageObject.isCreature(game)) {
return true;
}
return false;
}
@Override
public PlayerSacrificesCreatureTriggeredAbility copy() {
return new PlayerSacrificesCreatureTriggeredAbility(this);
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.n;
import mage.abilities.Ability;
import mage.abilities.common.OpponentSacrificesNonTokenPermanentTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.common.DoUnlessTargetPlayerOrTargetsControllerPaysEffect;
@ -13,10 +13,9 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
import java.util.UUID;
@ -26,25 +25,33 @@ import java.util.UUID;
*/
public final class NazgulBattleMace extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("nontoken permanent");
static {
filter.add(TokenPredicate.FALSE);
}
public NazgulBattleMace(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
this.subtype.add(SubType.EQUIPMENT);
//String abilityText = "Whenever an opponent sacrifices a nontoken permanent, put that card onto the battlefield under your control unless that player pays 3 life";
// Equipped creature has menace, deathtouch, annihilator 1, and
// "Whenever an opponent sacrifices a nontoken permanent, put that card onto the battlefield under your control unless that player pays 3 life."
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(new MenaceAbility(false), AttachmentType.EQUIPMENT));
ability.addEffect(new GainAbilityAttachedEffect(DeathtouchAbility.getInstance(), AttachmentType.EQUIPMENT).setText(", deathtouch"));
ability.addEffect(new GainAbilityAttachedEffect(new AnnihilatorAbility(1), AttachmentType.EQUIPMENT).setText(", annihilator 1"));
Ability sacTriggerAbility = new OpponentSacrificesNonTokenPermanentTriggeredAbility(
Ability sacTriggerAbility = new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(
new ReturnToBattlefieldUnderYourControlTargetEffect(),
new PayLifeCost(3)
).setText("put that card onto the battlefield under your control unless that player pays 3 life"));
).setText("put that card onto the battlefield under your control unless that player pays 3 life"),
filter, TargetController.OPPONENT, SetTargetPointer.PERMANENT, false
);
ability.addEffect(new GainAbilityAttachedEffect(sacTriggerAbility, AttachmentType.EQUIPMENT)
.setText(", and \""+sacTriggerAbility.getRule()+"\"")
.setText(", and \"" + sacTriggerAbility.getRule() + "\"")
);
this.addAbility(ability);
// Equip {3}
this.addAbility(new EquipAbility(3, false));
}

View file

@ -8,10 +8,7 @@ import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
@ -34,9 +31,9 @@ public final class ProwlingGeistcatcher extends CardImpl {
this.toughness = new MageInt(4);
// Whenever you sacrifice another creature, exile it. If that creature was a token, put a +1/+1 counter on Prowling Geistcatcher.
this.addAbility(new SacrificePermanentTriggeredAbility(
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new ProwlingGeistcatcherExileEffect(),
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true
StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, TargetController.YOU, SetTargetPointer.PERMANENT, false
));
// When Prowling Geistcatcher leaves the battlefield, return each card exiled with it to the battlefield under your control.

View file

@ -1,22 +1,19 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
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.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -33,7 +30,10 @@ public final class RuthlessDeathfang extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever you sacrifice a creature, target opponent sacrifices a creature.
Ability ability = new RuthlessDeathfangTriggeredAbility();
Ability ability = new SacrificePermanentTriggeredAbility(
new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "target opponent"),
StaticFilters.FILTER_PERMANENT_CREATURE
);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
@ -47,32 +47,3 @@ public final class RuthlessDeathfang extends CardImpl {
return new RuthlessDeathfang(this);
}
}
class RuthlessDeathfangTriggeredAbility extends TriggeredAbilityImpl {
public RuthlessDeathfangTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "target opponent"), false);
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a creature, ");
}
private RuthlessDeathfangTriggeredAbility(final RuthlessDeathfangTriggeredAbility ability) {
super(ability);
}
@Override
public RuthlessDeathfangTriggeredAbility copy() {
return new RuthlessDeathfangTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game);
}
}

View file

@ -7,9 +7,7 @@ import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
@ -36,13 +34,14 @@ public final class SanguineStatuette extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new BloodToken())));
// Whenever you sacrifice a Blood token, you may have Sanguine Statuette become a 3/3 Vampire artifact creature with haste until end of turn.
this.addAbility(new SacrificePermanentTriggeredAbility(new BecomesCreatureSourceEffect(
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(
new CreatureToken(3, 3, "3/3 Vampire artifact creature with haste")
.withType(CardType.ARTIFACT)
.withSubType(SubType.VAMPIRE)
.withAbility(HasteAbility.getInstance()),
CardType.ARTIFACT, Duration.EndOfTurn
).setText("have {this} become a 3/3 Vampire artifact creature with haste until end of turn"), filter, false, true));
).setText("have {this} become a 3/3 Vampire artifact creature with haste until end of turn"),
filter, TargetController.YOU, SetTargetPointer.NONE, true));
}
private SanguineStatuette(final SanguineStatuette card) {

View file

@ -1,37 +1,41 @@
package mage.cards.s;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
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;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public final class SavraQueenOfTheGolgari extends CardImpl {
private static final FilterCreaturePermanent filterBlack = new FilterCreaturePermanent("a black creature");
private static final FilterCreaturePermanent filterGreen = new FilterCreaturePermanent("a green creature");
static {
filterBlack.add(new ColorPredicate(ObjectColor.BLACK));
filterGreen.add(new ColorPredicate(ObjectColor.GREEN));
}
public SavraQueenOfTheGolgari(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{B}{G}");
this.supertype.add(SuperType.LEGENDARY);
@ -41,10 +45,15 @@ public final class SavraQueenOfTheGolgari extends CardImpl {
this.toughness = new MageInt(2);
// Whenever you sacrifice a black creature, you may pay 2 life. If you do, each other player sacrifices a creature.
this.addAbility(new SavraSacrificeBlackCreatureAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new DoIfCostPaid(new SavraSacrificeEffect(), new PayLifeCost(2)),
filterBlack
));
// Whenever you sacrifice a green creature, you may gain 2 life.
this.addAbility(new SavraSacrificeGreenCreatureAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(2),
filterGreen, TargetController.YOU, SetTargetPointer.NONE, true
));
}
private SavraQueenOfTheGolgari(final SavraQueenOfTheGolgari card) {
@ -57,36 +66,6 @@ public final class SavraQueenOfTheGolgari extends CardImpl {
}
}
class SavraSacrificeBlackCreatureAbility extends TriggeredAbilityImpl {
public SavraSacrificeBlackCreatureAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new SavraSacrificeEffect(), new PayLifeCost(2)));
this.setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a black creature, ");
}
private SavraSacrificeBlackCreatureAbility(final SavraSacrificeBlackCreatureAbility ability) {
super(ability);
}
@Override
public SavraSacrificeBlackCreatureAbility copy() {
return new SavraSacrificeBlackCreatureAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game)
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).getColor(game).isBlack();
}
}
class SavraSacrificeEffect extends OneShotEffect {
SavraSacrificeEffect() {
@ -129,32 +108,3 @@ class SavraSacrificeEffect extends OneShotEffect {
return false;
}
}
class SavraSacrificeGreenCreatureAbility extends TriggeredAbilityImpl {
public SavraSacrificeGreenCreatureAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(2), true);
setTriggerPhrase("Whenever you sacrifice a green creature, ");
}
private SavraSacrificeGreenCreatureAbility(final SavraSacrificeGreenCreatureAbility ability) {
super(ability);
}
@Override
public SavraSacrificeGreenCreatureAbility copy() {
return new SavraSacrificeGreenCreatureAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game)
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).getColor(game).isGreen();
}
}

View file

@ -2,7 +2,7 @@ package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.GenericManaCost;
@ -14,13 +14,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
@ -49,7 +46,9 @@ public final class SlaughterPriestOfMogis extends CardImpl {
this.toughness = new MageInt(2);
// Whenever you sacrifice a permanent, Slaughter-Priest of Mogis gets +2/+0 until end of turn.
this.addAbility(new SlaughterPriestOfMogisAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new BoostSourceEffect(2, 0, Duration.EndOfTurn), StaticFilters.FILTER_PERMANENT
));
// {2}, Sacrifice another creature or enchantment: Slaughter-Priest of Mogis gains first strike until end of turn.
Ability ability = new SimpleActivatedAbility(
@ -68,34 +67,3 @@ public final class SlaughterPriestOfMogis extends CardImpl {
return new SlaughterPriestOfMogis(this);
}
}
class SlaughterPriestOfMogisAbility extends TriggeredAbilityImpl {
SlaughterPriestOfMogisAbility() {
super(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn));
}
private SlaughterPriestOfMogisAbility(final SlaughterPriestOfMogisAbility ability) {
super(ability);
}
@Override
public SlaughterPriestOfMogisAbility copy() {
return new SlaughterPriestOfMogisAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId());
}
@Override
public String getRule() {
return "Whenever you sacrifice a permanent, {this} gets +2/+0 until end of turn.";
}
}

View file

@ -1,10 +1,8 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.keyword.DevoidAbility;
@ -14,10 +12,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import java.util.UUID;
/**
*
@ -42,7 +39,9 @@ public final class SmotheringAbomination extends CardImpl {
StaticFilters.FILTER_PERMANENT_CREATURE, 1, null), TargetController.YOU, false));
// Whenever you sacrifice a creature, draw a card.
this.addAbility(new SmotheringAbominationTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new DrawCardSourceControllerEffect(1), StaticFilters.FILTER_PERMANENT_CREATURE
));
}
private SmotheringAbomination(final SmotheringAbomination card) {
@ -54,32 +53,3 @@ public final class SmotheringAbomination extends CardImpl {
return new SmotheringAbomination(this);
}
}
class SmotheringAbominationTriggeredAbility extends TriggeredAbilityImpl {
public SmotheringAbominationTriggeredAbility() {
super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1));
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a creature, ");
}
private SmotheringAbominationTriggeredAbility(final SmotheringAbominationTriggeredAbility ability) {
super(ability);
}
@Override
public SmotheringAbominationTriggeredAbility copy() {
return new SmotheringAbominationTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).isCreature(game);
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.CreateTokenCopySourceEffect;
import mage.abilities.effects.common.DoIfCostPaid;
@ -9,9 +9,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import java.util.UUID;
@ -20,6 +19,12 @@ import java.util.UUID;
*/
public final class SorcerersBroom extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("another permanent");
static {
filter.add(AnotherPredicate.instance);
}
public SorcerersBroom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
@ -28,7 +33,10 @@ public final class SorcerersBroom extends CardImpl {
this.toughness = new MageInt(1);
// Whenever you sacrifice another permanent, you may pay {3}. If you do, create a token that's a copy of Sorcerer's Broom.
this.addAbility(new SorcerersBroomTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new DoIfCostPaid(new CreateTokenCopySourceEffect(), new GenericManaCost(3)),
filter
));
}
private SorcerersBroom(final SorcerersBroom card) {
@ -40,36 +48,3 @@ public final class SorcerersBroom extends CardImpl {
return new SorcerersBroom(this);
}
}
class SorcerersBroomTriggeredAbility extends TriggeredAbilityImpl {
SorcerersBroomTriggeredAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new CreateTokenCopySourceEffect(), new GenericManaCost(3)));
}
private SorcerersBroomTriggeredAbility(final SorcerersBroomTriggeredAbility ability) {
super(ability);
}
@Override
public SorcerersBroomTriggeredAbility copy() {
return new SorcerersBroomTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& !event.getTargetId().equals(sourceId);
}
@Override
public String getRule() {
return "Whenever you sacrifice another permanent, you may pay {3}. " +
"If you do, create a token that's a copy of {this}.";
}
}

View file

@ -1,25 +1,18 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
*
@ -40,10 +33,16 @@ public final class Thraximundar extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// Whenever Thraximundar attacks, defending player sacrifices a creature.
this.addAbility(new ThraximundarTriggeredAbility());
this.addAbility(new AttacksTriggeredAbility(
new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "defending player"),
false, null, SetTargetPointer.PLAYER
));
// Whenever a player sacrifices a creature, you may put a +1/+1 counter on Thraximundar.
this.addAbility(new PlayerSacrificesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true));
this.addAbility(new SacrificePermanentTriggeredAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), StaticFilters.FILTER_PERMANENT_CREATURE,
TargetController.ANY, SetTargetPointer.NONE, true
));
}
@ -56,75 +55,3 @@ public final class Thraximundar extends CardImpl {
return new Thraximundar(this);
}
}
class ThraximundarTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterControlledPermanent filter;
static {
filter = new FilterControlledPermanent(" a creature");
filter.add(CardType.CREATURE.getPredicate());
}
public ThraximundarTriggeredAbility() {
super(Zone.BATTLEFIELD, new SacrificeEffect(filter, 1, "defending player"));
}
private ThraximundarTriggeredAbility(final ThraximundarTriggeredAbility ability) {
super(ability);
}
@Override
public ThraximundarTriggeredAbility copy() {
return new ThraximundarTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ATTACKER_DECLARED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId() != null
&& event.getSourceId().equals(this.getSourceId())) {
UUID defender = game.getCombat().getDefendingPlayerId(this.getSourceId(), game);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defender));
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} attacks, defending player sacrifices a creature.";
}
}
class PlayerSacrificesCreatureTriggeredAbility extends TriggeredAbilityImpl {
public PlayerSacrificesCreatureTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
setTriggerPhrase("Whenever a player sacrifices a creature, ");
}
private PlayerSacrificesCreatureTriggeredAbility(final PlayerSacrificesCreatureTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
MageObject mageObject = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
return mageObject != null && mageObject.isCreature(game);
}
@Override
public PlayerSacrificesCreatureTriggeredAbility copy() {
return new PlayerSacrificesCreatureTriggeredAbility(this);
}
}

View file

@ -1,7 +1,7 @@
package mage.cards.t;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DoIfCostPaid;
@ -10,12 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.PutCards;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.FoodToken;
import java.util.UUID;
@ -34,7 +29,12 @@ public final class TrailOfCrumbs extends CardImpl {
// Whenever you sacrifice a Food, you may pay {1}. If you do, look at the top two cards of your library.
// You may reveal a permanent card from among them and put it into your hand.
// Put the rest on the bottom of your library in any order.
this.addAbility(new TrailOfCrumbsTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(
new DoIfCostPaid(new LookLibraryAndPickControllerEffect(
2, 1, StaticFilters.FILTER_CARD_PERMANENT, PutCards.HAND, PutCards.BOTTOM_ANY
), new GenericManaCost(1)),
StaticFilters.FILTER_CONTROLLED_FOOD
));
}
private TrailOfCrumbs(final TrailOfCrumbs card) {
@ -46,35 +46,3 @@ public final class TrailOfCrumbs extends CardImpl {
return new TrailOfCrumbs(this);
}
}
class TrailOfCrumbsTriggeredAbility extends TriggeredAbilityImpl {
TrailOfCrumbsTriggeredAbility() {
super(Zone.BATTLEFIELD, new DoIfCostPaid(new LookLibraryAndPickControllerEffect(
2, 1, StaticFilters.FILTER_CARD_PERMANENT, PutCards.HAND, PutCards.BOTTOM_ANY
), new GenericManaCost(1)));
setTriggerPhrase("Whenever you sacrifice a Food, ");
}
private TrailOfCrumbsTriggeredAbility(final TrailOfCrumbsTriggeredAbility ability) {
super(ability);
}
@Override
public TrailOfCrumbsTriggeredAbility copy() {
return new TrailOfCrumbsTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
return permanent != null
&& event.getPlayerId().equals(this.getControllerId())
&& permanent.hasSubtype(SubType.FOOD, game);
}
}

View file

@ -1,25 +1,19 @@
package mage.cards.u;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.SacrificePermanentTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.keyword.InvestigateEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.token.HumanSoldierToken;
import java.util.UUID;
/**
*
* @author fireshoes
@ -39,7 +33,7 @@ public final class UlvenwaldMysteries extends CardImpl {
this.addAbility(new DiesCreatureTriggeredAbility(new InvestigateEffect(), false, StaticFilters.FILTER_CONTROLLED_CREATURE_NON_TOKEN));
// Whenever you sacrifice a Clue, create a 1/1 white Human Soldier creature token.
this.addAbility(new UlvenwaldMysteriesTriggeredAbility());
this.addAbility(new SacrificePermanentTriggeredAbility(new CreateTokenEffect(new HumanSoldierToken()), filterClue));
}
private UlvenwaldMysteries(final UlvenwaldMysteries card) {
@ -51,32 +45,3 @@ public final class UlvenwaldMysteries extends CardImpl {
return new UlvenwaldMysteries(this);
}
}
class UlvenwaldMysteriesTriggeredAbility extends TriggeredAbilityImpl {
public UlvenwaldMysteriesTriggeredAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new HumanSoldierToken()));
setLeavesTheBattlefieldTrigger(true);
setTriggerPhrase("Whenever you sacrifice a Clue, ");
}
private UlvenwaldMysteriesTriggeredAbility(final UlvenwaldMysteriesTriggeredAbility ability) {
super(ability);
}
@Override
public UlvenwaldMysteriesTriggeredAbility copy() {
return new UlvenwaldMysteriesTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD).hasSubtype(SubType.CLUE, game);
}
}

View file

@ -1,46 +0,0 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.target.targetpointer.FixedTarget;
public class OpponentSacrificesNonTokenPermanentTriggeredAbility extends TriggeredAbilityImpl {
public OpponentSacrificesNonTokenPermanentTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
setTriggerPhrase("Whenever an opponent sacrifices a nontoken permanent, ");
}
protected OpponentSacrificesNonTokenPermanentTriggeredAbility(final OpponentSacrificesNonTokenPermanentTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getPlayer(getControllerId()).hasOpponent(event.getPlayerId(), game)) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (permanent != null && !(permanent instanceof PermanentToken)) {
getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game.getState().getZoneChangeCounter(event.getTargetId())));
return true;
}
}
return false;
}
@Override
public OpponentSacrificesNonTokenPermanentTriggeredAbility copy() {
return new OpponentSacrificesNonTokenPermanentTriggeredAbility(this);
}
}

View file

@ -1,48 +0,0 @@
package mage.abilities.common;
import mage.MageObject;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
public class OpponentSacrificesPermanentTriggeredAbility extends TriggeredAbilityImpl {
public OpponentSacrificesPermanentTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
setTriggerPhrase("Whenever an opponent sacrifices a nontoken permanent, ");
}
protected OpponentSacrificesPermanentTriggeredAbility(final OpponentSacrificesPermanentTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
MageObject object = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (object instanceof Permanent) {
for (Effect effect : getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId(), game));
}
return true;
}
}
return false;
}
@Override
public OpponentSacrificesPermanentTriggeredAbility copy() {
return new OpponentSacrificesPermanentTriggeredAbility(this);
}
}

View file

@ -1,82 +0,0 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author LevelX2
*/
public class SacrificeAllTriggeredAbility extends TriggeredAbilityImpl {
private final FilterPermanent filter;
private final TargetController sacrificingPlayer;
public SacrificeAllTriggeredAbility(Effect effect, FilterPermanent filter, TargetController sacrificingPlayer, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
this.filter = filter;
this.sacrificingPlayer = sacrificingPlayer;
setTriggerPhrase(generateTriggerPhrase());
}
protected SacrificeAllTriggeredAbility(final SacrificeAllTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.sacrificingPlayer = ability.sacrificingPlayer;
}
@Override
public SacrificeAllTriggeredAbility copy() {
return new SacrificeAllTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SACRIFICED_PERMANENT;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
switch (sacrificingPlayer) {
case YOU:
if (!event.getPlayerId().equals(getControllerId())) {
return false;
}
break;
case OPPONENT:
Player controller = game.getPlayer(getControllerId());
if (controller == null || !controller.hasOpponent(event.getPlayerId(), game)) {
return false;
}
break;
case ANY:
break;
default:
return false;
}
Permanent sacrificedPermanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
return sacrificedPermanent != null && filter.match(sacrificedPermanent, getControllerId(), this, game);
}
private String generateTriggerPhrase() {
String targetControllerText;
switch (sacrificingPlayer) {
case YOU:
targetControllerText = "you sacrifice ";
break;
case OPPONENT:
targetControllerText = "an opponent sacrifices ";
break;
default:
targetControllerText = "a player sacrifices ";
break;
}
return "Whenever " + targetControllerText + filter.getMessage() + ", ";
}
}

View file

@ -2,53 +2,53 @@ package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.SetTargetPointer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
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.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
* @author TheElk801
* @author TheElk801, xenohedron
*/
public class SacrificePermanentTriggeredAbility extends TriggeredAbilityImpl {
private final FilterPermanent filter;
private final boolean setTargetPointer;
private final SetTargetPointer setTargetPointer;
public SacrificePermanentTriggeredAbility(Effect effect) {
this(effect, StaticFilters.FILTER_PERMANENT_A);
}
private final TargetController sacrificingPlayer;
/**
* Whenever you sacrifice a "[filter]", "[effect]".
* zone = battlefield, setTargetPointer = NONE, optional = false
*/
public SacrificePermanentTriggeredAbility(Effect effect, FilterPermanent filter) {
this(effect, filter, false);
this(Zone.BATTLEFIELD, effect, filter, TargetController.YOU, SetTargetPointer.NONE, false);
}
public SacrificePermanentTriggeredAbility(Effect effect, FilterPermanent filter, boolean setTargetPointer) {
this(effect, filter, setTargetPointer, false);
}
public SacrificePermanentTriggeredAbility(Effect effect, FilterPermanent filter, boolean setTargetPointer, boolean optional) {
this(Zone.BATTLEFIELD, effect, filter, setTargetPointer, optional);
}
public SacrificePermanentTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter, boolean setTargetPointer, boolean optional) {
public SacrificePermanentTriggeredAbility(Zone zone, Effect effect, FilterPermanent filter,
TargetController sacrificingPlayer,
SetTargetPointer setTargetPointer, boolean optional) {
super(zone, effect, optional);
if (Zone.BATTLEFIELD.match(zone)) {
setLeavesTheBattlefieldTrigger(true);
}
this.filter = filter;
this.setTargetPointer = setTargetPointer;
setTriggerPhrase("Whenever you sacrifice " + CardUtil.addArticle(filter.getMessage()) + ", ");
this.sacrificingPlayer = sacrificingPlayer;
setTriggerPhrase(generateTriggerPhrase());
}
protected SacrificePermanentTriggeredAbility(final SacrificePermanentTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.setTargetPointer = ability.setTargetPointer;
this.sacrificingPlayer = ability.sacrificingPlayer;
}
@Override
@ -63,15 +63,59 @@ public class SacrificePermanentTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
switch (sacrificingPlayer) {
case YOU:
if (!event.getPlayerId().equals(getControllerId())) {
return false;
}
break;
case OPPONENT:
Player controller = game.getPlayer(getControllerId());
if (controller == null || !controller.hasOpponent(event.getPlayerId(), game)) {
return false;
}
break;
case ANY:
break;
default:
throw new IllegalArgumentException("Unsupported TargetController in SacrificePermanentTriggeredAbility: " + sacrificingPlayer);
}
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (!isControlledBy(event.getPlayerId()) || permanent == null
|| !filter.match(permanent, getControllerId(), this, game)) {
if (permanent == null || !filter.match(permanent, getControllerId(), this, game)) {
return false;
}
this.getEffects().setValue("sacrificedPermanent", permanent);
if (setTargetPointer) {
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
switch (setTargetPointer) {
case PERMANENT:
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId(), game));
break;
case PLAYER:
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId(), game));
break;
case NONE:
break;
default:
throw new IllegalArgumentException("Unsupported SetTargetPointer in SacrificePermanentTriggeredAbility: " + setTargetPointer);
}
return true;
}
private String generateTriggerPhrase() {
String targetControllerText;
switch (sacrificingPlayer) {
case YOU:
targetControllerText = "you sacrifice ";
break;
case OPPONENT:
targetControllerText = "an opponent sacrifices ";
break;
case ANY:
targetControllerText = "a player sacrifices ";
break;
default:
throw new IllegalArgumentException("Unsupported TargetController in SacrificePermanentTriggeredAbility: " + sacrificingPlayer);
}
return getWhen() + targetControllerText + CardUtil.addArticle(filter.getMessage()) + ", ";
}
}