[DMU] Implement Defiler cycle (Ready for review) (#9460)

* [DMU] Implemented Defiler of Faith

* [DMU] Implemented Defiler of Dreams

* [DMU] Implemented Defiler of Flesh

* [DMU] Implemented Defiler of Instinct

* [DMU] Implemented Defiler of Vigor

* create PermanentPredicate

* initial attempt at Defiler ability

* some nonfunctional recommended changes

* a few more requested changes

* change arguments to ObjectColor from String

* fix a dumb mistake

* add test

* a few requested changes
This commit is contained in:
Evan Kranzler 2022-09-14 15:16:56 -04:00 committed by GitHub
parent 835d90f0da
commit d165072ac9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 572 additions and 38 deletions

View file

@ -0,0 +1,59 @@
package mage.cards.d;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.MayPay2LifeForColorAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefilerOfDreams extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a blue permanent spell");
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
filter.add(PermanentPredicate.instance);
}
public DefilerOfDreams(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.SPHINX);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Flying
this.addAbility(FlyingAbility.getInstance());
// As an additional cost to cast blue permanent spells, you may pay 2 life. Those spells cost {U} less to cast if you paid life this way. This effect reduces only the amount of blue mana you pay.
this.addAbility(new MayPay2LifeForColorAbility(ObjectColor.BLUE));
// Whenever you cast a blue permanent spell, draw a card.
this.addAbility(new SpellCastControllerTriggeredAbility(
new DrawCardSourceControllerEffect(1), filter, false
));
}
private DefilerOfDreams(final DefilerOfDreams card) {
super(card);
}
@Override
public DefilerOfDreams copy() {
return new DefilerOfDreams(this);
}
}

View file

@ -0,0 +1,60 @@
package mage.cards.d;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.MayPay2LifeForColorAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.game.permanent.token.SoldierToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefilerOfFaith extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a white permanent spell");
static {
filter.add(new ColorPredicate(ObjectColor.WHITE));
filter.add(PermanentPredicate.instance);
}
public DefilerOfFaith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.HUMAN);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// As an additional cost to cast white permanent spells, you may pay 2 life. Those spells cost {W} less to cast if you paid life this way. This effect reduces only the amount of white mana you pay.
this.addAbility(new MayPay2LifeForColorAbility(ObjectColor.WHITE));
// Whenever you cast a white permanent spell, create a 1/1 white Soldier creature token.
this.addAbility(new SpellCastControllerTriggeredAbility(
new CreateTokenEffect(new SoldierToken()), filter, false
));
}
private DefilerOfFaith(final DefilerOfFaith card) {
super(card);
}
@Override
public DefilerOfFaith copy() {
return new DefilerOfFaith(this);
}
}

View file

@ -0,0 +1,68 @@
package mage.cards.d;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.MayPay2LifeForColorAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefilerOfFlesh extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a black permanent spell");
static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
filter.add(PermanentPredicate.instance);
}
public DefilerOfFlesh(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.HORROR);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Menace
this.addAbility(new MenaceAbility(false));
// As an additional cost to cast black permanent spells, you may pay 2 life. Those spells cost {B} less to cast if you paid life this way. This effect reduces only the amount of black mana you pay.
this.addAbility(new MayPay2LifeForColorAbility(ObjectColor.BLACK));
// Whenever you cast a black permanent spell, target creature you control gets +1/+1 and gains menace until end of turn.
Ability ability = new SpellCastControllerTriggeredAbility(
new BoostTargetEffect(1, 1)
.setText("target creature you control gets +1/+1"),
filter, false
);
ability.addEffect(new GainAbilityTargetEffect(new MenaceAbility(false))
.setText("and gains menace until end of turn"));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private DefilerOfFlesh(final DefilerOfFlesh card) {
super(card);
}
@Override
public DefilerOfFlesh copy() {
return new DefilerOfFlesh(this);
}
}

View file

