Replace many custom CostImpl classes with common ones. Fix some wrong text. Fix #9679

This commit is contained in:
Alex W. Jackson 2022-10-24 07:48:32 -04:00
parent 58d252876a
commit 5e10c3a279
20 changed files with 211 additions and 689 deletions

View file

@ -1,19 +1,15 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.PutCountersSourceCost;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
@ -29,7 +25,7 @@ public final class Aboroth extends CardImpl {
this.toughness = new MageInt(9);
// Cumulative upkeep-Put a -1/-1 counter on Aboroth.
this.addAbility(new CumulativeUpkeepAbility(new AborothCost()));
this.addAbility(new CumulativeUpkeepAbility(new PutCountersSourceCost(CounterType.M1M1.createInstance())));
}
private Aboroth(final Aboroth card) {
@ -41,35 +37,3 @@ public final class Aboroth extends CardImpl {
return new Aboroth(this);
}
}
class AborothCost extends CostImpl {
public AborothCost() {
this.text = "Put a -1/-1 counter on Aboroth";
}
private AborothCost(final AborothCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
permanent.addCounters(CounterType.M1M1.createInstance(), controllerId, ability, game);
this.paid = true;
return true;
}
return false;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return true;
}
@Override
public AborothCost copy() {
return new AborothCost(this);
}
}

View file

@ -30,7 +30,7 @@ public final class AltarOfBhaal extends AdventureCard {
new ReturnFromGraveyardToBattlefieldTargetEffect(), new ManaCostsImpl<>("{2}{B}")
);
ability.addCost(new TapSourceCost());
ability.addCost(new ExileTargetCost(new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true)));
ability.addCost(new ExileTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE)));
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
this.addAbility(ability);

View file

@ -1,11 +1,10 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.common.CastOnlyIfConditionIsTrueAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DontUntapInControllersUntapStepAllEffect;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.abilities.keyword.FlyingAbility;
@ -27,7 +26,7 @@ import mage.filter.predicate.mageobject.AbilityPredicate;
*/
public final class Blizzard extends CardImpl {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("a snow land");
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("if you control a snow land");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("creatures with flying");
static {
@ -44,7 +43,7 @@ public final class Blizzard extends CardImpl {
));
// Cumulative upkeep {2}
this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl<>("{2}")));
this.addAbility(new CumulativeUpkeepAbility(new GenericManaCost(2)));
// Creatures with flying don't untap during their controllers' untap steps.
this.addAbility(new SimpleStaticAbility(

View file

@ -28,12 +28,12 @@ public final class CityOfShadows extends CardImpl {
// {T}, Exile a creature you control: Put a storage counter on City of Shadows.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()), new TapSourceCost());
ability.addCost(new ExileTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true)));
ability.addCost(new ExileTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE)));
this.addAbility(ability);
// {T}: Add X mana of {C}, where X is the number of storage counters on City of Shadows.
// {T}: Add {C} for each storage counter on City of Shadows.
ability = new DynamicManaAbility(Mana.ColorlessMana(1), new CountersSourceCount(CounterType.STORAGE),
"Add X mana of {C}, where X is the number of storage counters on {this}");
"Add {C} for each storage counter on {this}");
this.addAbility(ability);
}

View file

@ -36,7 +36,7 @@ public final class FoodChain extends CardImpl {
// Exile a creature you control: Add X mana of any one color, where X is the exiled creature's converted mana cost plus one. Spend this mana only to cast creature spells.
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new FoodChainManaEffect(),
new ExileTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true)));
new ExileTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE)));
this.addAbility(ability);
}

View file

@ -1,9 +1,9 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
@ -14,8 +14,7 @@ import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
/**
*
@ -23,16 +22,17 @@ import mage.filter.common.FilterControlledCreaturePermanent;
*/
public final class GutwrencherOni extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("Ogre");
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Ogre");
static {
filter.add(SubType.OGRE.getPredicate());
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
public GutwrencherOni(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
this.subtype.add(SubType.DEMON);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.DEMON, SubType.SPIRIT);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
@ -41,11 +41,14 @@ public final class GutwrencherOni extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// At the beginning of your upkeep, discard a card if you don't control an Ogre.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ConditionalOneShotEffect(
new DiscardControllerEffect(1),
new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0),
"discard a card if you don't control an Ogre"), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new ConditionalOneShotEffect(
new DiscardControllerEffect(1),
condition,
"discard a card if you don't control an Ogre"
),
TargetController.YOU, false
));
}
private GutwrencherOni(final GutwrencherOni card) {
@ -57,4 +60,3 @@ public final class GutwrencherOni extends CardImpl {
return new GutwrencherOni(this);
}
}

View file

@ -1,29 +1,24 @@
package mage.cards.h;
import java.util.Collection;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetSpell;
import mage.target.common.TargetCardInHand;
import mage.util.CardUtil;
/**
* @author LevelX
@ -33,17 +28,15 @@ public final class HisokaMinamoSensei extends CardImpl {
public HisokaMinamoSensei(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.subtype.add(SubType.HUMAN, SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// {2}{U}, Discard a card: Counter target spell if it has the same converted mana cost as the discarded card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HisokaMinamoSenseiCounterEffect(), new ManaCostsImpl<>("{2}{U}"));
Ability ability = new SimpleActivatedAbility(new HisokaMinamoSenseiCounterEffect(), new ManaCostsImpl<>("{2}{U}"));
ability.addCost(new DiscardCardCost());
ability.addTarget(new TargetSpell());
TargetCardInHand targetCard = new TargetCardInHand(new FilterCard("a card"));
ability.addCost(new HisokaMinamoSenseiDiscardTargetCost(targetCard));
this.addAbility(ability);
}
@ -55,54 +48,6 @@ public final class HisokaMinamoSensei extends CardImpl {
public HisokaMinamoSensei copy() {
return new HisokaMinamoSensei(this);
}
}
class HisokaMinamoSenseiDiscardTargetCost extends CostImpl {
protected Card card = null;
public HisokaMinamoSenseiDiscardTargetCost(TargetCardInHand target) {
this.addTarget(target);
this.text = "Discard " + target.getTargetName();
}
public HisokaMinamoSenseiDiscardTargetCost(HisokaMinamoSenseiDiscardTargetCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
if (targets.choose(Outcome.Discard, controllerId, source.getSourceId(), source, game)) {
Player player = game.getPlayer(controllerId);
if(player != null) {
for (UUID targetId : targets.get(0).getTargets()) {
card = player.getHand().get(targetId, game);
if (card == null) {
return false;
}
paid |= player.discard(card, true, source, game);
}
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return targets.canChoose(controllerId, source, game);
}
@Override
public HisokaMinamoSenseiDiscardTargetCost copy() {
return new HisokaMinamoSenseiDiscardTargetCost(this);
}
public Card getDiscardedCard() {
return card;
}
}
class HisokaMinamoSenseiCounterEffect extends OneShotEffect {
@ -118,11 +63,14 @@ class HisokaMinamoSenseiCounterEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source));
if (spell != null) {
HisokaMinamoSenseiDiscardTargetCost cost = (HisokaMinamoSenseiDiscardTargetCost) source.getCosts().get(0);
if (cost != null && cost.getDiscardedCard().getManaValue() == spell.getManaValue()) {
return game.getStack().counter(targetPointer.getFirst(game, source), source, game);
}
if (spell == null) {
return false;
}
if (CardUtil.castStream(source.getCosts().stream(), DiscardTargetCost.class)
.map(DiscardTargetCost::getCards)
.flatMap(Collection::stream)
.anyMatch(card -> card.getManaValue() == spell.getManaValue())) {
return game.getStack().counter(targetPointer.getFirst(game, source), source, game);
}
return false;
}
@ -131,4 +79,4 @@ class HisokaMinamoSenseiCounterEffect extends OneShotEffect {
public HisokaMinamoSenseiCounterEffect copy() {
return new HisokaMinamoSenseiCounterEffect(this);
}
}
}

View file

@ -1,24 +1,15 @@
package mage.cards.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.PutCardFromHandOnTopOfLibraryCost;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
/**
*
@ -33,7 +24,7 @@ public final class Leashling extends CardImpl {
this.toughness = new MageInt(3);
// Put a card from your hand on top of your library: Return Leashling to its owner's hand.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(), new PutCardFromHandOnTopOfLibrary()));
this.addAbility(new SimpleActivatedAbility(new ReturnToHandSourceEffect(), new PutCardFromHandOnTopOfLibraryCost()));
}
private Leashling(final Leashling card) {
@ -45,52 +36,3 @@ public final class Leashling extends CardImpl {
return new Leashling(this);
}
}
class PutCardFromHandOnTopOfLibrary extends CostImpl {
protected final int amount;
public PutCardFromHandOnTopOfLibrary() {
this(1);
}
public PutCardFromHandOnTopOfLibrary(final int amount) {
this.amount = amount;
this.text = "put " + (amount == 1 ? "a card" : (amount + " cards")) + " from your hand on top of your library";
}
public PutCardFromHandOnTopOfLibrary(final PutCardFromHandOnTopOfLibrary cost) {
super(cost);
this.amount = cost.amount;
}
@Override
public Cost copy() {
return new PutCardFromHandOnTopOfLibrary(this);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
return !controller.getHand().isEmpty();
}
return false;
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
TargetCardInHand target = new TargetCardInHand();
controller.chooseTarget(Outcome.ReturnToHand, target, ability, game);
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
controller.putCardsOnTopOfLibrary(new CardsImpl(card), game, ability, false);
paid = true;
}
}
return paid;
}
}

View file

@ -1,29 +1,27 @@
package mage.cards.n;
import java.util.Collection;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.token.ZombieToken;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.util.CardUtil;
/**
* @author noxx
* @author awjackson
*/
public final class NecromancersStockpile extends CardImpl {
@ -32,9 +30,12 @@ public final class NecromancersStockpile extends CardImpl {
// {1}{B}, Discard a creature card: Draw a card.
// If the discarded card was a Zombie card, create a tapped 2/2 black Zombie creature token.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{B}"));
ability.addCost(new NecromancersStockpileDiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE)));
ability.addEffect(new NecromancersStockpilePutTokenEffect());
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{1}{B}"));
ability.addCost(new DiscardTargetCost(new TargetCardInHand(StaticFilters.FILTER_CARD_CREATURE_A)));
ability.addEffect(new ConditionalOneShotEffect(
new CreateTokenEffect(new ZombieToken(), 1, true, false),
NecromancersStockpileCondition.instance
));
this.addAbility(ability);
}
@ -46,79 +47,21 @@ public final class NecromancersStockpile extends CardImpl {
public NecromancersStockpile copy() {
return new NecromancersStockpile(this);
}
}
class NecromancersStockpileDiscardTargetCost extends CostImpl {
protected boolean isZombieCard;
public NecromancersStockpileDiscardTargetCost(TargetCardInHand target) {
this.addTarget(target);
this.text = "Discard " + target.getTargetName();
}
public NecromancersStockpileDiscardTargetCost(NecromancersStockpileDiscardTargetCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
if (targets.choose(Outcome.Discard, controllerId, source.getSourceId(), source, game)) {
Player player = game.getPlayer(controllerId);
if (player != null) {
for (UUID targetId : targets.get(0).getTargets()) {
Card card = player.getHand().get(targetId, game);
if (card == null) {
return false;
}
isZombieCard = card.hasSubtype(SubType.ZOMBIE, game);
paid |= player.discard(card, true, source, game);
}
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return targets.canChoose(controllerId, source, game);
}
@Override
public NecromancersStockpileDiscardTargetCost copy() {
return new NecromancersStockpileDiscardTargetCost(this);
}
public boolean isZombieCard() {
return isZombieCard;
}
}
class NecromancersStockpilePutTokenEffect extends OneShotEffect {
NecromancersStockpilePutTokenEffect() {
super(Outcome.Neutral);
staticText = "If the discarded card was a Zombie card, create a tapped 2/2 black Zombie creature token";
}
NecromancersStockpilePutTokenEffect(final NecromancersStockpilePutTokenEffect effect) {
super(effect);
}
enum NecromancersStockpileCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
NecromancersStockpileDiscardTargetCost cost = (NecromancersStockpileDiscardTargetCost) source.getCosts().get(0);
if (cost != null && cost.isZombieCard()) {
new CreateTokenEffect(new ZombieToken(), 1, true, false).apply(game, source);
}
return true;
return CardUtil.castStream(source.getCosts().stream(), DiscardTargetCost.class)
.map(DiscardTargetCost::getCards)
.flatMap(Collection::stream)
.anyMatch(card -> card.hasSubtype(SubType.ZOMBIE, game));
}
@Override
public NecromancersStockpilePutTokenEffect copy() {
return new NecromancersStockpilePutTokenEffect(this);
public String toString() {
return "the discarded card was a Zombie card";
}
}

View file

@ -23,7 +23,7 @@ public final class NecroticFumes extends CardImpl {
this.subtype.add(SubType.LESSON);
// As an additional cost to cast this spell, exile a creature you control.
this.getSpellAbility().addCost(new ExileTargetCost(new TargetControlledPermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true)));
this.getSpellAbility().addCost(new ExileTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE)));
// Exile target creature or planeswalker.
this.getSpellAbility().addEffect(new ExileTargetEffect());

View file

@ -1,22 +1,21 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.keyword.FearAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
/**
*
@ -24,19 +23,33 @@ import mage.game.Game;
*/
public final class PainwrackerOni extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Ogre");
static {
filter.add(SubType.OGRE.getPredicate());
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
public PainwrackerOni (UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}{B}");
this.subtype.add(SubType.DEMON);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.DEMON, SubType.SPIRIT);
this.power = new MageInt(5);
this.toughness = new MageInt(4);
// Fear (This creature can't be blocked except by artifact creatures and/or black creatures.)
this.addAbility(FearAbility.getInstance());
// At the beginning of your upkeep, sacrifice a creature if you don't control an Ogre.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new PainwrackerOniEffect(new FilterControlledCreaturePermanent(), 1, ""), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new ConditionalOneShotEffect(
new SacrificeControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, null),
condition,
"sacrifice a creature if you don't control an Ogre"
),
TargetController.YOU, false
));
}
public PainwrackerOni (final PainwrackerOni card) {
@ -47,30 +60,4 @@ public final class PainwrackerOni extends CardImpl {
public PainwrackerOni copy() {
return new PainwrackerOni(this);
}
}
class PainwrackerOniEffect extends SacrificeControllerEffect {
public PainwrackerOniEffect(FilterPermanent filter, int count, String preText) {
super(filter, count, preText);
this.staticText = "sacrifice a creature if you don't control an Ogre";
}
public PainwrackerOniEffect(final PainwrackerOniEffect effect) {
super(effect);
}
@Override
public PainwrackerOniEffect copy() {
return new PainwrackerOniEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
if (game.getBattlefield().countAll(new FilterCreaturePermanent(SubType.OGRE, "Ogre"), source.getControllerId(), game) < 1) {
return super.apply(game, source);
}
return true;
}
}

View file

@ -1,20 +1,19 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.players.Player;
import mage.filter.common.FilterControlledPermanent;
/**
*
@ -22,16 +21,30 @@ import mage.players.Player;
*/
public final class ScourgeOfNumai extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Ogre");
static {
filter.add(SubType.OGRE.getPredicate());
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
public ScourgeOfNumai(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}");
this.subtype.add(SubType.DEMON);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.DEMON, SubType.SPIRIT);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// At the beginning of your upkeep, you lose 2 life if you don't control an Ogre.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ScourgeOfNumaiEffect(), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new ConditionalOneShotEffect(
new LoseLifeSourceControllerEffect(2),
condition,
"you lose 2 life if you don't control an Ogre"
),
TargetController.YOU, false
));
}
private ScourgeOfNumai(final ScourgeOfNumai card) {
@ -43,32 +56,3 @@ public final class ScourgeOfNumai extends CardImpl {
return new ScourgeOfNumai(this);
}
}
class ScourgeOfNumaiEffect extends OneShotEffect {
public ScourgeOfNumaiEffect() {
super(Outcome.LoseLife);
this.staticText = "you lose 2 life if you don't control an Ogre.";
}
public ScourgeOfNumaiEffect(final ScourgeOfNumaiEffect effect) {
super(effect);
}
@Override
public ScourgeOfNumaiEffect copy() {
return new ScourgeOfNumaiEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (game.getBattlefield().countAll(new FilterCreaturePermanent(SubType.OGRE, "Ogre"), source.getControllerId(), game) < 1) {
controller.loseLife(2, game, source, false);
}
return true;
}
return false;
}
}

View file

@ -1,23 +1,17 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.OrCost;
import mage.abilities.costs.common.RevealTargetFromHandCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.util.ManaUtil;
import java.util.UUID;
@ -26,6 +20,12 @@ import java.util.UUID;
*/
public final class SilvergillAdept extends CardImpl {
private static final FilterCard filter = new FilterCard("a Merfolk card from your hand");
static {
filter.add(SubType.MERFOLK.getPredicate());
}
public SilvergillAdept(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.MERFOLK);
@ -35,7 +35,11 @@ public final class SilvergillAdept extends CardImpl {
this.toughness = new MageInt(1);
// As an additional cost to cast Silvergill Adept, reveal a Merfolk card from your hand or pay {3}.
this.getSpellAbility().addCost(new SilvergillAdeptCost());
this.getSpellAbility().addCost(new OrCost(
"reveal a Merfolk card from your hand or pay {3}", new RevealTargetFromHandCost(new TargetCardInHand(filter)),
new GenericManaCost(3)
));
// When Silvergill Adept enters the battlefield, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
}
@ -49,67 +53,3 @@ public final class SilvergillAdept extends CardImpl {
return new SilvergillAdept(this);
}
}
class SilvergillAdeptCost extends CostImpl {
private static final FilterCard filter = new FilterCard("Merfolk card");
private Cost mana = ManaUtil.createManaCost(3, false);
static {
filter.add(SubType.MERFOLK.getPredicate());
}
public SilvergillAdeptCost() {
this.text = "reveal a Merfolk card from your hand or pay {3}";
}
public SilvergillAdeptCost(SilvergillAdeptCost cost) {
super(cost);
this.mana = cost.mana.copy();
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player player = game.getPlayer(controllerId);
if (player == null) {
return false;
}
paid = false;
if (player.getHand().count(filter, game) > 0
&& player.chooseUse(Outcome.Benefit, "Reveal a Merfolk card? Otherwise pay {3}.", ability, game)) {
TargetCardInHand target = new TargetCardInHand(filter);
if (player.choose(Outcome.Benefit, target, source, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
paid = true;
player.revealCards("Revealed card", new CardsImpl(card), game);
}
}
} else {
mana.clearPaid();
if (mana.pay(ability, game, source, player.getId(), false)) {
paid = true;
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
Player player = game.getPlayer(controllerId);
if (player != null && player.getHand().count(filter, game) > 0) {
return true;
}
return mana.canPay(ability, source, controllerId, game);
}
@Override
public SilvergillAdeptCost copy() {
return new SilvergillAdeptCost(this);
}
}

View file

@ -27,7 +27,7 @@ public final class SoulExchange extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}{B}");
// As an additional cost to cast Soul Exchange, exile a creature you control.
Cost cost = new ExileTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_A_CREATURE, true));
Cost cost = new ExileTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_A_CREATURE));
this.getSpellAbility().addCost(cost);
// Return target creature card from your graveyard to the battlefield. Put a +2/+2 counter on that creature if the exiled creature was a Thrull.
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));

View file

@ -1,16 +1,13 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.OpponentControlsPermanentCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
@ -18,9 +15,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.target.common.TargetNonBasicLandPermanent;
/**
@ -29,20 +24,20 @@ import mage.target.common.TargetNonBasicLandPermanent;
*/
public final class TectonicEdge extends CardImpl {
private static final Condition condition = new OpponentControlsPermanentCondition(
new FilterLandPermanent("an opponent controls four or more lands"), ComparisonType.MORE_THAN, 3
);
public TectonicEdge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},null);
// Tap: Add 1.
this.addAbility(new ColorlessManaAbility());
// {1}, {T}, Sacrifice Tectonic Edge: Destroy target nonbasic land. Activate this ability only if an opponent controls four or more lands.
// {1}, {T}, Sacrifice Tectonic Edge: Destroy target nonbasic land. Activate only if an opponent controls four or more lands.
Ability ability = new ActivateIfConditionActivatedAbility(
Zone.BATTLEFIELD,
new DestroyTargetEffect(),
new ManaCostsImpl<>("{1}"),
new OpponentControlsPermanentCondition(
new FilterLandPermanent("an opponent controls four or more lands"),
ComparisonType.MORE_THAN, 3));
Zone.BATTLEFIELD, new DestroyTargetEffect(), new GenericManaCost(1), condition
);
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetNonBasicLandPermanent());
@ -57,39 +52,4 @@ public final class TectonicEdge extends CardImpl {
public TectonicEdge copy() {
return new TectonicEdge(this);
}
}
class TectonicEdgeCost extends CostImpl {
public TectonicEdgeCost() {
this.text = "Activate only if an opponent controls four or more lands";
}
public TectonicEdgeCost(final TectonicEdgeCost cost) {
super(cost);
}
@Override
public TectonicEdgeCost copy() {
return new TectonicEdgeCost(this);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
for (UUID opponentId: game.getOpponents(controllerId)) {
if (game.getBattlefield().countAll(StaticFilters.FILTER_LANDS, opponentId, game) > 3) {
return true;
}
}
return false;
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
this.paid = true;
return paid;
}
}

