diff --git a/Mage.Sets/src/mage/cards/w/WingsteedTrainer.java b/Mage.Sets/src/mage/cards/w/WingsteedTrainer.java new file mode 100644 index 0000000000..2a4ab3c2b0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WingsteedTrainer.java @@ -0,0 +1,37 @@ +package mage.cards.w; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; +import mage.abilities.effects.common.ConjureCardEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class WingsteedTrainer extends CardImpl { + + public WingsteedTrainer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}"); + + this.subtype.add(SubType.HUMAN); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Wingsteed Trainer enters the battlefield or attacks, conjure a Stormfront Pegasus card into your hand. + this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new ConjureCardEffect("Stormfront Pegasus"))); + } + + private WingsteedTrainer(final WingsteedTrainer card) { + super(card); + } + + @Override + public WingsteedTrainer copy() { + return new WingsteedTrainer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java index c0f13b50a8..9df1ec883b 100644 --- a/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java +++ b/Mage.Sets/src/mage/sets/JumpstartHistoricHorizons.java @@ -24,5 +24,6 @@ public final class JumpstartHistoricHorizons extends ExpansionSet { cards.add(new SetCardInfo("Faceless Agent", 31, Rarity.COMMON, mage.cards.f.FacelessAgent.class)); cards.add(new SetCardInfo("Manor Guardian", 16, Rarity.UNCOMMON, mage.cards.m.ManorGuardian.class)); cards.add(new SetCardInfo("Skyshroud Lookout", 29, Rarity.UNCOMMON, mage.cards.s.SkyshroudLookout.class)); + cards.add(new SetCardInfo("Wingsteed Trainer", 6, Rarity.UNCOMMON, mage.cards.w.WingsteedTrainer.class)); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/digital/ConjureTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/digital/ConjureTest.java new file mode 100644 index 0000000000..22ba17e988 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/digital/ConjureTest.java @@ -0,0 +1,48 @@ +package org.mage.test.cards.digital; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class ConjureTest extends CardTestPlayerBase { + + private static final String trainer = "Wingsteed Trainer"; + private static final String pegasus = "Stormfront Pegasus"; + + @Test + public void testConjureToHand() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 4); + addCard(Zone.HAND, playerA, trainer); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, trainer); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, trainer, 1); + assertHandCount(playerA, pegasus, 1); + } + + @Test + public void testConjureToHandAndCast() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 6); + addCard(Zone.HAND, playerA, trainer); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, trainer); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pegasus); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + assertAllCommandsUsed(); + + assertPermanentCount(playerA, trainer, 1); + assertPermanentCount(playerA, pegasus, 1); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ConjureCardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ConjureCardEffect.java new file mode 100644 index 0000000000..ddb8bd59a1 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ConjureCardEffect.java @@ -0,0 +1,94 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.repository.CardCriteria; +import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.util.CardUtil; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author TheElk801 + */ +public class ConjureCardEffect extends OneShotEffect { + + private final String cardName; + private final Zone zone; + private final int amount; + + public ConjureCardEffect(String cardName) { + this(cardName, Zone.HAND, 1); + } + + public ConjureCardEffect(String cardName, Zone zone, int amount) { + super(Outcome.Benefit); + this.cardName = cardName; + this.zone = zone; + this.amount = amount; + } + + private ConjureCardEffect(final ConjureCardEffect effect) { + super(effect); + this.cardName = effect.cardName; + this.zone = effect.zone; + this.amount = effect.amount; + } + + @Override + public ConjureCardEffect copy() { + return new ConjureCardEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + CardInfo cardInfo = CardRepository + .instance + .findCards(new CardCriteria().nameExact(cardName)) + .stream() + .findFirst() + .orElse(null); + if (cardInfo == null) { + return false; + } + Set cards = new HashSet<>(); + for (int i = 0; i < amount; i++) { + Card card = cardInfo.getCard(); + cards.add(card); + } + game.loadCards(cards, source.getControllerId()); + return player.moveCards(cards, zone, source, game); + } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder("conjure "); + sb.append(CardUtil.numberToText(amount, "a")); + sb.append(' '); + sb.append(cardName); + sb.append("card"); + sb.append(amount > 1 ? "s " : " "); + switch (zone) { + case HAND: + case GRAVEYARD: + sb.append("into your"); + break; + case BATTLEFIELD: + sb.append("onto the"); + } + sb.append(zone); + return sb.toString(); + } +}