Created class for reflexive triggered abilities (Ready for review) (#6500)

* added class for reflexive triggered abilities

* added DoWhenCostPaid

* a few more refactors

* some more refactoring

* almost all refactors done

* finished refactoring

* updated text generation

* Delete SendOptionUsedEventEffect.java

* fixed Wildborn Preserver text
This commit is contained in:
Evan Kranzler 2020-05-04 20:51:38 -04:00 committed by GitHub
parent 8a3ba6729f
commit bde65d6279
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 505 additions and 1278 deletions

View file

@ -2,18 +2,19 @@ package mage.cards.b;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
@ -48,6 +49,12 @@ public final class BackForMore extends CardImpl {
class BackForMoreEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature you don't control");
static {
filter.add(TargetController.NOT_YOU.getControllerPredicate());
}
BackForMoreEffect() {
super(Outcome.Benefit);
staticText = "Return target creature card from your graveyard to the battlefield. " +
@ -75,49 +82,13 @@ class BackForMoreEffect extends OneShotEffect {
if (permanent == null) {
return false;
}
game.addDelayedTriggeredAbility(new BackForMoreReflexiveTriggeredAbility(
new MageObjectReference(permanent, game)
), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class BackForMoreReflexiveTriggeredAbility extends DelayedTriggeredAbility {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature you don't control");
static {
filter.add(TargetController.NOT_YOU.getControllerPredicate());
}
BackForMoreReflexiveTriggeredAbility(MageObjectReference mor) {
super(new BackForMoreDamageEffect(mor), Duration.OneUse, false);
this.addTarget(new TargetPermanent(0, 1, filter, false));
}
private BackForMoreReflexiveTriggeredAbility(final BackForMoreReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public BackForMoreReflexiveTriggeredAbility copy() {
return new BackForMoreReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you do, it fights up to one target creature you don't control.";
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new BackForMoreDamageEffect(new MageObjectReference(permanent, game)),
false, "it fights up to one target creature you don't control"
);
ability.addTarget(new TargetPermanent(0, 1, filter, false));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}

View file

@ -3,19 +3,20 @@ package mage.cards.c;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfPreCombatMainTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.*;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledPermanent;
@ -39,16 +40,17 @@ public final class CabalTherapist extends CardImpl {
this.addAbility(new MenaceAbility());
// At the beginning of your precombat main phase, you may sacrifice a creature. When you do, choose a nonland card name, then target player reveals their hand and discards all cards with that name.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME),
false, "choose a nonland card name, then target player " +
"reveals their hand and discards all cards with that name."
);
ability.addEffect(new CabalTherapistDiscardEffect());
ability.addTarget(new TargetPlayer());
this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(
new DoIfCostPaid(
new CabalTherapistCreateReflexiveTriggerEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(
StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT
)), "Sacrifice a creature?"
).setText("you may sacrifice a creature. When you do, " +
"choose a nonland card name, then target player reveals their hand " +
"and discards all cards with that name."),
TargetController.YOU, false
new DoWhenCostPaid(ability, new SacrificeTargetCost(
new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)
), "Sacrifice a creature?"), TargetController.YOU, false
));
}
@ -62,62 +64,6 @@ public final class CabalTherapist extends CardImpl {
}
}
class CabalTherapistCreateReflexiveTriggerEffect extends OneShotEffect {
CabalTherapistCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
private CabalTherapistCreateReflexiveTriggerEffect(final CabalTherapistCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public CabalTherapistCreateReflexiveTriggerEffect copy() {
return new CabalTherapistCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new CabalTherapistReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class CabalTherapistReflexiveTriggeredAbility extends DelayedTriggeredAbility {
CabalTherapistReflexiveTriggeredAbility() {
super(new ChooseACardNameEffect(ChooseACardNameEffect.TypeOfName.NON_LAND_NAME), Duration.OneUse, true);
this.addEffect(new CabalTherapistDiscardEffect());
this.addTarget(new TargetPlayer());
}
private CabalTherapistReflexiveTriggeredAbility(final CabalTherapistReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public CabalTherapistReflexiveTriggeredAbility copy() {
return new CabalTherapistReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Choose a nonland card name, then target player reveals their hand and discards all cards with that name.";
}
}
class CabalTherapistDiscardEffect extends OneShotEffect {
CabalTherapistDiscardEffect() {
@ -155,9 +101,8 @@ class CabalTherapistDiscardEffect extends OneShotEffect {
if (CardUtil.haveSameNames(card.getName(), cardName)) {
return false;
}
return true;
});
targetPlayer.discard(hand, source, game);
}
targetPlayer.revealCards(source, hand, game);
return true;
}

View file

@ -2,27 +2,25 @@ package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
@ -56,10 +54,14 @@ public final class CavalierOfNight extends CardImpl {
this.addAbility(LifelinkAbility.getInstance());
// When Cavalier of Night enters the battlefield, you may sacrifice another creature. When you do, destroy target creature an opponent controls.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoIfCostPaid(
new CavalierOfNightCreateReflexiveTriggerEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(filter))
).setText("you may sacrifice another creature. When you do, destroy target creature an opponent controls.")));
ReflexiveTriggeredAbility triggeredAbility = new ReflexiveTriggeredAbility(
new DestroyTargetEffect(), false, "Sacrifice a creature?"
);
triggeredAbility.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
triggeredAbility, new SacrificeTargetCost(new TargetControlledPermanent(filter)),
"destroy target creature an opponent controls"
)));
// When Cavalier of Night dies, return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.
Ability ability = new DiesTriggeredAbility(new ReturnFromGraveyardToBattlefieldTargetEffect());
@ -76,58 +78,3 @@ public final class CavalierOfNight extends CardImpl {
return new CavalierOfNight(this);
}
}
class CavalierOfNightCreateReflexiveTriggerEffect extends OneShotEffect {
CavalierOfNightCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
private CavalierOfNightCreateReflexiveTriggerEffect(final CavalierOfNightCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public CavalierOfNightCreateReflexiveTriggerEffect copy() {
return new CavalierOfNightCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new CavalierOfNightReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class CavalierOfNightReflexiveTriggeredAbility extends DelayedTriggeredAbility {
CavalierOfNightReflexiveTriggeredAbility() {
super(new DestroyTargetEffect(), Duration.OneUse, true);
this.addTarget(new TargetOpponentsCreaturePermanent());
}
private CavalierOfNightReflexiveTriggeredAbility(final CavalierOfNightReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public CavalierOfNightReflexiveTriggeredAbility copy() {
return new CavalierOfNightReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Destroy target creature an opponent controls";
}
}

View file

@ -1,30 +1,28 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterNonlandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class DreamEater extends CardImpl {
@ -44,14 +42,12 @@ public final class DreamEater extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Dream Eater enters the battlefield, surveil 4. When you do, you may return target nonland permanent an opponent controls to its owner's hand.
Ability ability = new EntersBattlefieldTriggeredAbility(
new SurveilEffect(4)
);
ability.addEffect(new DreamEaterCreateReflexiveTriggerEffect());
Ability ability = new EntersBattlefieldTriggeredAbility(new SurveilEffect(4));
ability.addEffect(new DreamEaterEffect());
this.addAbility(ability);
}
public DreamEater(final DreamEater card) {
private DreamEater(final DreamEater card) {
super(card);
}
@ -61,31 +57,7 @@ public final class DreamEater extends CardImpl {
}
}
class DreamEaterCreateReflexiveTriggerEffect extends OneShotEffect {
public DreamEaterCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
this.staticText = "When you do, you may return target "
+ "nonland permanent an opponent controls to its owner's hand.";
}
public DreamEaterCreateReflexiveTriggerEffect(final DreamEaterCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public DreamEaterCreateReflexiveTriggerEffect copy() {
return new DreamEaterCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new DreamEaterReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class DreamEaterReflexiveTriggeredAbility extends DelayedTriggeredAbility {
class DreamEaterEffect extends OneShotEffect {
private static final FilterPermanent filter
= new FilterNonlandPermanent("nonland permanent an opponent controls");
@ -94,35 +66,29 @@ class DreamEaterReflexiveTriggeredAbility extends DelayedTriggeredAbility {
filter.add(TargetController.OPPONENT.getControllerPredicate());
}
public DreamEaterReflexiveTriggeredAbility() {
super(new ReturnToHandTargetEffect());
this.addTarget(new TargetPermanent(filter));
this.optional = true;
DreamEaterEffect() {
super(Outcome.Benefit);
this.staticText = "When you do, you may return target "
+ "nonland permanent an opponent controls to its owner's hand.";
}
public DreamEaterReflexiveTriggeredAbility(final DreamEaterReflexiveTriggeredAbility ability) {
super(ability);
private DreamEaterEffect(final DreamEaterEffect effect) {
super(effect);
}
@Override
public DreamEaterReflexiveTriggeredAbility copy() {
return new DreamEaterReflexiveTriggeredAbility(this);
public DreamEaterEffect copy() {
return new DreamEaterEffect(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you surveil 4, you may return target nonland permanent "
+ "an opponent controls to its owner's hand.";
public boolean apply(Game game, Ability source) {
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new ReturnToHandTargetEffect(), true,
"you may return target nonland permanent an opponent controls to its owner's hand"
);
ability.addTarget(new TargetPermanent(filter));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}

View file

@ -1,24 +1,17 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.CycleControllerTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -28,50 +21,6 @@ import java.util.UUID;
*/
public final class EscapeProtocol extends CardImpl {
public EscapeProtocol(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
// Whenever you cycle a card, you may pay {1}. When you do, exile target artifact or creature you control, then return it to the battlefield under its owner's control.
this.addAbility(new CycleControllerTriggeredAbility(new DoIfCostPaid(
new EscapeProtocolEffect(), new GenericManaCost(1)
).setText("you may pay {1}. When you do, exile target artifact or creature you control, " +
"then return it to the battlefield under its owner's control.")));
}
private EscapeProtocol(final EscapeProtocol card) {
super(card);
}
@Override
public EscapeProtocol copy() {
return new EscapeProtocol(this);
}
}
class EscapeProtocolEffect extends OneShotEffect {
EscapeProtocolEffect() {
super(Outcome.Benefit);
}
private EscapeProtocolEffect(final EscapeProtocolEffect effect) {
super(effect);
}
@Override
public EscapeProtocolEffect copy() {
return new EscapeProtocolEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new EscapeProtocolReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class EscapeProtocolReflexiveTriggeredAbility extends DelayedTriggeredAbility {
private static final FilterPermanent filter
= new FilterControlledPermanent("artifact or creature you control");
@ -82,35 +31,28 @@ class EscapeProtocolReflexiveTriggeredAbility extends DelayedTriggeredAbility {
));
}
EscapeProtocolReflexiveTriggeredAbility() {
super(new ExileTargetForSourceEffect(), Duration.OneUse, true);
this.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect());
this.addTarget(new TargetPermanent(filter));
public EscapeProtocol(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
// Whenever you cycle a card, you may pay {1}. When you do, exile target artifact or creature you control, then return it to the battlefield under its owner's control.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new ExileTargetForSourceEffect(), false,
"exile target artifact or creature you control, " +
"then return it to the battlefield under its owner's control."
);
ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(new CycleControllerTriggeredAbility(new DoWhenCostPaid(
ability, new GenericManaCost(1), "Pay {1}?"
)));
}
private EscapeProtocolReflexiveTriggeredAbility(final EscapeProtocolReflexiveTriggeredAbility ability) {
super(ability);
private EscapeProtocol(final EscapeProtocol card) {
super(card);
}
@Override
public EscapeProtocolReflexiveTriggeredAbility copy() {
return new EscapeProtocolReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Exile target artifact or creature you control, " +
"then return it to the battlefield under its owner's control.";
public EscapeProtocol copy() {
return new EscapeProtocol(this);
}
}

View file

@ -1,21 +1,18 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetOpponentOrPlaneswalker;
@ -38,15 +35,15 @@ public final class FirebladeArtist extends CardImpl {
this.addAbility(HasteAbility.getInstance());
// At the beginning of your upkeep, you may sacrifice a creature. When you do, Fireblade Artist deals 2 damage to target opponent or planeswalker.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(2), false,
"{this} deals 2 damage to target opponent or planeswalker"
);
ability.addTarget(new TargetOpponentOrPlaneswalker());
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new DoIfCostPaid(
new FirebladeArtistCreateReflexiveTriggerEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(
StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT
)), "Sacrifice a creature to deal 2 damage to an opponent or planeswalker?"
).setText("you may sacrifice a creature. When you do, " +
"{this} deals 2 damage to target opponent or planeswalker."),
TargetController.YOU, false
new DoWhenCostPaid(ability, new SacrificeTargetCost(
new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT)
), "Sacrifice a creature?"), TargetController.YOU, false
));
}
@ -59,58 +56,3 @@ public final class FirebladeArtist extends CardImpl {
return new FirebladeArtist(this);
}
}
class FirebladeArtistCreateReflexiveTriggerEffect extends OneShotEffect {
FirebladeArtistCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
private FirebladeArtistCreateReflexiveTriggerEffect(final FirebladeArtistCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public FirebladeArtistCreateReflexiveTriggerEffect copy() {
return new FirebladeArtistCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new FirebladeArtistReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class FirebladeArtistReflexiveTriggeredAbility extends DelayedTriggeredAbility {
FirebladeArtistReflexiveTriggeredAbility() {
super(new DamageTargetEffect(2), Duration.OneUse, true);
this.addTarget(new TargetOpponentOrPlaneswalker());
}
private FirebladeArtistReflexiveTriggeredAbility(final FirebladeArtistReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public FirebladeArtistReflexiveTriggeredAbility copy() {
return new FirebladeArtistReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "{this} deals 2 damage to target opponent or planeswalker.";
}
}

View file

@ -1,24 +1,17 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.cards.AdventureCard;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.token.BearToken;
import mage.target.TargetPermanent;
@ -38,9 +31,13 @@ public final class FlaxenIntruder extends AdventureCard {
this.toughness = new MageInt(2);
// Whenever Flaxen Intruder deals combat damage to a player, you may sacrifice it. When you do, destroy target artifact or enchantment.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DoIfCostPaid(
new FlaxenIntruderCreateReflexiveTriggerEffect(), new SacrificeSourceCost()
).setText("you may sacrifice it. When you do, destroy target artifact or enchantment."), false));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DestroyTargetEffect(), false, "destroy target artifact or enchantment"
);
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DoWhenCostPaid(
ability, new SacrificeSourceCost(), "Sacrifice {this}?"
), false));
// Welcome Home
// Create three 2/2 green Bear creature tokens.
@ -56,58 +53,3 @@ public final class FlaxenIntruder extends AdventureCard {
return new FlaxenIntruder(this);
}
}
class FlaxenIntruderCreateReflexiveTriggerEffect extends OneShotEffect {
FlaxenIntruderCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
private FlaxenIntruderCreateReflexiveTriggerEffect(final FlaxenIntruderCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public FlaxenIntruderCreateReflexiveTriggerEffect copy() {
return new FlaxenIntruderCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new FlaxenIntruderReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class FlaxenIntruderReflexiveTriggeredAbility extends DelayedTriggeredAbility {
FlaxenIntruderReflexiveTriggeredAbility() {
super(new DestroyTargetEffect(), Duration.OneUse, true);
this.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
}
private FlaxenIntruderReflexiveTriggeredAbility(final FlaxenIntruderReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public FlaxenIntruderReflexiveTriggeredAbility copy() {
return new FlaxenIntruderReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you do, destroy target artifact or enchantment.";
}
}

View file

@ -1,32 +1,29 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.keyword.EmbalmAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public final class HeartPiercerManticore extends CardImpl {
@ -39,16 +36,13 @@ public final class HeartPiercerManticore extends CardImpl {
this.toughness = new MageInt(3);
// When Heart-Piercer Manticore enters the battlefield, you may sacrifice another creature. When you do, Heart-Piercer Manticore deals damage equal to that creature's power to any target.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new HeartPiercerManticoreSacrificeEffect(), true
));
this.addAbility(new EntersBattlefieldTriggeredAbility(new HeartPiercerManticoreSacrificeEffect(), true));
// Embalm {5}{R}
this.addAbility(new EmbalmAbility(new ManaCostsImpl("{5}{R}"), this));
}
public HeartPiercerManticore(final HeartPiercerManticore card) {
private HeartPiercerManticore(final HeartPiercerManticore card) {
super(card);
}
@ -60,13 +54,13 @@ public final class HeartPiercerManticore extends CardImpl {
class HeartPiercerManticoreSacrificeEffect extends OneShotEffect {
public HeartPiercerManticoreSacrificeEffect() {
HeartPiercerManticoreSacrificeEffect() {
super(Outcome.Damage);
this.staticText = "sacrifice another creature. When you do, "
+ "{this} deals damage equal to that creature's power to any target";
}
public HeartPiercerManticoreSacrificeEffect(final HeartPiercerManticoreSacrificeEffect effect) {
private HeartPiercerManticoreSacrificeEffect(final HeartPiercerManticoreSacrificeEffect effect) {
super(effect);
}
@ -78,54 +72,29 @@ class HeartPiercerManticoreSacrificeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Target target = new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true);
if (controller.choose(outcome, target, source.getSourceId(), game)) {
Permanent toSacrifice = game.getPermanent(target.getFirstTarget());
if (toSacrifice != null) {
DelayedTriggeredAbility trigger = new HeartPiercerManticoreReflexiveTriggeredAbility(toSacrifice.getPower().getValue());
if (toSacrifice.sacrifice(source.getSourceId(), game)) {
game.addDelayedTriggeredAbility(trigger, source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
}
return true;
if (controller == null) {
return false;
}
return false;
}
}
class HeartPiercerManticoreReflexiveTriggeredAbility extends DelayedTriggeredAbility {
public HeartPiercerManticoreReflexiveTriggeredAbility(int damage) {
super(new DamageTargetEffect(damage), Duration.OneUse, true);
this.addTarget(new TargetAnyTarget());
}
public HeartPiercerManticoreReflexiveTriggeredAbility(final HeartPiercerManticoreReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public HeartPiercerManticoreReflexiveTriggeredAbility copy() {
return new HeartPiercerManticoreReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you sacrifice a creature to {this}'s ability, "
+ "{this} deals damage equal to that creature's power to any target";
Target target = new TargetControlledCreaturePermanent(
1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true
);
if (!controller.choose(outcome, target, source.getSourceId(), game)) {
return false;
}
Permanent toSacrifice = game.getPermanent(target.getFirstTarget());
if (toSacrifice == null) {
return false;
}
int power = toSacrifice.getPower().getValue();
if (!toSacrifice.sacrifice(source.getSourceId(), game)) {
return false;
}
ReflexiveTriggeredAbility trigger = new ReflexiveTriggeredAbility(
new DamageTargetEffect(power), false,
"{this} deals damage equal to that creature's power to any target."
);
trigger.addTarget(new TargetAnyTarget());
game.fireReflexiveTriggeredAbility(trigger, source);
return true;
}
}

View file

@ -1,26 +1,19 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class Hypothesizzle extends CardImpl {
@ -30,15 +23,19 @@ public final class Hypothesizzle extends CardImpl {
// Draw two cards. Then you may discard a nonland card. When you do, Hypothesizzle deals 4 damage to target creature.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2));
this.getSpellAbility().addEffect(new DoIfCostPaid(
new HypothesizzleCreateReflexiveTriggerEffect(),
new DiscardCardCost(StaticFilters.FILTER_CARD_A_NON_LAND),
"Discard a nonland card to deal 4 damage?"
).setText("Then you may discard a nonland card. "
+ "When you do, {this} deals 4 damage to target creature."));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(4), false,
"{this} deals 4 damage to target creature"
);
ability.addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DoWhenCostPaid(
ability, new DiscardCardCost(StaticFilters.FILTER_CARD_A_NON_LAND),
"Discard a nonland card?"
).concatBy("Then"));
}
public Hypothesizzle(final Hypothesizzle card) {
private Hypothesizzle(final Hypothesizzle card) {
super(card);
}
@ -47,60 +44,3 @@ public final class Hypothesizzle extends CardImpl {
return new Hypothesizzle(this);
}
}
class HypothesizzleCreateReflexiveTriggerEffect extends OneShotEffect {
public HypothesizzleCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
this.staticText = "When you do, it deals 4 damage to target creature";
}
public HypothesizzleCreateReflexiveTriggerEffect(final HypothesizzleCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public HypothesizzleCreateReflexiveTriggerEffect copy() {
return new HypothesizzleCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new HypothesizzleReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class HypothesizzleReflexiveTriggeredAbility extends DelayedTriggeredAbility {
public HypothesizzleReflexiveTriggeredAbility() {
super(new DamageTargetEffect(4), Duration.OneUse, true);
this.addTarget(new TargetCreaturePermanent());
}
public HypothesizzleReflexiveTriggeredAbility(final HypothesizzleReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public HypothesizzleReflexiveTriggeredAbility copy() {
return new HypothesizzleReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you discard a nonland card, "
+ "{this} deals 4 damage to target creature";
}
}

View file

@ -1,27 +1,19 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.counters.Counters;
import mage.filter.FilterCard;
@ -33,8 +25,9 @@ import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class IsarethTheAwakener extends CardImpl {
@ -55,7 +48,7 @@ public final class IsarethTheAwakener extends CardImpl {
this.addAbility(new AttacksTriggeredAbility(new IsarethTheAwakenerCreateReflexiveTriggerEffect(), false));
}
public IsarethTheAwakener(final IsarethTheAwakener card) {
private IsarethTheAwakener(final IsarethTheAwakener card) {
super(card);
}
@ -67,15 +60,17 @@ public final class IsarethTheAwakener extends CardImpl {
class IsarethTheAwakenerCreateReflexiveTriggerEffect extends OneShotEffect {
public IsarethTheAwakenerCreateReflexiveTriggerEffect() {
private static final String rule = "return target creature card "
+ "with converted mana cost X from your graveyard to the battlefield "
+ "with a corpse counter on it. If that creature would leave the battlefield, "
+ "exile it instead of putting it anywhere else.";
IsarethTheAwakenerCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
this.staticText = "you may pay {X}. When you do, return target creature card "
+ "with converted mana cost X from your graveyard to the battlefield "
+ "with a corpse counter on it. If that creature would leave the battlefield, "
+ "exile it instead of putting it anywhere else.";
this.staticText = "you may pay {X}. When you do, " + rule;
}
public IsarethTheAwakenerCreateReflexiveTriggerEffect(final IsarethTheAwakenerCreateReflexiveTriggerEffect effect) {
private IsarethTheAwakenerCreateReflexiveTriggerEffect(final IsarethTheAwakenerCreateReflexiveTriggerEffect effect) {
super(effect);
}
@ -97,67 +92,34 @@ class IsarethTheAwakenerCreateReflexiveTriggerEffect extends OneShotEffect {
if (!cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
return false;
}
game.addDelayedTriggeredAbility(new IsarethTheAwakenerReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect(costX).apply(game, source);
}
}
class IsarethTheAwakenerReflexiveTriggeredAbility extends DelayedTriggeredAbility {
public IsarethTheAwakenerReflexiveTriggeredAbility() {
super(new IsarethTheAwakenerEffect(), Duration.OneUse, true);
this.addEffect(new IsarethTheAwakenerReplacementEffect());
}
public IsarethTheAwakenerReflexiveTriggeredAbility(final IsarethTheAwakenerReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public IsarethTheAwakenerReflexiveTriggeredAbility copy() {
return new IsarethTheAwakenerReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!event.getPlayerId().equals(this.getControllerId())
|| !event.getSourceId().equals(this.getSourceId())) {
return false;
}
FilterCard filter = new FilterCreatureCard(
"creature card with converted mana cost "
+ event.getAmount()
+ " or less from your graveyard"
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new IsarethTheAwakenerEffect(), false, rule
);
filter.add(new ConvertedManaCostPredicate(
ComparisonType.FEWER_THAN, event.getAmount() + 1
));
this.getTargets().clear();
this.addTarget(new TargetCardInYourGraveyard(filter));
ability.addEffect(new IsarethTheAwakenerReplacementEffect());
ability.addTarget(new TargetCardInYourGraveyard(makeFilter(costX)));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
@Override
public String getRule() {
return "When you pay {X}, return target creature card "
+ "with converted mana cost X from your graveyard to the battlefield "
+ "with a corpse counter on it. If that creature would leave the battlefield, "
+ "exile it instead of putting it anywhere else.";
private static FilterCard makeFilter(int xValue) {
FilterCard filter = new FilterCreatureCard(
"creature card with converted mana cost " +
xValue + " or less from your graveyard"
);
filter.add(new ConvertedManaCostPredicate(
ComparisonType.EQUAL_TO, xValue
));
return filter;
}
}
class IsarethTheAwakenerEffect extends OneShotEffect {
public IsarethTheAwakenerEffect() {
IsarethTheAwakenerEffect() {
super(Outcome.PutCreatureInPlay);
}
public IsarethTheAwakenerEffect(final IsarethTheAwakenerEffect effect) {
private IsarethTheAwakenerEffect(final IsarethTheAwakenerEffect effect) {
super(effect);
}
@ -182,11 +144,11 @@ class IsarethTheAwakenerEffect extends OneShotEffect {
class IsarethTheAwakenerReplacementEffect extends ReplacementEffectImpl {
public IsarethTheAwakenerReplacementEffect() {
IsarethTheAwakenerReplacementEffect() {
super(Duration.Custom, Outcome.Exile);
}
public IsarethTheAwakenerReplacementEffect(final IsarethTheAwakenerReplacementEffect effect) {
private IsarethTheAwakenerReplacementEffect(final IsarethTheAwakenerReplacementEffect effect) {
super(effect);
}

View file

@ -2,22 +2,23 @@ package mage.cards.l;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -93,45 +94,17 @@ class LavabrinkFloodgatesEffect extends OneShotEffect {
break;
case "Do nothing":
default:
return false;
break;
}
if (permanent.getCounters(game).getCount(CounterType.DOOM) < 3
|| !permanent.sacrifice(source.getSourceId(), game)) {
return true;
}
game.addDelayedTriggeredAbility(new LavabrinkFloodgatesReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class LavabrinkFloodgatesReflexiveTriggeredAbility extends DelayedTriggeredAbility {
LavabrinkFloodgatesReflexiveTriggeredAbility() {
super(new DamageAllEffect(6, StaticFilters.FILTER_PERMANENT_CREATURE), Duration.OneUse, true);
}
private LavabrinkFloodgatesReflexiveTriggeredAbility(final LavabrinkFloodgatesReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public LavabrinkFloodgatesReflexiveTriggeredAbility copy() {
return new LavabrinkFloodgatesReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "It deals 6 damage to each creature.";
game.fireReflexiveTriggeredAbility(new ReflexiveTriggeredAbility(
new DamageAllEffect(
6, StaticFilters.FILTER_PERMANENT_CREATURE
), false, "it deals 6 damage to each creature."
), source);
return true;
}
}

View file

@ -3,25 +3,26 @@ package mage.cards.n;
import mage.ConditionalMana;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.SpellAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.Cost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.mana.conditional.ManaCondition;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.*;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.game.Game;
import mage.game.command.emblems.NarsetOfTheAncientWayEmblem;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.common.TargetCreatureOrPlaneswalker;
@ -141,41 +142,12 @@ class NarsetOfTheAncientWayDrawEffect extends OneShotEffect {
if (card == null || card.isLand()) {
return false;
}
game.addDelayedTriggeredAbility(new NarsetOfTheAncientWayReflexiveTriggeredAbility(card.getConvertedManaCost()), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class NarsetOfTheAncientWayReflexiveTriggeredAbility extends DelayedTriggeredAbility {
NarsetOfTheAncientWayReflexiveTriggeredAbility(int cmc) {
super(new DamageTargetEffect(cmc), Duration.OneUse, true);
this.addTarget(new TargetCreatureOrPlaneswalker());
}
private NarsetOfTheAncientWayReflexiveTriggeredAbility(final NarsetOfTheAncientWayReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public NarsetOfTheAncientWayReflexiveTriggeredAbility copy() {
return new NarsetOfTheAncientWayReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "{this} deals damage to target creature or planeswalker " +
"equal to the discarded card's converted mana cost";
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(card.getConvertedManaCost()), false, "{this} deals damage " +
"to target creature or planeswalker equal to the discarded card's converted mana cost"
);
ability.addTarget(new TargetCreatureOrPlaneswalker());
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}

View file

@ -1,23 +1,16 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.CycleControllerTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -35,12 +28,15 @@ public final class SavaiThundermane extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Whenever you cycle a card, you may pay {2}. When you do Savai Thundermane deals 2 damage to target creature and you gain 2 life.
// Whenever you cycle a card, you may pay {2}. When you do, Savai Thundermane deals 2 damage to target creature and you gain 2 life.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(2), false,
"{this} deals 2 damage to target creature and you gain 2 life"
);
ability.addEffect(new GainLifeEffect(2));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(new CycleControllerTriggeredAbility(
new DoIfCostPaid(
new SavaiThundermaneCreateReflexiveTriggerEffect(), new GenericManaCost(2),
"Pay {2} to deal 2 damage and gain 2 life?"
).setText("you may pay {2}. When you do, {this} deals 2 damage to target creature and you gain 2 life")
new DoWhenCostPaid(ability, new GenericManaCost(2), "Pay {2}?")
));
}
@ -53,59 +49,3 @@ public final class SavaiThundermane extends CardImpl {
return new SavaiThundermane(this);
}
}
class SavaiThundermaneCreateReflexiveTriggerEffect extends OneShotEffect {
SavaiThundermaneCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
private SavaiThundermaneCreateReflexiveTriggerEffect(final SavaiThundermaneCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public SavaiThundermaneCreateReflexiveTriggerEffect copy() {
return new SavaiThundermaneCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new SavaiThundermaneReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class SavaiThundermaneReflexiveTriggeredAbility extends DelayedTriggeredAbility {
SavaiThundermaneReflexiveTriggeredAbility() {
super(new DamageTargetEffect(2), Duration.OneUse, true);
this.addEffect(new GainLifeEffect(2));
this.addTarget(new TargetCreaturePermanent());
}
private SavaiThundermaneReflexiveTriggeredAbility(final SavaiThundermaneReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public SavaiThundermaneReflexiveTriggeredAbility copy() {
return new SavaiThundermaneReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "{this} deals 2 damage to target creature and you gain 2 life";
}
}

View file

@ -1,37 +1,38 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class SkyriderPatrol extends CardImpl {
private static final FilterControlledCreaturePermanent filter
= new FilterControlledCreaturePermanent("another creature you control");
static {
filter.add(AnotherPredicate.instance);
}
public SkyriderPatrol(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
@ -44,20 +45,19 @@ public final class SkyriderPatrol extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// At the beginning of combat on your turn, you may pay {G}{U}. When you do, put a +1/+1 counter on another target creature you control, and that creature gains flying until end of turn.
this.addAbility(new BeginningOfCombatTriggeredAbility(
new DoIfCostPaid(
new SkyriderPatrolCreateReflexiveTriggerEffect(),
new ManaCostsImpl("{G}{U}"),
"Pay {G}{U} to put a +1/+1 counter on another"
+ " creature you control and give it flying?"
).setText("you may pay {G}{U}. When you do, "
+ "put a +1/+1 counter on another target creature you control, "
+ "and that creature gains flying until end of turn."),
TargetController.YOU, false
));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false,
"put a +1/+1 counter on another target creature you control, " +
"and that creature gains flying until end of turn"
);
ability.addEffect(new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn));
ability.addTarget(new TargetPermanent(filter));
this.addAbility(new BeginningOfCombatTriggeredAbility(new DoWhenCostPaid(
ability, new ManaCostsImpl("{G}{U}"), "Pay {G}{U}?"
), TargetController.YOU, false));
}
public SkyriderPatrol(final SkyriderPatrol card) {
private SkyriderPatrol(final SkyriderPatrol card) {
super(card);
}
@ -66,71 +66,3 @@ public final class SkyriderPatrol extends CardImpl {
return new SkyriderPatrol(this);
}
}
class SkyriderPatrolCreateReflexiveTriggerEffect extends OneShotEffect {
public SkyriderPatrolCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
}
public SkyriderPatrolCreateReflexiveTriggerEffect(final SkyriderPatrolCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public SkyriderPatrolCreateReflexiveTriggerEffect copy() {
return new SkyriderPatrolCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new SkyriderPatrolReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class SkyriderPatrolReflexiveTriggeredAbility extends DelayedTriggeredAbility {
private static final FilterControlledCreaturePermanent filter
= new FilterControlledCreaturePermanent("another creature you control");
static {
filter.add(AnotherPredicate.instance);
}
public SkyriderPatrolReflexiveTriggeredAbility() {
super(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), Duration.OneUse, true);
this.addEffect(new GainAbilityTargetEffect(
FlyingAbility.getInstance(),
Duration.EndOfTurn
));
this.addTarget(new TargetPermanent(filter));
}
public SkyriderPatrolReflexiveTriggeredAbility(final SkyriderPatrolReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public SkyriderPatrolReflexiveTriggeredAbility copy() {
return new SkyriderPatrolReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you pay {G}{U}, put a +1/+1 counter "
+ "on another target creature you control, "
+ "and that creature gains flying until end of turn.";
}
}

View file

@ -1,12 +1,15 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.*;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.LifelinkAbility;
@ -21,7 +24,6 @@ import mage.filter.FilterCard;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetControlledCreaturePermanent;
@ -58,11 +60,16 @@ public final class SorinImperiousBloodlord extends CardImpl {
this.addAbility(ability);
// +1: You may sacrifice a Vampire. When you do, Sorin, Imperious Bloodlord deals 3 damage to any target and you gain 3 life.
this.addAbility(new LoyaltyAbility(new DoIfCostPaid(
new SorinImperiousBloodlordCreateReflexiveTriggerEffect(),
new SacrificeTargetCost(new TargetControlledPermanent(filter))
).setText("You may sacrifice a Vampire. " +
"When you do, {this} deals 3 damage to any target and you gain 3 life."
ReflexiveTriggeredAbility triggeredAbility = new ReflexiveTriggeredAbility(
new DamageTargetEffect(3), false,
"{this} deals 3 damage to any target and you gain 3 life"
);
triggeredAbility.addEffect(new GainLifeEffect(3));
triggeredAbility.addTarget(new TargetAnyTarget());
this.addAbility(new LoyaltyAbility(new DoWhenCostPaid(
triggeredAbility,
new SacrificeTargetCost(new TargetControlledPermanent(filter)),
"Sacrifice a Vampire?"
), 1));
// 3: You may put a Vampire creature card from your hand onto the battlefield.
@ -110,58 +117,3 @@ class SorinImperiousBloodlordEffect extends OneShotEffect {
return true;
}
}
class SorinImperiousBloodlordCreateReflexiveTriggerEffect extends OneShotEffect {
SorinImperiousBloodlordCreateReflexiveTriggerEffect() {
super(Benefit);
}
private SorinImperiousBloodlordCreateReflexiveTriggerEffect(final SorinImperiousBloodlordCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public SorinImperiousBloodlordCreateReflexiveTriggerEffect copy() {
return new SorinImperiousBloodlordCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new SorinImperiousBloodlordReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class SorinImperiousBloodlordReflexiveTriggeredAbility extends DelayedTriggeredAbility {
SorinImperiousBloodlordReflexiveTriggeredAbility() {
super(new DamageTargetEffect(3), Duration.OneUse, true);
this.addEffect(new GainLifeEffect(3));
this.addTarget(new TargetAnyTarget());
}
private SorinImperiousBloodlordReflexiveTriggeredAbility(final SorinImperiousBloodlordReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public SorinImperiousBloodlordReflexiveTriggeredAbility copy() {
return new SorinImperiousBloodlordReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "{this} deals 3 damage to any target and you gain 3 life";
}
}

View file

@ -1,28 +1,21 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.constants.SubType;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.keyword.FlyingAbility;
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.events.GameEvent;
import mage.constants.SubType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class SparktongueDragon extends CardImpl {
@ -38,16 +31,18 @@ public final class SparktongueDragon extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Sparktongue Dragon enters the battlefield, you may pay {2}{R}. When you do, it deals 3 damage to any target.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DoIfCostPaid(
new SparktongueDragonCreateReflexiveTriggerEffect(),
new ManaCostsImpl("{2}{R}"),
"Pay {2}{R} to deal 3 damage?"
).setText("you may pay {2}{R}. When you do, it deals 3 damage to any target")
));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(3), false,
"it deals 3 damage to any target"
);
ability.addTarget(new TargetAnyTarget());
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new ManaCostsImpl("{2}{R}"),
"Pay {2}{R} to deal 3 damage?"
)));
}
public SparktongueDragon(final SparktongueDragon card) {
private SparktongueDragon(final SparktongueDragon card) {
super(card);
}
@ -56,59 +51,3 @@ public final class SparktongueDragon extends CardImpl {
return new SparktongueDragon(this);
}
}
class SparktongueDragonCreateReflexiveTriggerEffect extends OneShotEffect {
public SparktongueDragonCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
this.staticText = "When you do, it deals 3 damage to any target";
}
public SparktongueDragonCreateReflexiveTriggerEffect(final SparktongueDragonCreateReflexiveTriggerEffect effect) {
super(effect);
}
@Override
public SparktongueDragonCreateReflexiveTriggerEffect copy() {
return new SparktongueDragonCreateReflexiveTriggerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.addDelayedTriggeredAbility(new SparktongueDragonReflexiveTriggeredAbility(), source);
return new SendOptionUsedEventEffect().apply(game, source);
}
}
class SparktongueDragonReflexiveTriggeredAbility extends DelayedTriggeredAbility {
public SparktongueDragonReflexiveTriggeredAbility() {
super(new DamageTargetEffect(3), Duration.OneUse, true);
this.addTarget(new TargetAnyTarget());
}
public SparktongueDragonReflexiveTriggeredAbility(final SparktongueDragonReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public SparktongueDragonReflexiveTriggeredAbility copy() {
return new SparktongueDragonReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you pay {2}{R}, {this} deals 3 damage to any target";
}
}

View file

@ -1,9 +1,9 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
@ -18,7 +18,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
@ -89,41 +88,12 @@ class TheRoyalScionsCreateReflexiveTriggerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
effect.apply(game, source);
game.addDelayedTriggeredAbility(new TheRoyalScionsReflexiveTriggeredAbility(), source);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId(), 0));
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DamageTargetEffect(CardsInControllerHandCount.instance), false,
"{this} deals damage to any target equal to the number of cards in your hand"
);
ability.addTarget(new TargetAnyTarget());
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}
class TheRoyalScionsReflexiveTriggeredAbility extends DelayedTriggeredAbility {
TheRoyalScionsReflexiveTriggeredAbility() {
super(new DamageTargetEffect(CardsInControllerHandCount.instance), Duration.OneUse, true);
this.addTarget(new TargetAnyTarget());
}
private TheRoyalScionsReflexiveTriggeredAbility(final TheRoyalScionsReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public TheRoyalScionsReflexiveTriggeredAbility copy() {
return new TheRoyalScionsReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you do, {this} deals damage to any target equal to the number of cards in your hand.";
}
}

View file

@ -1,30 +1,24 @@
package mage.cards.v;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.cards.*;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class ViviensInvocation extends CardImpl {
@ -36,7 +30,7 @@ public final class ViviensInvocation extends CardImpl {
this.getSpellAbility().addEffect(new ViviensInvocationEffect());
}
public ViviensInvocation(final ViviensInvocation card) {
private ViviensInvocation(final ViviensInvocation card) {
super(card);
}
@ -48,11 +42,9 @@ public final class ViviensInvocation extends CardImpl {
class ViviensInvocationEffect extends OneShotEffect {
public ViviensInvocationEffect(final ViviensInvocationEffect effect) {
super(effect);
}
private static final FilterCard filter = new FilterCreatureCard("creature card to put on the battlefield");
public ViviensInvocationEffect() {
ViviensInvocationEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Look at the top seven cards of your library. "
+ "You may put a creature card from among them onto the battlefield. "
@ -61,6 +53,10 @@ class ViviensInvocationEffect extends OneShotEffect {
+ "it deals damage equal to its power to target creature an opponent controls";
}
private ViviensInvocationEffect(final ViviensInvocationEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
@ -68,31 +64,32 @@ class ViviensInvocationEffect extends OneShotEffect {
return false;
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 7));
if (!cards.isEmpty()) {
TargetCard target = new TargetCard(
Zone.LIBRARY,
new FilterCreatureCard("creature card to put on the battlefield")
);
target.setNotTarget(true);
if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
game.addDelayedTriggeredAbility(
new ViviensInvocationReflexiveTriggeredAbility(
new MageObjectReference(permanent, game)
), source);
new SendOptionUsedEventEffect().apply(game, source);
}
}
}
if (!cards.isEmpty()) {
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
}
if (cards.isEmpty()) {
return true;
}
TargetCard target = new TargetCard(Zone.LIBRARY, filter);
target.setNotTarget(true);
controller.choose(Outcome.PutCreatureInPlay, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card == null) {
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
cards.remove(card);
}
Permanent permanent = game.getPermanent(card.getId());
if (permanent == null) {
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new ViviensInvocationDamageEffect(new MageObjectReference(permanent, game)), false,
"it deals damage equals to its power to target creature an opponent controls"
);
ability.addTarget(new TargetOpponentsCreaturePermanent());
game.fireReflexiveTriggeredAbility(ability, source);
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
return true;
}
@ -102,50 +99,16 @@ class ViviensInvocationEffect extends OneShotEffect {
}
}
class ViviensInvocationReflexiveTriggeredAbility extends DelayedTriggeredAbility {
public ViviensInvocationReflexiveTriggeredAbility(MageObjectReference mor) {
super(new ViviensInvocationDamageEffect(mor), Duration.OneUse, false);
this.addTarget(new TargetOpponentsCreaturePermanent());
}
public ViviensInvocationReflexiveTriggeredAbility(final ViviensInvocationReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public ViviensInvocationReflexiveTriggeredAbility copy() {
return new ViviensInvocationReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When a creature is put onto the battlefield with {this}, "
+ "it deals damage equal to its power to target creature an opponent controls";
}
}
class ViviensInvocationDamageEffect extends OneShotEffect {
private final MageObjectReference mor;
public ViviensInvocationDamageEffect(MageObjectReference mor) {
ViviensInvocationDamageEffect(MageObjectReference mor) {
super(Outcome.Benefit);
this.mor = mor;
}
public ViviensInvocationDamageEffect(final ViviensInvocationDamageEffect effect) {
private ViviensInvocationDamageEffect(final ViviensInvocationDamageEffect effect) {
super(effect);
mor = effect.mor;
}

View file

@ -2,8 +2,8 @@ package mage.cards.w;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -14,7 +14,6 @@ import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
@ -23,7 +22,6 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import java.util.UUID;
@ -74,11 +72,11 @@ class WildbornPreserverCreateReflexiveTriggerEffect extends OneShotEffect {
WildbornPreserverCreateReflexiveTriggerEffect() {
super(Outcome.Benefit);
staticText = "you may pay {X}. When you do, put X +1/+1 counters on {this}";
}
private WildbornPreserverCreateReflexiveTriggerEffect(final WildbornPreserverCreateReflexiveTriggerEffect effect) {
super(effect);
staticText = "you may pay {X}. When you do, put X +1/+1 counters on {this}";
}
@Override
@ -101,40 +99,10 @@ class WildbornPreserverCreateReflexiveTriggerEffect extends OneShotEffect {
if (!cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) {
return false;
}
game.addDelayedTriggeredAbility(new WildbornPreserverReflexiveTriggeredAbility(costX), source);
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId(), 0));
game.fireReflexiveTriggeredAbility(new ReflexiveTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(costX)),
false, "put X +1/+1 counters on {this}"
), source);
return true;
}
}
class WildbornPreserverReflexiveTriggeredAbility extends DelayedTriggeredAbility {
WildbornPreserverReflexiveTriggeredAbility(int counters) {
super(new AddCountersSourceEffect(CounterType.P1P1.createInstance(counters)), Duration.OneUse, true);
}
private WildbornPreserverReflexiveTriggeredAbility(final WildbornPreserverReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public WildbornPreserverReflexiveTriggeredAbility copy() {
return new WildbornPreserverReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you do, put X +1/+1 counters on {this}.";
}
}

View file

@ -2,12 +2,11 @@ package mage.cards.y;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.keyword.PartnerWithAbility;
import mage.abilities.keyword.VigilanceAbility;
@ -19,7 +18,6 @@ import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
@ -109,43 +107,15 @@ class YannikScavengingSentinelEffect extends OneShotEffect {
), permanent.getIdName()).setTargetPointer(new FixedTarget(permanent, game)).apply(game, source);
game.addDelayedTriggeredAbility(new OnLeaveReturnExiledToBattlefieldAbility(), source);
if (game.getState().getZone(permanent.getId()) != Zone.BATTLEFIELD) {
game.addDelayedTriggeredAbility(new YannikScavengingSentinelReflexiveTriggeredAbility(power), source);
return new SendOptionUsedEventEffect().apply(game, source);
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new DistributeCountersEffect(
CounterType.P1P1, power, false, ""
), false, "distribute X +1/+1 counters among any number of target creatures, " +
"where X is the exiled creature's power"
);
ability.addTarget(new TargetCreaturePermanentAmount(power));
game.fireReflexiveTriggeredAbility(ability, source);
}
return true;
}
}
class YannikScavengingSentinelReflexiveTriggeredAbility extends DelayedTriggeredAbility {
YannikScavengingSentinelReflexiveTriggeredAbility(int power) {
super(new DistributeCountersEffect(CounterType.P1P1, power, false, ""), Duration.OneUse, true);
this.addTarget(new TargetCreaturePermanentAmount(power));
}
private YannikScavengingSentinelReflexiveTriggeredAbility(final YannikScavengingSentinelReflexiveTriggeredAbility ability) {
super(ability);
}
@Override
public YannikScavengingSentinelReflexiveTriggeredAbility copy() {
return new YannikScavengingSentinelReflexiveTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Distribute X +1/+1 counters among any number of target creatures, " +
"where X is the exiled creature's power.";
}
}

View file

@ -0,0 +1,50 @@
package mage.abilities.common.delayed;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.constants.Duration;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
* @author TheElk801
*/
public class ReflexiveTriggeredAbility extends DelayedTriggeredAbility {
private final String text;
public ReflexiveTriggeredAbility(Effect effect, boolean optional, String text) {
super(effect, Duration.EndOfTurn, true, optional);
this.text = text;
}
protected ReflexiveTriggeredAbility(final ReflexiveTriggeredAbility ability) {
super(ability);
this.text = ability.text;
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return text.substring(0, 1).toUpperCase() + text.substring(1) + '.';
}
public String getText() {
return text;
}
@Override
public ReflexiveTriggeredAbility copy() {
return new ReflexiveTriggeredAbility(this);
}
}

View file

@ -0,0 +1,103 @@
package mage.abilities.effects.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.Locale;
public class DoWhenCostPaid extends OneShotEffect {
private final ReflexiveTriggeredAbility ability;
private final Cost cost;
private final String chooseUseText;
private final boolean optional;
public DoWhenCostPaid(ReflexiveTriggeredAbility ability, Cost cost, String chooseUseText) {
this(ability, cost, chooseUseText, true);
}
public DoWhenCostPaid(ReflexiveTriggeredAbility ability, Cost cost, String chooseUseText, boolean optional) {
super(Outcome.Benefit);
this.ability = ability;
this.cost = cost;
this.chooseUseText = chooseUseText;
this.optional = optional;
}
private DoWhenCostPaid(final DoWhenCostPaid effect) {
super(effect);
this.ability = effect.ability.copy();
this.cost = effect.cost.copy();
this.chooseUseText = effect.chooseUseText;
this.optional = effect.optional;
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getObject(source.getSourceId());
if (player == null || mageObject == null) {
return false;
}
String message = CardUtil.replaceSourceName(chooseUseText, mageObject.getLogName());
Outcome payOutcome = ability.getEffects().getOutcome(source, this.outcome);
if (!cost.canPay(source, source.getSourceId(), player.getId(), game)
|| (optional && !player.chooseUse(payOutcome, message, source, game))) {
return false;
}
cost.clearPaid();
int bookmark = game.bookmarkState();
if (cost.pay(source, game, source.getSourceId(), player.getId(), false)) {
game.fireReflexiveTriggeredAbility(ability, source);
player.resetStoredBookmark(game);
}
return true;
}
public Cost getCost() {
return cost;
}
@Override
public String getText(Mode mode) {
if (!staticText.isEmpty()) {
return staticText;
}
return (optional ? "you may " : "") + getCostText() + ". When you do, " + ability.getText();
}
private String getCostText() {
StringBuilder sb = new StringBuilder();
String costText = cost.getText();
if (costText != null
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("put")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("return")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("exile")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("discard")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("sacrifice")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("remove")
&& !costText.toLowerCase(Locale.ENGLISH).startsWith("pay")) {
sb.append("pay ");
}
return sb.append(costText).toString();
}
@Override
public void setValue(String key, Object value) {
super.setValue(key, value);
ability.getEffects().setValue(key, value);
}
@Override
public DoWhenCostPaid copy() {
return new DoWhenCostPaid(this);
}
}

View file

@ -1,42 +0,0 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
/**
*
* @author LevelX2
*/
public class SendOptionUsedEventEffect extends OneShotEffect {
private final int value;
public SendOptionUsedEventEffect() {
this(0);
}
public SendOptionUsedEventEffect(int value) {
super(Outcome.Detriment);
this.value = value;
}
public SendOptionUsedEventEffect(final SendOptionUsedEventEffect effect) {
super(effect);
this.value = effect.value;
}
@Override
public SendOptionUsedEventEffect copy() {
return new SendOptionUsedEventEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId(), value));
return true;
}
}

View file

@ -6,6 +6,7 @@ import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.effects.PreventionEffectData;
@ -398,6 +399,8 @@ public interface Game extends MageItem, Serializable {
UUID addDelayedTriggeredAbility(DelayedTriggeredAbility delayedAbility, Ability source);
UUID fireReflexiveTriggeredAbility(ReflexiveTriggeredAbility reflexiveAbility, Ability source);
void applyEffects();
boolean checkStateAndTriggered();

View file

@ -6,6 +6,7 @@ import mage.abilities.*;
import mage.abilities.common.AttachableToRestrictedAbility;
import mage.abilities.common.CantHaveMoreThanAmountCountersSourceAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffects;
import mage.abilities.effects.Effect;
@ -1748,6 +1749,13 @@ public abstract class GameImpl implements Game, Serializable {
return newAbility.getId();
}
@Override
public UUID fireReflexiveTriggeredAbility(ReflexiveTriggeredAbility reflexiveAbility, Ability source) {
UUID uuid = this.addDelayedTriggeredAbility(reflexiveAbility, source);
this.fireEvent(GameEvent.getEvent(GameEvent.EventType.OPTION_USED, source.getOriginalId(), source.getSourceId(), source.getControllerId()));
return uuid;
}
/**
* 116.5. Each time a player would get priority, the game first performs all
* applicable state-based actions as a single event (see rule 704,