From a05b4db27eb450a5f128a5d7bae327bde64bdf02 Mon Sep 17 00:00:00 2001 From: theelk801 Date: Fri, 9 Jan 2026 11:31:29 -0500 Subject: [PATCH] [ECL] Implement Kinscaer Sentry --- .../src/mage/cards/k/KinscaerSentry.java | 88 +++++++++++++++++ .../src/mage/cards/m/MinionOfTheMighty.java | 67 ++----------- .../cards/p/PaladinElizabethTaggerdy.java | 84 ++++++---------- .../src/mage/cards/p/PreeminentCaptain.java | 72 +++----------- .../mage/cards/s/ShadowfaxLordOfHorses.java | 96 +++++++------------ Mage.Sets/src/mage/sets/LorwynEclipsed.java | 2 + .../PutCardFromHandOntoBattlefieldEffect.java | 58 ++++++++--- 7 files changed, 218 insertions(+), 249 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/k/KinscaerSentry.java diff --git a/Mage.Sets/src/mage/cards/k/KinscaerSentry.java b/Mage.Sets/src/mage/cards/k/KinscaerSentry.java new file mode 100644 index 00000000000..a041bdf4951 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KinscaerSentry.java @@ -0,0 +1,88 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; +import mage.abilities.hint.Hint; +import mage.abilities.hint.ValueHint; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class KinscaerSentry extends CardImpl { + + private static final FilterCard filter = new FilterCard( + "creature card with mana value less than or equal to the number of attacking creatures you control" + ); + + static { + filter.add(KinscaerSentryPredicate.instance); + } + + public KinscaerSentry(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.KITHKIN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // First strike + this.addAbility(FirstStrikeAbility.getInstance()); + + // Lifelink + this.addAbility(LifelinkAbility.getInstance()); + + // Whenever this creature attacks, you may put a creature card with mana value X or less from your hand onto the battlefield tapped and attacking, where X is the number of attacking creatures you control. + this.addAbility(new AttacksTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect( + filter, false, true, true + ).setText("you may put a creature card with mana value X or less from your hand onto the battlefield " + + "tapped and attacking, where X is the number of attacking creatures you control")).addHint(KinscaerSentryPredicate.getHint())); + } + + private KinscaerSentry(final KinscaerSentry card) { + super(card); + } + + @Override + public KinscaerSentry copy() { + return new KinscaerSentry(this); + } +} + +enum KinscaerSentryPredicate implements ObjectSourcePlayerPredicate { + instance; + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(AttackingPredicate.instance); + } + + private static final Hint hint = new ValueHint("Attacking creatures you control", new PermanentsOnBattlefieldCount(filter)); + + public static Hint getHint() { + return hint; + } + + @Override + public boolean apply(ObjectSourcePlayer input, Game game) { + return input.getObject().getManaValue() <= game.getBattlefield().count(filter, input.getPlayerId(), input.getSource(), game); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java b/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java index da230db6b23..96f949f66f9 100644 --- a/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java +++ b/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java @@ -1,24 +1,15 @@ package mage.cards.m; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.MenaceAbility; import mage.abilities.keyword.PackTacticsAbility; -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.FilterCard; import mage.filter.common.FilterCreatureCard; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.util.CardUtil; import java.util.UUID; @@ -27,6 +18,12 @@ import java.util.UUID; */ public final class MinionOfTheMighty extends CardImpl { + private static final FilterCard filter = new FilterCreatureCard("a Dragon creature card"); + + static { + filter.add(SubType.DRAGON.getPredicate()); + } + public MinionOfTheMighty(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); @@ -38,7 +35,9 @@ public final class MinionOfTheMighty extends CardImpl { this.addAbility(new MenaceAbility(false)); // Pack tactics — Whenever Minion of the Mighty attacks, if you attacked with creatures wih total power 6 or greater this combat, you may put a Dragon creature card from your hand onto the battlefield tapped and attacking. - this.addAbility(new PackTacticsAbility(new MinionOfTheMightyEffect())); + this.addAbility(new PackTacticsAbility(new PutCardFromHandOntoBattlefieldEffect( + filter, false, true, true + ))); } private MinionOfTheMighty(final MinionOfTheMighty card) { @@ -50,49 +49,3 @@ public final class MinionOfTheMighty extends CardImpl { return new MinionOfTheMighty(this); } } - -class MinionOfTheMightyEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCreatureCard("a Dragon creature card"); - - static { - filter.add(SubType.DRAGON.getPredicate()); - } - - MinionOfTheMightyEffect() { - super(Outcome.Benefit); - staticText = "you may put a Dragon creature card from your hand onto the battlefield tapped and attacking"; - } - - private MinionOfTheMightyEffect(final MinionOfTheMightyEffect effect) { - super(effect); - } - - @Override - public MinionOfTheMightyEffect copy() { - return new MinionOfTheMightyEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - TargetCardInHand target = new TargetCardInHand(filter); - if (controller == null) { - return false; - } - target.choose(outcome, controller.getId(), source.getSourceId(), source, game); - Card card = controller.getHand().get(target.getFirstTarget(), game); - if (card == null) { - return false; - } - controller.moveCards( - card, Zone.BATTLEFIELD, source, game, true, - false, true, null - ); - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent != null) { - game.getCombat().addAttackingCreature(permanent.getId(), game); - } - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PaladinElizabethTaggerdy.java b/Mage.Sets/src/mage/cards/p/PaladinElizabethTaggerdy.java index 9548a0a9b8b..42db506c060 100644 --- a/Mage.Sets/src/mage/cards/p/PaladinElizabethTaggerdy.java +++ b/Mage.Sets/src/mage/cards/p/PaladinElizabethTaggerdy.java @@ -1,33 +1,41 @@ package mage.cards.p; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.BattalionAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.card.ManaValueLessThanOrEqualToSourcePowerPredicate; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.util.CardUtil; +import java.util.Optional; import java.util.UUID; /** - * * @author notgreat */ public final class PaladinElizabethTaggerdy extends CardImpl { + + private static final FilterCard filter = new FilterCreatureCard("creature card with mana value X or less"); + + static { + filter.add(PaladinElizabethTaggerdyPredicate.instance); + } + public PaladinElizabethTaggerdy(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{W}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.KNIGHT); @@ -36,9 +44,11 @@ public final class PaladinElizabethTaggerdy extends CardImpl { // Battalion -- Whenever Paladin Elizabeth Taggerdy and at least two other creatures attack, draw a card, then you may put a creature card with mana value X or less from your hand onto the battlefield tapped and attacking, where X is Paladin Elizabeth Taggerdy's power. Ability ability = new BattalionAbility(new DrawCardSourceControllerEffect(1)); - ability.addEffect(new PaladinElizabethTaggerdyEffect().concatBy(", then")); + ability.addEffect(new PutCardFromHandOntoBattlefieldEffect( + filter, false, true, true + ).concatBy(", then")); + ability.addEffect(new InfoEffect(", where X is {this}'s power")); this.addAbility(ability); - } private PaladinElizabethTaggerdy(final PaladinElizabethTaggerdy card) { @@ -51,50 +61,16 @@ public final class PaladinElizabethTaggerdy extends CardImpl { } } -//Based on Preeminent Captain -class PaladinElizabethTaggerdyEffect extends OneShotEffect { - - private static final FilterCard filter = new FilterCreatureCard("a creature card with mana value less than or equal to {this}'s power"); - - static { - filter.add(ManaValueLessThanOrEqualToSourcePowerPredicate.instance); - } - - public PaladinElizabethTaggerdyEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "you may put a creature card with mana value X or less from your hand onto the battlefield tapped and attacking, where X is {this}'s power"; - } - - private PaladinElizabethTaggerdyEffect(final PaladinElizabethTaggerdyEffect effect) { - super(effect); - } +enum PaladinElizabethTaggerdyPredicate implements ObjectSourcePlayerPredicate { + instance; @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - TargetCardInHand target = new TargetCardInHand(filter); - if (controller != null && target.canChoose(controller.getId(), source, game) - && target.choose(outcome, controller.getId(), source.getSourceId(), source, game)) { - if (!target.getTargets().isEmpty()) { - UUID cardId = target.getFirstTarget(); - Card card = controller.getHand().get(cardId, game); - if (card != null) { - if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null)) { - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent != null) { - game.getCombat().addAttackingCreature(permanent.getId(), game); - } - } - } - } - return true; - } - return false; + public boolean apply(ObjectSourcePlayer input, Game game) { + return Optional + .ofNullable(input.getSource().getSourcePermanentOrLKI(game)) + .map(MageObject::getPower) + .map(MageInt::getValue) + .filter(power -> input.getObject().getManaValue() <= power) + .isPresent(); } - - @Override - public PaladinElizabethTaggerdyEffect copy() { - return new PaladinElizabethTaggerdyEffect(this); - } - } diff --git a/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java b/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java index 52a27a5fbba..c784dddc623 100644 --- a/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java +++ b/Mage.Sets/src/mage/cards/p/PreeminentCaptain.java @@ -1,23 +1,14 @@ package mage.cards.p; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.keyword.FirstStrikeAbility; -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.common.FilterCreatureCard; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.util.CardUtil; import java.util.UUID; @@ -26,6 +17,12 @@ import java.util.UUID; */ public final class PreeminentCaptain extends CardImpl { + private static final FilterCreatureCard filter = new FilterCreatureCard("Soldier creature card"); + + static { + filter.add(SubType.SOLDIER.getPredicate()); + } + public PreeminentCaptain(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); this.subtype.add(SubType.KITHKIN); @@ -35,9 +32,11 @@ public final class PreeminentCaptain extends CardImpl { this.toughness = new MageInt(2); this.addAbility(FirstStrikeAbility.getInstance()); - // Whenever Preeminent Captain attacks, you may put a Soldier creature - // card from your hand onto the battlefield tapped and attacking. - this.addAbility(new AttacksTriggeredAbility(new PreeminentCaptainEffect(), true)); + + // Whenever Preeminent Captain attacks, you may put a Soldier creature card from your hand onto the battlefield tapped and attacking. + this.addAbility(new AttacksTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect( + filter, false, true, true + ), true)); } private PreeminentCaptain(final PreeminentCaptain card) { @@ -49,50 +48,3 @@ public final class PreeminentCaptain extends CardImpl { return new PreeminentCaptain(this); } } - -class PreeminentCaptainEffect extends OneShotEffect { - - private static final FilterCreatureCard filter = new FilterCreatureCard("a soldier creature card"); - - static { - filter.add(SubType.SOLDIER.getPredicate()); - } - - public PreeminentCaptainEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "put a Soldier creature card from your hand onto the battlefield tapped and attacking"; - } - - private PreeminentCaptainEffect(final PreeminentCaptainEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - TargetCardInHand target = new TargetCardInHand(filter); - if (controller != null && target.canChoose(controller.getId(), source, game) - && target.choose(outcome, controller.getId(), source.getSourceId(), source, game)) { - if (!target.getTargets().isEmpty()) { - UUID cardId = target.getFirstTarget(); - Card card = controller.getHand().get(cardId, game); - if (card != null) { - if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null)) { - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent != null) { - game.getCombat().addAttackingCreature(permanent.getId(), game); - } - } - } - } - return true; - } - return false; - } - - @Override - public PreeminentCaptainEffect copy() { - return new PreeminentCaptainEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/s/ShadowfaxLordOfHorses.java b/Mage.Sets/src/mage/cards/s/ShadowfaxLordOfHorses.java index 4256be9eb53..0fec06983df 100644 --- a/Mage.Sets/src/mage/cards/s/ShadowfaxLordOfHorses.java +++ b/Mage.Sets/src/mage/cards/s/ShadowfaxLordOfHorses.java @@ -1,49 +1,56 @@ package mage.cards.s; -import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; +import mage.MageObject; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; -import mage.constants.*; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.filter.FilterCard; import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreatureCard; -import mage.filter.predicate.mageobject.PowerPredicate; +import mage.filter.predicate.ObjectSourcePlayer; +import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.util.CardUtil; + +import java.util.Optional; +import java.util.UUID; /** - * * @author Susucr */ public final class ShadowfaxLordOfHorses extends CardImpl { private static final FilterControlledPermanent filter = new FilterControlledPermanent(SubType.HORSE, "Horses"); + private static final FilterCard filter2 = new FilterCreatureCard("creature card with lesser power"); + + static { + filter.add(ShadowfaxLordOfHorsesPredicate.instance); + } public ShadowfaxLordOfHorses(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}"); - + this.supertype.add(SuperType.LEGENDARY); this.subtype.add(SubType.HORSE); this.power = new MageInt(4); this.toughness = new MageInt(4); // Horses you control have haste. - this.addAbility(new SimpleStaticAbility( - new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect( + HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter + ))); - // Whenever Shadowfax, Lord of Horses attacks, you may put a creature card - // with lesser power from your hand onto the battlefield tapped and attacking. - this.addAbility(new AttacksTriggeredAbility(new ShadowfaxLordOfHorsesEffect())); + // Whenever Shadowfax, Lord of Horses attacks, you may put a creature card with lesser power from your hand onto the battlefield tapped and attacking. + this.addAbility(new AttacksTriggeredAbility(new PutCardFromHandOntoBattlefieldEffect(filter2, false, true, true))); } private ShadowfaxLordOfHorses(final ShadowfaxLordOfHorses card) { @@ -56,55 +63,16 @@ public final class ShadowfaxLordOfHorses extends CardImpl { } } -class ShadowfaxLordOfHorsesEffect extends OneShotEffect { - - ShadowfaxLordOfHorsesEffect() { - super(Outcome.PutCreatureInPlay); - staticText = "you may put a creature card with lesser power " + - "from your hand onto the battlefield tapped and attacking."; - } - - private ShadowfaxLordOfHorsesEffect(final ShadowfaxLordOfHorsesEffect effect) { - super(effect); - } +enum ShadowfaxLordOfHorsesPredicate implements ObjectSourcePlayerPredicate { + instance; @Override - public ShadowfaxLordOfHorsesEffect copy() { - return new ShadowfaxLordOfHorsesEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { - return false; - } - - Permanent shadowfax = source.getSourcePermanentOrLKI(game); - if (shadowfax == null) { - return false; - } - - FilterCreatureCard filter = new FilterCreatureCard("a creature card with lesser power"); - filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, shadowfax.getPower().getValue())); - TargetCardInHand target = new TargetCardInHand(0,1,filter); - target.withNotTarget(true); - - if (!player.choose(outcome, player.getHand(), target, source, game)) { - return false; - } - - Card card = game.getCard(target.getFirstTarget()); - if(card == null) { - return false; - } - - player.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null); - Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game); - if (permanent != null) { - game.getCombat().addAttackingCreature(permanent.getId(), game); - } - - return true; + public boolean apply(ObjectSourcePlayer input, Game game) { + return Optional + .ofNullable(input.getSource().getSourcePermanentOrLKI(game)) + .map(MageObject::getPower) + .map(MageInt::getValue) + .filter(power -> input.getObject().getPower().getValue() < power) + .isPresent(); } } diff --git a/Mage.Sets/src/mage/sets/LorwynEclipsed.java b/Mage.Sets/src/mage/sets/LorwynEclipsed.java index 877d1e56f78..5870ad9fce2 100644 --- a/Mage.Sets/src/mage/sets/LorwynEclipsed.java +++ b/Mage.Sets/src/mage/sets/LorwynEclipsed.java @@ -154,6 +154,8 @@ public final class LorwynEclipsed extends ExpansionSet { cards.add(new SetCardInfo("Island", 275, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Island", 280, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Kinsbaile Aspirant", 21, Rarity.UNCOMMON, mage.cards.k.KinsbaileAspirant.class)); + cards.add(new SetCardInfo("Kinscaer Sentry", 22, Rarity.RARE, mage.cards.k.KinscaerSentry.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Kinscaer Sentry", 300, Rarity.RARE, mage.cards.k.KinscaerSentry.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kirol, Attentive First-Year", 231, Rarity.RARE, mage.cards.k.KirolAttentiveFirstYear.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kirol, Attentive First-Year", 374, Rarity.RARE, mage.cards.k.KirolAttentiveFirstYear.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Kithkeeper", 23, Rarity.UNCOMMON, mage.cards.k.Kithkeeper.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java index 5a67997ff02..7b2a7abb6c9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PutCardFromHandOntoBattlefieldEffect.java @@ -7,10 +7,13 @@ import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; -import mage.filter.common.FilterPermanentCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; + +import java.util.Optional; /** * @author magenoxx_at_gmail.com @@ -20,9 +23,10 @@ public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { private final FilterCard filter; private final boolean useTargetController; private final boolean tapped; + private final boolean attacking; public PutCardFromHandOntoBattlefieldEffect() { - this(new FilterPermanentCard("a permanent card"), false); + this(StaticFilters.FILTER_CARD_A_PERMANENT, false); } public PutCardFromHandOntoBattlefieldEffect(FilterCard filter) { @@ -34,10 +38,15 @@ public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { } public PutCardFromHandOntoBattlefieldEffect(FilterCard filter, boolean useTargetController, boolean tapped) { + this(filter, useTargetController, tapped, false); + } + + public PutCardFromHandOntoBattlefieldEffect(FilterCard filter, boolean useTargetController, boolean tapped, boolean attacking) { super(Outcome.PutCardInPlay); this.filter = filter; this.useTargetController = useTargetController; this.tapped = tapped; + this.attacking = attacking; } protected PutCardFromHandOntoBattlefieldEffect(final PutCardFromHandOntoBattlefieldEffect effect) { @@ -45,6 +54,7 @@ public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { this.filter = effect.filter.copy(); this.useTargetController = effect.useTargetController; this.tapped = effect.tapped; + this.attacking = effect.attacking; } @Override @@ -63,16 +73,20 @@ public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { if (player == null) { return false; } - if (player.chooseUse(Outcome.PutCardInPlay, "Put " + filter.getMessage() + " from your hand onto the battlefield?", source, game)) { - TargetCardInHand target = new TargetCardInHand(filter); - if (player.choose(Outcome.PutCardInPlay, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - return player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null); - } - } + if (!player.chooseUse(Outcome.PutCardInPlay, "Put " + filter.getMessage() + " from your hand onto the battlefield?", source, game)) { + return false; } - return false; + TargetCardInHand target = new TargetCardInHand(filter); + player.choose(Outcome.PutCardInPlay, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null || !player.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null)) { + return false; + } + if (attacking) { + Optional.ofNullable(CardUtil.getPermanentFromCardPutToBattlefield(card, game)) + .ifPresent(permanent -> game.getCombat().addAttackingCreature(permanent.getId(), game)); + } + return true; } @Override @@ -80,11 +94,27 @@ public class PutCardFromHandOntoBattlefieldEffect extends OneShotEffect { if (this.staticText != null && !this.staticText.isEmpty()) { return staticText; } - + StringBuilder sb = new StringBuilder(); if (useTargetController) { - return "that player may put " + filter.getMessage() + " from their hand onto the battlefield" + (this.tapped ? " tapped" : ""); + sb.append("that player"); } else { - return "you may put " + filter.getMessage() + " from your hand onto the battlefield" + (this.tapped ? " tapped" : ""); + sb.append("you"); } + sb.append(" may put "); + sb.append(CardUtil.addArticle(filter.getMessage())); + sb.append(" from "); + if (useTargetController) { + sb.append("their"); + } else { + sb.append("your"); + } + sb.append(" hand onto the battlefield"); + if (tapped) { + sb.append(" tapped"); + } + if (attacking) { + sb.append(" and attacking"); + } + return sb.toString(); } }