mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
Replace many custom CostImpl classes with common ones. Fix some wrong text. Fix #9679
This commit is contained in:
parent
58d252876a
commit
5e10c3a279
20 changed files with 211 additions and 689 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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}, ");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue