[40K] Implemented Sister Repentia

This commit is contained in:
Evan Kranzler 2022-09-17 10:30:03 -04:00
parent 9c801056d3
commit a893e5ba88
16 changed files with 109 additions and 85 deletions

View file

@ -1,8 +1,5 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -12,8 +9,9 @@ import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author noxx
*/
public final class BanishingStroke extends CardImpl {
@ -24,7 +22,8 @@ public final class BanishingStroke extends CardImpl {
filter.add(Predicates.or(
CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate(),
CardType.ENCHANTMENT.getPredicate()));
CardType.ENCHANTMENT.getPredicate()
));
}
public BanishingStroke(UUID ownerId, CardSetInfo setInfo) {
@ -36,7 +35,7 @@ public final class BanishingStroke extends CardImpl {
this.getSpellAbility().addTarget(new TargetPermanent(filter));
// Miracle {W}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{W}")));
this.addAbility(new MiracleAbility("{W}"));
}
private BanishingStroke(final BanishingStroke card) {

View file

@ -1,6 +1,5 @@
package mage.cards.b;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -23,7 +22,7 @@ public final class BlessingsOfNature extends CardImpl {
this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.P1P1, 4, false, "any number of target creatures"));
this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(4));
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{G}")));
this.addAbility(new MiracleAbility("{G}"));
}
private BlessingsOfNature(final BlessingsOfNature card) {

View file

@ -1,7 +1,6 @@
package mage.cards.b;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -29,7 +28,7 @@ public final class BonfireOfTheDamned extends CardImpl {
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Miracle {X}{R}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{X}{R}")));
this.addAbility(new MiracleAbility("{X}{R}"));
}
private BonfireOfTheDamned(final BonfireOfTheDamned card) {

View file

@ -1,8 +1,5 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -10,8 +7,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterNonlandPermanent;
import java.util.UUID;
/**
*
* @author noxx
*/
public final class DevastationTide extends CardImpl {
@ -23,7 +21,7 @@ public final class DevastationTide extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandFromBattlefieldAllEffect(new FilterNonlandPermanent("nonland permanents")));
// Miracle {1}{U}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{1}{U}")));
this.addAbility(new MiracleAbility("{1}{U}"));
}
private DevastationTide(final DevastationTide card) {

View file

@ -1,8 +1,5 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.MiracleAbility;
@ -11,10 +8,10 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.permanent.token.AngelToken;
import java.util.UUID;
/**
*
* @author noxx
*
*/
public final class EntreatTheAngels extends CardImpl {
@ -25,7 +22,7 @@ public final class EntreatTheAngels extends CardImpl {
this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken(), ManacostVariableValue.REGULAR));
// Miracle {X}{W}{W}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{X}{W}{W}")));
this.addAbility(new MiracleAbility("{X}{W}{W}"));
}
private EntreatTheAngels(final EntreatTheAngels card) {

View file

@ -1,22 +1,20 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.target.Target;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetadjustment.TargetAdjuster;
import java.util.UUID;
/**
*
* @author TheElk801
*/
public final class EntreatTheDead extends CardImpl {
@ -29,7 +27,7 @@ public final class EntreatTheDead extends CardImpl {
this.getSpellAbility().setTargetAdjuster(EntreatTheDeadAdjuster.instance);
// Miracle {X}{B}{B}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{X}{B}{B}")));
this.addAbility(new MiracleAbility("{X}{B}{B}"));
}
private EntreatTheDead(final EntreatTheDead card) {

View file

@ -1,8 +1,5 @@
package mage.cards.r;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.effects.common.discard.DiscardHandAllEffect;
@ -11,8 +8,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
*
* @author North
*/
public final class ReforgeTheSoul extends CardImpl {
@ -27,7 +25,7 @@ public final class ReforgeTheSoul extends CardImpl {
this.getSpellAbility().addEffect(effect);
// Miracle {1}{R}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{1}{R}")));
this.addAbility(new MiracleAbility("{1}{R}"));
}
private ReforgeTheSoul(final ReforgeTheSoul card) {

View file

@ -1,8 +1,5 @@
package mage.cards.r;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.MustBeBlockedByAllTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
@ -15,8 +12,9 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author North
*/
public final class RevengeOfTheHunted extends CardImpl {
@ -24,7 +22,6 @@ public final class RevengeOfTheHunted extends CardImpl {
public RevengeOfTheHunted(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
// Until end of turn, target creature gets +6/+6 and gains trample, and all creatures able to block it this turn do so.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BoostTargetEffect(6, 6, Duration.EndOfTurn));
@ -34,7 +31,7 @@ public final class RevengeOfTheHunted extends CardImpl {
this.getSpellAbility().addEffect(effect);
// Miracle {G}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{G}")));
this.addAbility(new MiracleAbility("{G}"));
}
private RevengeOfTheHunted(final RevengeOfTheHunted card) {

View file

@ -0,0 +1,46 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SisterRepentia extends CardImpl {
public SisterRepentia(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(5);
this.toughness = new MageInt(1);
// Martyrdom -- When Sister Repentia dies, you gain 2 life and draw two cards.
Ability ability = new DiesSourceTriggeredAbility(new GainLifeEffect(2));
ability.addEffect(new DrawCardSourceControllerEffect(2));
this.addAbility(ability.withFlavorWord("Martyrdom"));
// Miracle {W}{B}
this.addAbility(new MiracleAbility("{W}{B}"));
}
private SisterRepentia(final SisterRepentia card) {
super(card);
}
@Override
public SisterRepentia copy() {
return new SisterRepentia(this);
}
}

View file

@ -1,8 +1,5 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect;
import mage.abilities.keyword.MiracleAbility;
@ -10,6 +7,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import java.util.UUID;
/**
* @author noxx
*/
@ -18,13 +17,12 @@ public final class TemporalMastery extends CardImpl {
public TemporalMastery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{U}{U}");
// Take an extra turn after this one. Exile Temporal Mastery.
this.getSpellAbility().addEffect(new AddExtraTurnControllerEffect());
this.getSpellAbility().addEffect(new ExileSpellEffect());
// Miracle {1}{U}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{1}{U}")));
this.addAbility(new MiracleAbility("{1}{U}"));
}
private TemporalMastery(final TemporalMastery card) {

View file

@ -1,8 +1,6 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -17,8 +15,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author North
*/
public final class Terminus extends CardImpl {
@ -28,8 +27,9 @@ public final class Terminus extends CardImpl {
// Put all creatures on the bottom of their owners' libraries.
this.getSpellAbility().addEffect(new TerminusEffect());
// Miracle {W}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{W}")));
this.addAbility(new MiracleAbility("{W}"));
}
private Terminus(final Terminus card) {

View file

@ -1,8 +1,5 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -10,8 +7,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author North
*/
public final class ThunderousWrath extends CardImpl {
@ -19,13 +17,12 @@ public final class ThunderousWrath extends CardImpl {
public ThunderousWrath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{R}{R}");
// Thunderous Wrath deals 5 damage to any target.
this.getSpellAbility().addEffect(new DamageTargetEffect(5));
this.getSpellAbility().addTarget(new TargetAnyTarget());
// Miracle {R}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{R}")));
this.addAbility(new MiracleAbility("{R}"));
}
private ThunderousWrath(final ThunderousWrath card) {

View file

@ -1,8 +1,5 @@
package mage.cards.v;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.keyword.MiracleAbility;
import mage.cards.CardImpl;
@ -10,8 +7,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
*
* @author noxx
*/
public final class Vanishment extends CardImpl {
@ -19,13 +17,12 @@ public final class Vanishment extends CardImpl {
public Vanishment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{4}{U}");
// Put target nonland permanent on top of its owner's library.
this.getSpellAbility().addEffect(new PutOnLibraryTargetEffect(true));
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
// Miracle {U}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl<>("{U}")));
this.addAbility(new MiracleAbility("{U}"));
}
private Vanishment(final Vanishment card) {

View file

@ -154,6 +154,7 @@ public final class Warhammer40000 extends ExpansionSet {
cards.add(new SetCardInfo("Scoured Barrens", 293, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
cards.add(new SetCardInfo("Screamer-Killer", 84, Rarity.RARE, mage.cards.s.ScreamerKiller.class));
cards.add(new SetCardInfo("Sculpting Steel", 247, Rarity.RARE, mage.cards.s.SculptingSteel.class));
cards.add(new SetCardInfo("Sister Repentia", 142, Rarity.RARE, mage.cards.s.SisterRepentia.class));
cards.add(new SetCardInfo("Skorpekh Destroyer", 57, Rarity.UNCOMMON, mage.cards.s.SkorpekhDestroyer.class));
cards.add(new SetCardInfo("Skorpekh Lord", 58, Rarity.RARE, mage.cards.s.SkorpekhLord.class));
cards.add(new SetCardInfo("Skullclamp", 248, Rarity.UNCOMMON, mage.cards.s.Skullclamp.class));

View file

@ -6,6 +6,7 @@ import mage.abilities.SpellAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Outcome;
@ -18,53 +19,53 @@ import mage.watchers.common.MiracleWatcher;
/**
* 702.92. Miracle
*
* <p>
* 702.92a Miracle is a static ability linked to a triggered ability (see rule
* 603.10). "Miracle [cost]" means "You may reveal this card from your hand as
* you draw it if it's the first card you've drawn this turn. When you reveal
* this card this way, you may cast it by paying [cost] rather than its mana
* cost."
*
* <p>
* 702.92b If a player chooses to reveal a card using its miracle ability, they
* play with that card revealed until that card leaves their hand, that ability
* resolves, or that ability otherwise leaves the stack.
*
* <p>
* You can cast a card for its miracle cost only as the miracle triggered
* ability resolves. If you don't want to cast it at that time (or you can't
* cast it, perhaps because there are no legal targets available), you won't be
* able to cast it later for the miracle cost.
*
* <p>
* RULINGS: You still draw the card, whether you use the miracle ability or not.
* Any ability that triggers whenever you draw a card, for example, will
* trigger. If you don't cast the card using its miracle ability, it will remain
* in your hand.
*
* <p>
* You can reveal and cast a card with miracle on any turn, not just your own,
* if it's the first card you've drawn that turn.
*
* <p>
* You don't have to reveal a drawn card with miracle if you don't wish to cast
* it at that time.
*
* <p>
* You can cast a card for its miracle cost only as the miracle triggered
* ability resolves. If you don't want to cast it at that time (or you can't
* cast it, perhaps because there are no legal targets available), you won't be
* able to cast it later for the miracle cost.
*
* <p>
* You cast the card with miracle during the resolution of the triggered
* ability. Ignore any timing restrictions based on the card's type.
*
* <p>
* It's important to reveal a card with miracle before it is mixed with the
* other cards in your hand.
*
* <p>
* Multiple card draws are always treated as a sequence of individual card
* draws. For example, if you haven't drawn any cards yet during a turn and cast
* a spell that instructs you to draw three cards, you'll draw them one at a
* time. Only the first card drawn this way may be revealed and cast using its
* miracle ability.
*
* <p>
* If the card with miracle leaves your hand before the triggered ability
* resolves, you won't be able to cast it using its miracle ability.
*
* <p>
* You draw your opening hand before any turn begins. Cards you draw for your
* opening hand can't be cast using miracle.
*
@ -73,16 +74,15 @@ import mage.watchers.common.MiracleWatcher;
public class MiracleAbility extends TriggeredAbilityImpl {
private static final String staticRule = " <i>(You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.)</i>";
private String ruleText;
private final String ruleText;
@SuppressWarnings("unchecked")
public MiracleAbility(Card card, ManaCosts miracleCosts) {
super(Zone.HAND, new MiracleEffect((ManaCosts<ManaCost>) miracleCosts), true);
public MiracleAbility(String miracleCosts) {
super(Zone.HAND, new MiracleEffect(miracleCosts), true);
addWatcher(new MiracleWatcher());
ruleText = "Miracle " + miracleCosts.getText() + staticRule;
ruleText = "Miracle " + miracleCosts + staticRule;
}
public MiracleAbility(final MiracleAbility ability) {
private MiracleAbility(final MiracleAbility ability) {
super(ability);
this.ruleText = ability.ruleText;
}
@ -117,10 +117,10 @@ class MiracleEffect extends OneShotEffect {
private final ManaCosts<ManaCost> miracleCosts;
public MiracleEffect(ManaCosts<ManaCost> miracleCosts) {
public MiracleEffect(String miracleCosts) {
super(Outcome.Benefit);
this.staticText = "cast this card for its miracle cost";
this.miracleCosts = miracleCosts;
this.miracleCosts = new ManaCostsImpl<>(miracleCosts);
}
public MiracleEffect(final MiracleEffect effect) {

View file

@ -73,7 +73,7 @@ Madness|cost|
Melee|new|
Menace|new|
Mentor|new|
Miracle|cost|
Miracle|manaString|
Modular|card, number|
Mountaincycling|cost|
Mountainwalk|new|