@ -0,0 +1,63 @@
package mage.cards.d;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.MayPay2LifeForColorAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefilerOfInstinct extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a red permanent spell");
static {
filter.add(new ColorPredicate(ObjectColor.RED));
filter.add(PermanentPredicate.instance);
}
public DefilerOfInstinct(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.KAVU);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// As an additional cost to cast red permanent spells, you may pay 2 life. Those spells cost {R} less to cast if you paid life this way. This effect reduces only the amount of red mana you pay.
this.addAbility(new MayPay2LifeForColorAbility(ObjectColor.RED));
// Whenever you cast a red permanent spell, Defiler of Instinct deals 1 damage to any target.
Ability ability = new SpellCastControllerTriggeredAbility(
new DamageTargetEffect(1), filter, false
);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private DefilerOfInstinct(final DefilerOfInstinct card) {
super(card);
}
@Override
public DefilerOfInstinct copy() {
return new DefilerOfInstinct(this);
}
}

View file

@ -0,0 +1,64 @@
package mage.cards.d;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.MayPay2LifeForColorAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DefilerOfVigor extends CardImpl {
private static final FilterSpell filter = new FilterSpell("a green permanent spell");
static {
filter.add(new ColorPredicate(ObjectColor.GREEN));
filter.add(PermanentPredicate.instance);
}
public DefilerOfVigor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.WURM);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Trample
this.addAbility(TrampleAbility.getInstance());
// As an additional cost to cast green permanent spells, you may pay 2 life. Those spells cost {G} less to cast if you paid life this way. This effect reduces only the amount of green mana you pay.
this.addAbility(new MayPay2LifeForColorAbility(ObjectColor.GREEN));
// Whenever you cast a green permanent spell, put a +1/+1 counter on each creature you control.
this.addAbility(new SpellCastControllerTriggeredAbility(
new AddCountersAllEffect(
CounterType.P1P1.createInstance(),
StaticFilters.FILTER_CONTROLLED_CREATURE
), filter, false
));
}
private DefilerOfVigor(final DefilerOfVigor card) {
super(card);
}
@Override
public DefilerOfVigor copy() {
return new DefilerOfVigor(this);
}
}

View file

@ -16,6 +16,7 @@ import mage.filter.FilterCard;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterPermanentCard; import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -85,6 +86,7 @@ class InSearchOfGreatnessEffect extends OneShotEffect {
.orElse(0); .orElse(0);
FilterCard filter = new FilterPermanentCard(); FilterCard filter = new FilterPermanentCard();
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, manaValue + 1)); filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, manaValue + 1));
filter.add(PermanentPredicate.instance);
return CardUtil.castSpellWithAttributesForFree( return CardUtil.castSpellWithAttributesForFree(
controller, source, game, new CardsImpl(controller.getHand()), filter controller, source, game, new CardsImpl(controller.getHand()), filter
) || controller.scry(1, source, game); ) || controller.scry(1, source, game);

View file

@ -16,11 +16,10 @@ import mage.constants.TargetController;
import mage.filter.FilterSpell; import mage.filter.FilterSpell;
import mage.filter.FilterStackObject; import mage.filter.FilterStackObject;
import mage.filter.common.FilterInstantOrSorcerySpell; import mage.filter.common.FilterInstantOrSorcerySpell;
import mage.filter.predicate.Predicate; import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility; import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetSpell; import mage.target.TargetSpell;
import mage.target.common.TargetActivatedOrTriggeredAbility; import mage.target.common.TargetActivatedOrTriggeredAbility;
@ -43,7 +42,7 @@ public final class LithoformEngine extends CardImpl {
filter.add(TargetController.YOU.getControllerPredicate()); filter.add(TargetController.YOU.getControllerPredicate());
filter2.add(TargetController.YOU.getControllerPredicate()); filter2.add(TargetController.YOU.getControllerPredicate());
filter3.add(TargetController.YOU.getControllerPredicate()); filter3.add(TargetController.YOU.getControllerPredicate());
filter3.add(LithoformEnginePredicate.instance); filter3.add(PermanentPredicate.instance);
} }
public LithoformEngine(UUID ownerId, CardSetInfo setInfo) { public LithoformEngine(UUID ownerId, CardSetInfo setInfo) {
@ -82,15 +81,6 @@ public final class LithoformEngine extends CardImpl {
} }
} }
enum LithoformEnginePredicate implements Predicate<StackObject> {
instance;
@Override
public boolean apply(StackObject input, Game game) {
return input.isPermanent(game);
}
}
class LithoformEngineEffect extends OneShotEffect { class LithoformEngineEffect extends OneShotEffect {
public LithoformEngineEffect() { public LithoformEngineEffect() {

View file

@ -16,9 +16,7 @@ import mage.constants.SuperType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterSpell; import mage.filter.FilterSpell;
import mage.filter.predicate.Predicate; import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.game.Game;
import mage.game.stack.StackObject;
import mage.target.TargetSpell; import mage.target.TargetSpell;
import mage.watchers.common.CastFromHandWatcher; import mage.watchers.common.CastFromHandWatcher;
@ -30,9 +28,10 @@ import java.util.UUID;
public class MyojinOfCrypticDreams extends CardImpl { public class MyojinOfCrypticDreams extends CardImpl {
private static final FilterSpell permanentSpellFilter = new FilterSpell("permanent spell you control"); private static final FilterSpell permanentSpellFilter = new FilterSpell("permanent spell you control");
static { static {
permanentSpellFilter.add(TargetController.YOU.getControllerPredicate()); permanentSpellFilter.add(TargetController.YOU.getControllerPredicate());
permanentSpellFilter.add(MyojinOfCrypticDreamsPredicate.instance); permanentSpellFilter.add(PermanentPredicate.instance);
} }
public MyojinOfCrypticDreams(UUID ownderId, CardSetInfo setInfo) { public MyojinOfCrypticDreams(UUID ownderId, CardSetInfo setInfo) {
@ -63,17 +62,12 @@ public class MyojinOfCrypticDreams extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
} }
private MyojinOfCrypticDreams(final MyojinOfCrypticDreams card) { super(card); } private MyojinOfCrypticDreams(final MyojinOfCrypticDreams card) {
super(card);
}
@Override @Override
public MyojinOfCrypticDreams copy() { return new MyojinOfCrypticDreams(this); } public MyojinOfCrypticDreams copy() {
} return new MyojinOfCrypticDreams(this);
enum MyojinOfCrypticDreamsPredicate implements Predicate<StackObject> {
instance;
@Override
public boolean apply(StackObject input, Game game) {
return input.isPermanent(game);
} }
} }

View file

@ -88,6 +88,11 @@ public final class DominariaUnited extends ExpansionSet {
cards.add(new SetCardInfo("Cut Down", 89, Rarity.UNCOMMON, mage.cards.c.CutDown.class)); cards.add(new SetCardInfo("Cut Down", 89, Rarity.UNCOMMON, mage.cards.c.CutDown.class));
cards.add(new SetCardInfo("Danitha, Benalia's Hope", 15, Rarity.RARE, mage.cards.d.DanithaBenaliasHope.class)); cards.add(new SetCardInfo("Danitha, Benalia's Hope", 15, Rarity.RARE, mage.cards.d.DanithaBenaliasHope.class));
cards.add(new SetCardInfo("Deathbloom Gardener", 159, Rarity.COMMON, mage.cards.d.DeathbloomGardener.class)); cards.add(new SetCardInfo("Deathbloom Gardener", 159, Rarity.COMMON, mage.cards.d.DeathbloomGardener.class));
cards.add(new SetCardInfo("Defiler of Dreams", 46, Rarity.RARE, mage.cards.d.DefilerOfDreams.class));
cards.add(new SetCardInfo("Defiler of Faith", 16, Rarity.RARE, mage.cards.d.DefilerOfFaith.class));
cards.add(new SetCardInfo("Defiler of Flesh", 90, Rarity.RARE, mage.cards.d.DefilerOfFlesh.class));
cards.add(new SetCardInfo("Defiler of Instinct", 119, Rarity.RARE, mage.cards.d.DefilerOfInstinct.class));
cards.add(new SetCardInfo("Defiler of Vigor", 160, Rarity.RARE, mage.cards.d.DefilerOfVigor.class));
cards.add(new SetCardInfo("Destroy Evil", 17, Rarity.COMMON, mage.cards.d.DestroyEvil.class)); cards.add(new SetCardInfo("Destroy Evil", 17, Rarity.COMMON, mage.cards.d.DestroyEvil.class));
cards.add(new SetCardInfo("Djinn of the Fountain", 47, Rarity.UNCOMMON, mage.cards.d.DjinnOfTheFountain.class)); cards.add(new SetCardInfo("Djinn of the Fountain", 47, Rarity.UNCOMMON, mage.cards.d.DjinnOfTheFountain.class));
cards.add(new SetCardInfo("Drag to the Bottom", 91, Rarity.RARE, mage.cards.d.DragToTheBottom.class)); cards.add(new SetCardInfo("Drag to the Bottom", 91, Rarity.RARE, mage.cards.d.DragToTheBottom.class));

View file

@ -0,0 +1,118 @@
package org.mage.test.cards.cost.additional;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author TheElk801
*/
public class DefilersTest extends CardTestPlayerBase {
private static final String greenDefiler = "Defiler of Vigor";
private static final String redDefiler = "Defiler of Instinct";
private static final String bear = "Grizzly Bears";
private static final String tusker = "Kalonian Tusker";
private static final String goblin = "Scarwood Goblins";
@Test
public void testRegularAccept() {
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, greenDefiler);
addCard(Zone.HAND, playerA, bear);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
setChoice(playerA, true);
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertLife(playerA, 20 - 2);
assertPermanentCount(playerA, bear, 1);
assertCounterCount(playerA, greenDefiler, CounterType.P1P1, 1);
assertTappedCount("Forest", true, 1);
}
@Test
public void testRegularDecline() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
addCard(Zone.BATTLEFIELD, playerA, greenDefiler);
addCard(Zone.HAND, playerA, bear);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
setChoice(playerA, false);
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertLife(playerA, 20);
assertPermanentCount(playerA, bear, 1);
assertCounterCount(playerA, greenDefiler, CounterType.P1P1, 1);
assertTappedCount("Forest", true, 2);
}
@Test
public void testDoubleReduceOne() {
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, greenDefiler, 2);
addCard(Zone.HAND, playerA, bear);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
setChoice(playerA, true);
setChoice(playerA, true);
setChoice(playerA, "");
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertLife(playerA, 20 - 2 - 2);
assertPermanentCount(playerA, bear, 1);
assertCounterCount(playerA, greenDefiler, CounterType.P1P1, 2);
assertTappedCount("Forest", true, 1);
}
@Test
public void testDoubleReduceBoth() {
addCard(Zone.BATTLEFIELD, playerA, greenDefiler, 2);
addCard(Zone.HAND, playerA, tusker);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, tusker);
setChoice(playerA, true);
setChoice(playerA, true);
setChoice(playerA, "");
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertLife(playerA, 20 - 2 - 2);
assertPermanentCount(playerA, tusker, 1);
assertCounterCount(playerA, greenDefiler, CounterType.P1P1, 2);
}
@Test
public void testTwoColors() {
addCard(Zone.BATTLEFIELD, playerA, greenDefiler);
addCard(Zone.BATTLEFIELD, playerA, redDefiler);
addCard(Zone.HAND, playerA, goblin);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, goblin);
setChoice(playerA, true);
setChoice(playerA, true);
setChoice(playerA, "");
addTarget(playerA, playerB);
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertLife(playerA, 20 - 2 - 2);
assertLife(playerB, 20 - 1);
assertPermanentCount(playerA, goblin, 1);
assertCounterCount(playerA, greenDefiler, CounterType.P1P1, 1);
}
}

