[VOW] Implemented Howlpack Piper / WIldsong Howler

This commit is contained in:
Evan Kranzler 2021-11-10 09:47:45 -05:00
parent 81428811fe
commit 599e5c2a4f
7 changed files with 243 additions and 146 deletions

View file

@ -1,7 +1,8 @@
package mage.cards.b;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.TransformsOrEntersTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
@ -10,10 +11,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
@ -34,7 +31,12 @@ public final class BrutalCathar extends CardImpl {
this.secondSideCardClazz = mage.cards.m.MoonrageBrute.class;
// When this creature enters the battlefield or transforms into Brutal Cathar, exile target creature an opponent controls until this creature leaves the battlefield.
this.addAbility(new BrutalCatharTriggeredAbility());
Ability ability = new TransformsOrEntersTriggeredAbility(
new ExileUntilSourceLeavesEffect("creature an opponent controls"), false
);
ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
// Daybound
this.addAbility(new DayboundAbility());
@ -49,48 +51,3 @@ public final class BrutalCathar extends CardImpl {
return new BrutalCathar(this);
}
}
class BrutalCatharTriggeredAbility extends TriggeredAbilityImpl {
public BrutalCatharTriggeredAbility() {
super(Zone.BATTLEFIELD, new ExileUntilSourceLeavesEffect("creature an opponent controls"), false);
this.addTarget(new TargetOpponentsCreaturePermanent());
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
}
public BrutalCatharTriggeredAbility(final BrutalCatharTriggeredAbility ability) {
super(ability);
}
@Override
public BrutalCatharTriggeredAbility copy() {
return new BrutalCatharTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED
|| event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!event.getTargetId().equals(this.getSourceId())) {
return false;
}
switch (event.getType()) {
case TRANSFORMED:
Permanent permanent = getSourcePermanentIfItStillExists(game);
return permanent != null && !permanent.isTransformed();
case ENTERS_THE_BATTLEFIELD:
return true;
}
return false;
}
@Override
public String getRule() {
return "When this creature enters the battlefield or transforms into {this}, " +
"exile target creature an opponent controls until this creature leaves the battlefield.";
}
}

View file

@ -0,0 +1,105 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.CantBeCounteredSourceAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.DayboundAbility;
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.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HowlpackPiper extends CardImpl {
public HowlpackPiper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.secondSideCardClazz = mage.cards.w.WildsongHowler.class;
// This spell can't be countered.
this.addAbility(new CantBeCounteredSourceAbility());
// {1}{G}, {T}: You may put a creature card from your hand onto the battlefield. If it's a Wolf or Werewolf, untap Howlpack Piper. Activate only as a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(
new HowlpackPiperEffect(), new ManaCostsImpl<>("{1}{G}")
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// Daybound
this.addAbility(new DayboundAbility());
}
private HowlpackPiper(final HowlpackPiper card) {
super(card);
}
@Override
public HowlpackPiper copy() {
return new HowlpackPiper(this);
}
}
class HowlpackPiperEffect extends OneShotEffect {
HowlpackPiperEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "you may put a creature card from your hand onto the battlefield. " +
"If it's a Wolf or Werewolf, untap {this}";
}
private HowlpackPiperEffect(final HowlpackPiperEffect effect) {
super(effect);
}
@Override
public HowlpackPiperEffect copy() {
return new HowlpackPiperEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null || player.getHand().count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) {
return false;
}
TargetCard target = new TargetCardInHand(0, 1, StaticFilters.FILTER_CARD_CREATURE);
player.choose(outcome, player.getHand(), target, game);
Card card = game.getCard(target.getFirstTarget());
if (card == null) {
return false;
}
player.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent permanent = game.getPermanent(card.getId());
Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || sourcePermanent == null) {
return true;
}
if (permanent.hasSubtype(SubType.WOLF, game) || permanent.hasSubtype(SubType.WEREWOLF, game)) {
sourcePermanent.untap(game);
}
return true;
}
}

View file

