[MH2] Implemented Grief

This commit is contained in:
Evan Kranzler 2021-05-21 07:52:08 -04:00
parent 80f61e3b68
commit af3bd24f03
25 changed files with 110 additions and 51 deletions

View file

@ -34,7 +34,7 @@ public final class Aethersnipe extends CardImpl {
this.addAbility(ability);
// Evoke {1}{U}{U}
this.addAbility(new EvokeAbility(this, "{1}{U}{U}"));
this.addAbility(new EvokeAbility("{1}{U}{U}"));
}
private Aethersnipe(final Aethersnipe card) {

View file

@ -35,7 +35,7 @@ public final class Briarhorn extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Evoke {1}{G}
this.addAbility(new EvokeAbility(this, "{1}{G}"));
this.addAbility(new EvokeAbility("{1}{G}"));
}
private Briarhorn(final Briarhorn card) {

View file

@ -45,7 +45,7 @@ public final class Cloudthresher extends CardImpl {
ability.addEffect(new DamagePlayersEffect(2));
this.addAbility(ability);
// Evoke {2}{G}{G}
this.addAbility(new EvokeAbility(this, "{2}{G}{G}"));
this.addAbility(new EvokeAbility("{2}{G}{G}"));
}
private Cloudthresher(final Cloudthresher card) {

View file

@ -37,7 +37,7 @@ public final class Dawnfluke extends CardImpl {
ability.addTarget(target);
this.addAbility(ability);
// Evoke {W}
this.addAbility(new EvokeAbility(this, "{W}"));
this.addAbility(new EvokeAbility("{W}"));
}
private Dawnfluke(final Dawnfluke card) {

View file

@ -37,7 +37,7 @@ public final class Faultgrinder extends CardImpl {
this.addAbility(ability);
// Evoke {4}{R}
this.addAbility(new EvokeAbility(this, "{4}{R}"));
this.addAbility(new EvokeAbility("{4}{R}"));
}
private Faultgrinder(final Faultgrinder card) {

View file

@ -36,7 +36,7 @@ public final class Glarewielder extends CardImpl {
ability.addTarget(new TargetCreaturePermanent(0, 2));
this.addAbility(ability);
// Evoke {1}{R}
this.addAbility(new EvokeAbility(this, "{1}{R}"));
this.addAbility(new EvokeAbility("{1}{R}"));
}
private Glarewielder(final Glarewielder card) {

View file

@ -0,0 +1,65 @@
package mage.cards.g;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.abilities.keyword.EvokeAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class Grief extends CardImpl {
private static final FilterCard filter = new FilterCard("a black card from your hand");
static {
filter.add(new ColorPredicate(ObjectColor.BLACK));
}
public Grief(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.INCARNATION);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Menace
this.addAbility(new MenaceAbility());
// When Grief enters the battlefield, target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility(
new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.OPPONENT)
);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
// EvokeExile a black card from your hand.
this.addAbility(new EvokeAbility(new ExileFromHandCost(new TargetCardInHand(filter))));
}
private Grief(final Grief card) {
super(card);
}
@Override
public Grief copy() {
return new Grief(this);
}
}

View file

@ -33,7 +33,7 @@ public final class IngotChewer extends CardImpl {
ability.addTarget(target);
this.addAbility(ability);
// Evoke {R}
this.addAbility(new EvokeAbility(this, "{R}"));
this.addAbility(new EvokeAbility("{R}"));
}
private IngotChewer(final IngotChewer card) {

View file

@ -38,7 +38,7 @@ public final class InnerFlameAcolyte extends CardImpl {
this.addAbility(ability);
// Evoke {R}
this.addAbility(new EvokeAbility(this, "{R}"));
this.addAbility(new EvokeAbility("{R}"));
}
private InnerFlameAcolyte(final InnerFlameAcolyte card) {

View file

@ -37,7 +37,7 @@ public final class Meadowboon extends CardImpl {
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
// Evoke {3}{W}
this.addAbility(new EvokeAbility(this, "{3}{W}"));
this.addAbility(new EvokeAbility("{3}{W}"));
}
private Meadowboon(final Meadowboon card) {

View file

@ -31,7 +31,7 @@ public final class Mournwhelk extends CardImpl {
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
// Evoke {3}{B}
this.addAbility(new EvokeAbility(this, "{3}{B}"));
this.addAbility(new EvokeAbility("{3}{B}"));
}
private Mournwhelk(final Mournwhelk card) {

View file

@ -30,7 +30,7 @@ public final class Mulldrifter extends CardImpl {
// When Mulldrifter enters the battlefield, draw two cards.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(2)));
// Evoke {2}{U}
this.addAbility(new EvokeAbility(this, "{2}{U}"));
this.addAbility(new EvokeAbility("{2}{U}"));
}
private Mulldrifter(final Mulldrifter card) {

View file

@ -37,7 +37,7 @@ public final class Nevermaker extends CardImpl {
this.addAbility(ability);
// Evoke {3}{U}
this.addAbility(new EvokeAbility(this, "{3}{U}"));
this.addAbility(new EvokeAbility("{3}{U}"));
}
private Nevermaker(final Nevermaker card) {

View file

@ -34,7 +34,7 @@ public final class NightIncarnate extends CardImpl {
));
// Evoke {3}{B}
this.addAbility(new EvokeAbility(this, "{3}{B}"));
this.addAbility(new EvokeAbility("{3}{B}"));
}

View file

@ -36,7 +36,7 @@ public final class Offalsnout extends CardImpl {
ability.addTarget(target);
this.addAbility(ability);
// Evoke {B}
this.addAbility(new EvokeAbility(this, "{B}"));
this.addAbility(new EvokeAbility("{B}"));
}
private Offalsnout(final Offalsnout card) {

View file

@ -42,7 +42,7 @@ public final class Reveillark extends CardImpl {
ability.addTarget(new TargetCardInYourGraveyard(0,2,filter));
this.addAbility(ability);
// Evoke {5}{W}
this.addAbility(new EvokeAbility(this, "{5}{W}"));
this.addAbility(new EvokeAbility("{5}{W}"));
}
private Reveillark(final Reveillark card) {

View file

@ -49,7 +49,7 @@ public final class Shriekmaw extends CardImpl {
this.addAbility(ability);
// Evoke {1}{B} (You may cast this spell for its evoke cost. If you do, it's sacrificed when it enters the battlefield.)
this.addAbility(new EvokeAbility(this, "{1}{B}"));
this.addAbility(new EvokeAbility("{1}{B}"));
}
private Shriekmaw(final Shriekmaw card) {

View file

@ -34,7 +34,7 @@ public final class Slithermuse extends CardImpl {
// When Slithermuse leaves the battlefield, choose an opponent. If that player has more cards in hand than you, draw cards equal to the difference.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new SlithermuseEffect(), false));
// Evoke {3}{U}
this.addAbility(new EvokeAbility(this, "{3}{U}"));
this.addAbility(new EvokeAbility("{3}{U}"));
}
private Slithermuse(final Slithermuse card) {

View file

@ -31,7 +31,7 @@ public final class Spitebellows extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Evoke {1}{R}{R}
this.addAbility(new EvokeAbility(this, "{1}{R}{R}"));
this.addAbility(new EvokeAbility("{1}{R}{R}"));
}
private Spitebellows(final Spitebellows card) {

View file

@ -1,7 +1,5 @@
package mage.cards.u;
import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.costs.AlternativeCostSourceAbility;
import mage.abilities.costs.common.ExileFromHandCost;
@ -11,35 +9,33 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class Unmask extends CardImpl {
private static final FilterCard filter = new FilterCard("a black card from your hand");
private static final FilterCard filterNonLand = new FilterCard("nonland card");
static {
filterNonLand.add(Predicates.not(CardType.LAND.getPredicate()));
filter.add(new ColorPredicate(ObjectColor.BLACK));
}
public Unmask(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}");
public Unmask(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// You may exile a black card from your hand rather than pay Unmask's mana cost.
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter))));
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter))));
// Target player reveals their hand. You choose a nonland card from it. That player discards that card.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(filterNonLand, TargetController.ANY));
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(StaticFilters.FILTER_CARD_NON_LAND, TargetController.ANY));
}
private Unmask(final Unmask card) {

View file

@ -48,7 +48,7 @@ public final class Vesperlark extends CardImpl {
this.addAbility(ability);
// Evoke {1}{W}
this.addAbility(new EvokeAbility(this, "{1}{W}"));
this.addAbility(new EvokeAbility("{1}{W}"));
}
private Vesperlark(final Vesperlark card) {

View file

@ -28,7 +28,7 @@ public final class WalkerOfTheGrove extends CardImpl {
// When Walker of the Grove leaves the battlefield, create a 4/4 green Elemental creature token.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new CreateTokenEffect(new WalkerOfTheGroveToken(), 1), false));
// Evoke {4}{G}
this.addAbility(new EvokeAbility(this, "{4}{G}"));
this.addAbility(new EvokeAbility("{4}{G}"));
}
private WalkerOfTheGrove(final WalkerOfTheGrove card) {

View file

@ -34,7 +34,7 @@ public final class Wispmare extends CardImpl {
ability.addTarget(new TargetEnchantmentPermanent());
this.addAbility(ability);
// Evoke {W}
this.addAbility(new EvokeAbility(this, "{W}"));
this.addAbility(new EvokeAbility("{W}"));
}
private Wispmare(final Wispmare card) {

View file

@ -33,6 +33,7 @@ public final class ModernHorizons2 extends ExpansionSet {
cards.add(new SetCardInfo("Counterspell", 267, Rarity.UNCOMMON, mage.cards.c.Counterspell.class));
cards.add(new SetCardInfo("Diamond Lion", 225, Rarity.RARE, mage.cards.d.DiamondLion.class));
cards.add(new SetCardInfo("Flametongue Yearling", 125, Rarity.UNCOMMON, mage.cards.f.FlametongueYearling.class));
cards.add(new SetCardInfo("Grief", 87, Rarity.MYTHIC, mage.cards.g.Grief.class));
cards.add(new SetCardInfo("Marsh Flats", 248, Rarity.RARE, mage.cards.m.MarshFlats.class));
cards.add(new SetCardInfo("Misty Rainforest", 250, Rarity.RARE, mage.cards.m.MistyRainforest.class));
cards.add(new SetCardInfo("Rishadan Dockhand", 59, Rarity.RARE, mage.cards.r.RishadanDockhand.class));

View file

@ -1,20 +1,11 @@
package mage.abilities.keyword;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.EvokedCondition;
import mage.abilities.costs.AlternativeCost2;
import mage.abilities.costs.AlternativeCost2Impl;
import mage.abilities.costs.AlternativeSourceCosts;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.*;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.SacrificeSourceEffect;
@ -24,8 +15,11 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
*
* @author LevelX2
*/
public class EvokeAbility extends StaticAbility implements AlternativeSourceCosts {
@ -38,17 +32,20 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost
// needed to check activation status, if card changes zone after casting it
private int zoneChangeCounter = 0;
public EvokeAbility(Card card, String manaString) {
public EvokeAbility(String manaString) {
this(new ManaCostsImpl<>(manaString));
}
public EvokeAbility(Cost cost) {
super(Zone.ALL, null);
name = EVOKE_KEYWORD;
this.addEvokeCost(manaString);
this.addEvokeCost(cost);
Ability ability = new ConditionalInterveningIfTriggeredAbility(new EntersBattlefieldTriggeredAbility(new SacrificeSourceEffect()), EvokedCondition.instance, "Sacrifice {this} when it enters the battlefield and was evoked.");
ability.setRuleVisible(false);
addSubAbility(ability);
}
public EvokeAbility(final EvokeAbility ability) {
private EvokeAbility(final EvokeAbility ability) {
super(ability);
this.evokeCosts.addAll(ability.evokeCosts);
this.zoneChangeCounter = ability.zoneChangeCounter;
@ -59,8 +56,8 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost
return new EvokeAbility(this);
}
public final AlternativeCost2 addEvokeCost(String manaString) {
AlternativeCost2 evokeCost = new AlternativeCost2Impl(EVOKE_KEYWORD, REMINDER_TEXT, new ManaCostsImpl(manaString));
public final AlternativeCost2 addEvokeCost(Cost cost) {
AlternativeCost2 evokeCost = new AlternativeCost2Impl<>(EVOKE_KEYWORD, REMINDER_TEXT, cost);
evokeCosts.add(evokeCost);
return evokeCost;
}
@ -102,7 +99,7 @@ public class EvokeAbility extends StaticAbility implements AlternativeSourceCost
activateEvoke(evokeCost, game);
ability.getManaCostsToPay().clear();
ability.getCosts().clear();
for (Iterator it = ((Costs) evokeCost).iterator(); it.hasNext();) {
for (Iterator it = ((Costs) evokeCost).iterator(); it.hasNext(); ) {
Cost cost = (Cost) it.next();
if (cost instanceof ManaCostsImpl) {
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());