View file

@ -1,26 +1,22 @@
package mage.cards.t;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.CastOnlyIfConditionIsTrueAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.dynamicvalue.common.CountersSourceCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.RemoveAllCountersSourceEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
@ -32,39 +28,51 @@ import mage.game.events.GameEvent;
import java.util.UUID;
/**
* @author LoneFox
* @author awjackson
*/
public final class TidalInfluence extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blue creatures");
private static final FilterPermanent filterName = new FilterPermanent("if no permanents named Tidal Influence are on the battlefield");
private static final FilterCreaturePermanent filterBlue = new FilterCreaturePermanent("all blue creatures");
static {
filter.add(new ColorPredicate(ObjectColor.BLUE));
filterName.add(new NamePredicate("Tidal Influence"));
filterBlue.add(new ColorPredicate(ObjectColor.BLUE));
}
private static final Condition conditionCast = new PermanentsOnTheBattlefieldCondition(
filterName, ComparisonType.EQUAL_TO, 0, false);
private static final Condition condition1 = new SourceHasCounterCondition(CounterType.TIDE, 1, 1);
private static final Condition condition3 = new SourceHasCounterCondition(CounterType.TIDE, 3, 3);
public TidalInfluence(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
// Cast Tidal Influence only if no permanents named Tidal Influence are on the battlefield.
this.getSpellAbility().addCost(new TidalInfluenceCost());
// Cast this spell only if no permanents named Tidal Influence are on the battlefield.
this.addAbility(new CastOnlyIfConditionIsTrueAbility(conditionCast));
// Tidal Influence enters the battlefield with a tide counter on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.TIDE.createInstance()),
"with a tide counter on it."));
// At the beginning of your upkeep, put a tide counter on Tidal Influence.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.TIDE.createInstance()),
TargetController.YOU, false));
// As long as there is exactly one tide counter on Tidal Influence, all blue creatures get -2/-0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new BoostAllEffect(-2, -0, Duration.WhileOnBattlefield, filter, false),
new SourceHasCounterCondition(CounterType.TIDE, 1, 1),
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new BoostAllEffect(-2, -0, Duration.WhileOnBattlefield, filterBlue, false),
condition1,
"As long as there is exactly one tide counter on {this}, all blue creatures get -2/-0.")));
// As long as there are exactly three tide counters on Tidal Influence, all blue creatures get +2/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new BoostAllEffect(2, -0, Duration.WhileOnBattlefield, filter, false),
new SourceHasCounterCondition(CounterType.TIDE, 3, 3),
"As long as there are exactly three tide counter on {this}, all blue creatures get +2/-0.")));
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new BoostAllEffect(2, 0, Duration.WhileOnBattlefield, filterBlue, false),
condition3,
"As long as there are exactly three tide counter on {this}, all blue creatures get +2/+0.")));
// Whenever there are four tide counters on Tidal Influence, remove all tide counters from it.
this.addAbility(new TidalInfluenceTriggeredAbility(new RemoveAllCountersSourceEffect(CounterType.TIDE)));
this.addAbility(new TidalInfluenceTriggeredAbility());
}
private TidalInfluence(final TidalInfluence card) {
@ -77,45 +85,10 @@ public final class TidalInfluence extends CardImpl {
}
}
class TidalInfluenceCost extends CostImpl {
private static final FilterPermanent filter = new FilterPermanent();
static {
filter.add(new NamePredicate("Tidal Influence"));
}
public TidalInfluenceCost() {
this.text = "Cast Tidal Influence only if no permanents named Tidal Influence are on the battlefield";
}
public TidalInfluenceCost(final TidalInfluenceCost cost) {
super(cost);
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return !game.getBattlefield().contains(filter, source, game, 1);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
this.paid = true;
return paid;
}
@Override
public TidalInfluenceCost copy() {
return new TidalInfluenceCost(this);
}
}
class TidalInfluenceTriggeredAbility extends StateTriggeredAbility {
public TidalInfluenceTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect);
public TidalInfluenceTriggeredAbility() {
super(Zone.BATTLEFIELD, new RemoveAllCountersSourceEffect(CounterType.TIDE));
setTriggerPhrase("Whenever there are four tide counters on {this}, ");
}