@ -1,7 +1,8 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.TransformsOrEntersTriggeredAbility;
import mage.abilities.common.WerewolfFrontTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GainLifeEffect;
@ -10,10 +11,6 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.WolfToken;
import java.util.UUID;
@ -34,7 +31,11 @@ public final class HuntmasterOfTheFells extends CardImpl {
this.toughness = new MageInt(2);
// Whenever this creature enters the battlefield or transforms into Huntmaster of the Fells, create a 2/2 green Wolf creature token and you gain 2 life.
this.addAbility(new HuntmasterOfTheFellsAbility());
Ability ability = new TransformsOrEntersTriggeredAbility(
new CreateTokenEffect(new WolfToken()), false, true
);
ability.addEffect(new GainLifeEffect(2).concatBy("and"));
this.addAbility(ability);
// At the beginning of each upkeep, if no spells were cast last turn, transform Huntmaster of the Fells.
this.addAbility(new TransformAbility());
@ -50,44 +51,3 @@ public final class HuntmasterOfTheFells extends CardImpl {
return new HuntmasterOfTheFells(this);
}
}
class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl {
public HuntmasterOfTheFellsAbility() {
super(Zone.BATTLEFIELD, new CreateTokenEffect(new WolfToken()), false);
this.addEffect(new GainLifeEffect(2));
}
public HuntmasterOfTheFellsAbility(final HuntmasterOfTheFellsAbility ability) {
super(ability);
}
@Override
public HuntmasterOfTheFellsAbility copy() {
return new HuntmasterOfTheFellsAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TRANSFORMED && event.getTargetId().equals(this.getSourceId())) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && !permanent.isTransformed()) {
return true;
}
}
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId())) {
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature enters the battlefield or transforms into {this}, create a 2/2 green Wolf creature token and you gain 2 life.";
}
}

View file

@ -1,16 +1,16 @@
package mage.cards.u;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.Ability;
import mage.abilities.common.TransformsOrEntersTriggeredAbility;
import mage.abilities.common.WerewolfFrontTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@ -28,11 +28,14 @@ public final class UlrichOfTheKrallenhorde extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.secondSideCardClazz = UlrichUncontestedAlpha.class;
// Whenever this creature enters the battlefield or transforms into Ulrich of the Krallenhorde, target creature gets +4/+4 until end of turn.
this.addAbility(new UlrichOfTheKrallenhordeAbility());
Ability ability = new TransformsOrEntersTriggeredAbility(
new BoostTargetEffect(4, 4), false, true
);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// At the beginning of each upkeep, if no spells were cast last turn, transform Ulrich of the Krallenhorde.
this.addAbility(new TransformAbility());
@ -48,44 +51,3 @@ public final class UlrichOfTheKrallenhorde extends CardImpl {
return new UlrichOfTheKrallenhorde(this);
}
}
class UlrichOfTheKrallenhordeAbility extends TriggeredAbilityImpl {
public UlrichOfTheKrallenhordeAbility() {
super(Zone.BATTLEFIELD, new BoostTargetEffect(4, 4, Duration.EndOfTurn), false);
this.addTarget(new TargetCreaturePermanent());
}
public UlrichOfTheKrallenhordeAbility(final UlrichOfTheKrallenhordeAbility ability) {
super(ability);
}
@Override
public UlrichOfTheKrallenhordeAbility copy() {
return new UlrichOfTheKrallenhordeAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TRANSFORMED && event.getTargetId().equals(this.getSourceId())) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && !permanent.isTransformed()) {
return true;
}
}
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId())) {
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature enters the battlefield or transforms into Ulrich of the Krallenhorde, target creature gets +4/+4 until end of turn.";
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.common.TransformsOrEntersTriggeredAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WildsongHowler extends CardImpl {
public WildsongHowler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
this.color.setGreen(true);
this.nightCard = true;
// Whenever this creature enters the battlefield or transforms into Wildsong Howler, look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(new TransformsOrEntersTriggeredAbility(new LookLibraryAndPickControllerEffect(
StaticValue.get(5), false, StaticValue.get(1),
StaticFilters.FILTER_CARD_CREATURE, Zone.LIBRARY, false,
true, false, Zone.HAND, true, false, false
).setText("look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order"), false));
// Nightbound
this.addAbility(new NightboundAbility());
}
private WildsongHowler(final WildsongHowler card) {
super(card);
}
@Override
public WildsongHowler copy() {
return new WildsongHowler(this);
}
}

View file

@ -171,6 +171,7 @@ public final class InnistradCrimsonVow extends ExpansionSet {
cards.add(new SetCardInfo("Hookhand Mariner", 203, Rarity.COMMON, mage.cards.h.HookhandMariner.class));
cards.add(new SetCardInfo("Hopeful Initiate", 20, Rarity.RARE, mage.cards.h.HopefulInitiate.class));
cards.add(new SetCardInfo("Howling Moon", 204, Rarity.RARE, mage.cards.h.HowlingMoon.class));
cards.add(new SetCardInfo("Howlpack Piper", 205, Rarity.RARE, mage.cards.h.HowlpackPiper.class));
cards.add(new SetCardInfo("Hullbreaker Horror", 63, Rarity.RARE, mage.cards.h.HullbreakerHorror.class));
cards.add(new SetCardInfo("Hungry Ridgewolf", 161, Rarity.COMMON, mage.cards.h.HungryRidgewolf.class));
cards.add(new SetCardInfo("Infestation Expert", 206, Rarity.UNCOMMON, mage.cards.i.InfestationExpert.class));
@ -319,6 +320,7 @@ public final class InnistradCrimsonVow extends ExpansionSet {
cards.add(new SetCardInfo("Wedding Security", 138, Rarity.UNCOMMON, mage.cards.w.WeddingSecurity.class));
cards.add(new SetCardInfo("Welcoming Vampire", 46, Rarity.RARE, mage.cards.w.WelcomingVampire.class));
cards.add(new SetCardInfo("Whispering Wizard", 88, Rarity.UNCOMMON, mage.cards.w.WhisperingWizard.class));
cards.add(new SetCardInfo("Wildsong Howler", 205, Rarity.RARE, mage.cards.w.WildsongHowler.class));
cards.add(new SetCardInfo("Winged Portent", 89, Rarity.RARE, mage.cards.w.WingedPortent.class));
cards.add(new SetCardInfo("Witch's Web", 227, Rarity.COMMON, mage.cards.w.WitchsWeb.class));
cards.add(new SetCardInfo("Witness the Future", 90, Rarity.UNCOMMON, mage.cards.w.WitnessTheFuture.class));

View file

@ -0,0 +1,61 @@
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
* @author TheElk801
*/
public class TransformsOrEntersTriggeredAbility extends TriggeredAbilityImpl {
private final boolean whenever;
public TransformsOrEntersTriggeredAbility(Effect effect, boolean optional) {
this(effect, optional, false);
}
public TransformsOrEntersTriggeredAbility(Effect effect, boolean optional, boolean whenever) {
super(Zone.BATTLEFIELD, effect, optional);
this.whenever = whenever;
}
private TransformsOrEntersTriggeredAbility(final TransformsOrEntersTriggeredAbility ability) {
super(ability);
this.whenever = ability.whenever;
}
@Override
public TransformsOrEntersTriggeredAbility copy() {
return new TransformsOrEntersTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED
|| event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!event.getTargetId().equals(this.getSourceId())) {
return false;
}
switch (event.getType()) {
case TRANSFORMED:
Permanent permanent = getSourcePermanentIfItStillExists(game);
return permanent != null && !permanent.isTransformed();
case ENTERS_THE_BATTLEFIELD:
return true;
}
return false;
}
@Override
public String getTriggerPhrase() {
return "When" + (whenever ? "ever" : "") + " this creature enters the battlefield or transforms into {this}, ";
}
}