View file

@ -0,0 +1,104 @@
package mage.abilities.common;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.cards.Card;
import mage.constants.CostModificationType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
/**
* @author TheElk801
*/
public class MayPay2LifeForColorAbility extends StaticAbility {
private final String rule;
public MayPay2LifeForColorAbility(ObjectColor color) {
super(Zone.BATTLEFIELD, new MayPay2LifeEffect(color));
this.rule = makeRule(color);
}
private MayPay2LifeForColorAbility(final MayPay2LifeForColorAbility ability) {
super(ability);
this.rule = ability.rule;
}
@Override
public MayPay2LifeForColorAbility copy() {
return new MayPay2LifeForColorAbility(this);
}
@Override
public String getRule() {
return rule;
}
private static String makeRule(ObjectColor color) {
return "As an additional cost to cast " + color.getDescription() +
" permanent spells, you may pay 2 life. Those spells cost {" + color +
"} less to cast if you paid life this way. This effect reduces only " +
"the amount of " + color.getDescription() + " mana you pay.";
}
}
class MayPay2LifeEffect extends CostModificationEffectImpl {
private final ObjectColor color;
private final ManaCosts<ManaCost> manaCost;
MayPay2LifeEffect(ObjectColor color) {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
this.color = color;
this.manaCost = new ManaCostsImpl<>("{" + color + "}");
}
private MayPay2LifeEffect(final MayPay2LifeEffect effect) {
super(effect);
this.color = effect.color;
this.manaCost = effect.manaCost;
}
@Override
public MayPay2LifeEffect copy() {
return new MayPay2LifeEffect(this);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player player = game.getPlayer(abilityToModify.getControllerId());
Cost cost = new PayLifeCost(2);
if (!cost.canPay(abilityToModify, source, source.getControllerId(), game)) {
return true;
}
if (game.inCheckPlayableState() || (
player.chooseUse(outcome, "Pay 2 life to reduce the cost by {" + color + "}?", source, game)
&& cost.pay(abilityToModify, game, source, source.getControllerId(), true)
)) {
CardUtil.adjustCost((SpellAbility) abilityToModify, manaCost, false);
}
return true;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (!(abilityToModify instanceof SpellAbility)
|| !abilityToModify.isControlledBy(source.getControllerId())) {
return false;
}
Card spellCard = ((SpellAbility) abilityToModify).getCharacteristics(game);
return spellCard.isPermanent(game) && spellCard.getColor(game).contains(color);
}
}

View file

@ -1,13 +1,9 @@
package mage.filter.common; package mage.filter.common;
import mage.constants.CardType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.PermanentPredicate;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public class FilterPermanentCard extends FilterCard { public class FilterPermanentCard extends FilterCard {
@ -18,13 +14,7 @@ public class FilterPermanentCard extends FilterCard {
public FilterPermanentCard(String name) { public FilterPermanentCard(String name) {
super(name); super(name);
this.add( this.add(PermanentPredicate.instance);
Predicates.or(
CardType.ARTIFACT.getPredicate(),
CardType.CREATURE.getPredicate(),
CardType.ENCHANTMENT.getPredicate(),
CardType.LAND.getPredicate(),
CardType.PLANESWALKER.getPredicate()));
} }
public FilterPermanentCard(final FilterPermanentCard filter) { public FilterPermanentCard(final FilterPermanentCard filter) {

View file

@ -0,0 +1,17 @@
package mage.filter.predicate.mageobject;
import mage.MageObject;
import mage.filter.predicate.Predicate;
import mage.game.Game;
/**
* @author TheElk801
*/
public enum PermanentPredicate implements Predicate<MageObject> {
instance;
@Override
public boolean apply(MageObject input, Game game) {
return input.isPermanent(game);
}
}