View file

@ -1,24 +1,25 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.common.SacrificeAllCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.StaticFilters;
import mage.game.permanent.token.UramiToken;
/**
@ -27,18 +28,31 @@ import mage.game.permanent.token.UramiToken;
*/
public final class TombOfUrami extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("Ogre");
static {
filter.add(SubType.OGRE.getPredicate());
}
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, ComparisonType.EQUAL_TO, 0);
public TombOfUrami(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.addSuperType(SuperType.LEGENDARY);
// {tap}: Add {B}. Tomb of Urami deals 1 damage to you if you don't control an Ogre.
Ability ability = new BlackManaAbility();
ability.addEffect(new DamageControllerEffect(1));
ability.addEffect(new ConditionalOneShotEffect(
new DamageControllerEffect(1),
condition,
"{this} deals 1 damage to you if you don't control an Ogre"
));
this.addAbility(ability);
// {2}{B}{B}, {tap}, Sacrifice all lands you control: Create a legendary 5/5 black Demon Spirit creature token with flying named Urami.
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new UramiToken()), new ManaCostsImpl<>("{2}{B}{B}"));
Ability ability2 = new SimpleActivatedAbility(new CreateTokenEffect(new UramiToken()), new ManaCostsImpl<>("{2}{B}{B}"));
ability2.addCost(new TapSourceCost());
ability2.addCost(new SacrificeAllLandCost());
ability2.addCost(new SacrificeAllCost(StaticFilters.FILTER_CONTROLLED_PERMANENT_LANDS));
this.addAbility(ability2);
}
@ -51,38 +65,3 @@ public final class TombOfUrami extends CardImpl {
return new TombOfUrami(this);
}
}
class SacrificeAllLandCost extends CostImpl {
public SacrificeAllLandCost() {
this.text = "Sacrifice all lands you control";
}
public SacrificeAllLandCost(SacrificeAllLandCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), ability.getControllerId(), game)) {
paid |= permanent.sacrifice(source, game);
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), ability.getControllerId(), game)) {
if (!game.getPlayer(controllerId).canPaySacrificeCost(permanent, source, controllerId, game)) {
return false;
}
}
return true;
}
@Override
public SacrificeAllLandCost copy() {
return new SacrificeAllLandCost(this);
}
}

View file

@ -4,11 +4,8 @@ import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroySourceEffect;
import mage.cards.Card;
@ -17,7 +14,6 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
@ -36,16 +32,14 @@ public final class VolrathsDungeon extends CardImpl {
// Pay 5 life: Destroy Volrath's Dungeon. Any player may activate this ability but only during their turn.
ActivatedAbility ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new DestroySourceEffect().setText("Destroy {this}. Any player may activate this ability but only during their turn."),
new PayLifeActivePlayerCost(5));
new PayLifeCost(5));
ability.setMayActivate(TargetController.ACTIVE);
this.addAbility(ability);
// Discard a card: Target player puts a card from their hand on top of their library. Activate this ability only any time you could cast a sorcery.
ability = new ActivateAsSorceryActivatedAbility(
Zone.BATTLEFIELD, new VolrathsDungeonEffect(), new DiscardCardCost()
);
// Discard a card: Target player puts a card from their hand on top of their library.
// Activate this ability only any time you could cast a sorcery.
ability = new ActivateAsSorceryActivatedAbility(new VolrathsDungeonEffect(), new DiscardCardCost());
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
@ -60,52 +54,6 @@ public final class VolrathsDungeon extends CardImpl {
}
}
class PayLifeActivePlayerCost extends CostImpl {
private final DynamicValue amount;
public PayLifeActivePlayerCost(int amount) {
this.amount = StaticValue.get(amount);
this.text = "Pay " + amount + " life";
}
public PayLifeActivePlayerCost(DynamicValue amount, String text) {
this.amount = amount.copy();
this.text = "Pay " + text;
}
public PayLifeActivePlayerCost(PayLifeActivePlayerCost cost) {
super(cost);
this.amount = cost.amount.copy();
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
int lifeToPayAmount = amount.calculate(game, ability, null);
return game.getPlayer(game.getActivePlayerId()).getLife() >= lifeToPayAmount;
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player activatingPlayer = game.getPlayer(game.getActivePlayerId());
if (activatingPlayer == null) {
return false;
}
int lifeToPayAmount = amount.calculate(game, ability, null);
if (activatingPlayer.chooseUse(Outcome.LoseLife, "Pay " + lifeToPayAmount + " life?", ability, game)) {
this.paid = CardUtil.tryPayLife(lifeToPayAmount, activatingPlayer, source, game);
return this.paid;
}
return false;
}
@Override
public PayLifeActivePlayerCost copy() {
return new PayLifeActivePlayerCost(this);
}
}
class VolrathsDungeonEffect extends OneShotEffect {
public VolrathsDungeonEffect() {

View file

@ -1,14 +1,10 @@
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.ExileTargetCost;
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.keyword.FlyingAbility;
@ -16,15 +12,11 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.util.CardUtil;
import mage.target.common.TargetControlledPermanent;
/**
*
@ -32,10 +24,15 @@ import mage.util.CardUtil;
*/
public final class WormfangDrake extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledCreaturePermanent("a creature you control other than {this}");
static {
filter.add(AnotherPredicate.instance);
}
public WormfangDrake(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{U}");
this.subtype.add(SubType.NIGHTMARE);
this.subtype.add(SubType.DRAKE);
this.subtype.add(SubType.NIGHTMARE, SubType.DRAKE);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
@ -44,7 +41,9 @@ public final class WormfangDrake extends CardImpl {
// When Wormfang Drake enters the battlefield, sacrifice it unless you exile a creature you control other than Wormfang Drake.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SacrificeSourceUnlessPaysEffect(new WormfangDrakeExileCost()), false));
new SacrificeSourceUnlessPaysEffect(new ExileTargetCost(new TargetControlledPermanent(filter))),
false
));
// When Wormfang Drake leaves the battlefield, return the exiled card to the battlefield under its owner's control.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false));
@ -59,50 +58,3 @@ public final class WormfangDrake extends CardImpl {
return new WormfangDrake(this);
}
}
class WormfangDrakeExileCost extends CostImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
public WormfangDrakeExileCost() {
this.addTarget(new TargetControlledCreaturePermanent(1, 1, filter, true));
this.text = "Exile a creature you control other than {this}";
}
public WormfangDrakeExileCost(WormfangDrakeExileCost cost) {
super(cost);
}
@Override
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
MageObject sourceObject = ability.getSourceObject(game);
if (controller != null && sourceObject != null) {
if (targets.choose(Outcome.Exile, controllerId, source.getSourceId(), source, game)) {
UUID exileId = CardUtil.getExileZoneId(game, ability.getSourceId(), ability.getSourceObjectZoneChangeCounter());
for (UUID targetId : targets.get(0).getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent == null) {
return false;
}
paid |= controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getIdName() + " exiled permanents", source, game, Zone.BATTLEFIELD, true);
}
}
}
return paid;
}
@Override
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
return targets.canChoose(controllerId, source, game);
}
@Override
public WormfangDrakeExileCost copy() {
return new WormfangDrakeExileCost(this);
}
}

View file

@ -26,8 +26,9 @@ public class ExileTargetCost extends CostImpl {
List<Permanent> permanents = new ArrayList<>();
public ExileTargetCost(TargetControlledPermanent target) {
target.setNotTarget(true);
this.addTarget(target);
this.text = "Exile " + target.getTargetName();
this.text = "exile " + target.getTargetName();
}
public ExileTargetCost(TargetControlledPermanent target, boolean noText) {
@ -61,7 +62,7 @@ public class ExileTargetCost extends CostImpl {
// so return state here is not important because the user indended to exile the target anyway
}
player.moveCardsToExile(
cards.getCards(game), source, game, false,
cards.getCards(game), source, game, true,
CardUtil.getExileZoneId(game, source),
CardUtil.getSourceName(game, source)
);