diff --git a/Mage.Sets/src/mage/cards/t/ThunderkinAwakener.java b/Mage.Sets/src/mage/cards/t/ThunderkinAwakener.java new file mode 100644 index 00000000000..d4528600880 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThunderkinAwakener.java @@ -0,0 +1,131 @@ +package mage.cards.t; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.mageobject.ToughnessPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetadjustment.TargetAdjuster; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author JayDi85 + */ +public final class ThunderkinAwakener extends CardImpl { + + public ThunderkinAwakener(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.SHAMAN); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Whenever Thunderkin Awakener attacks, choose target Elemental creature card in your graveyard + // with toughness less than Thunderkin Awakener’s toughness. Return that card to the battlefield tapped and attacking. + // Sacrifice it at the beginning of the next end step. + Ability ability = new AttacksTriggeredAbility(new ThunderkinAwakenerEffect(), false); + ability.setTargetAdjuster(ThunderkinAwakenerAdjuster.instance); + this.addAbility(ability); + } + + public ThunderkinAwakener(final ThunderkinAwakener card) { + super(card); + } + + @Override + public ThunderkinAwakener copy() { + return new ThunderkinAwakener(this); + } +} + +enum ThunderkinAwakenerAdjuster implements TargetAdjuster { + instance; + + @Override + public void adjustTargets(Ability ability, Game game) { + // target Elemental creature card in your graveyard with toughness less than Thunderkin Awakener’s toughness + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); + if (sourcePermanent != null) { + int xValue = sourcePermanent.getToughness().getValue(); + FilterCard filter = new FilterCreatureCard("creature card in your graveyard with toughness less than Thunderkin Awakener’s toughness"); + filter.add(new SubtypePredicate(SubType.ELEMENTAL)); + filter.add(new ToughnessPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + + ability.getTargets().clear(); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + } + } +} + +class ThunderkinAwakenerEffect extends OneShotEffect { + + public ThunderkinAwakenerEffect() { + super(Outcome.Benefit); + staticText = "choose target Elemental creature card in your graveyard with toughness less than Thunderkin Awakener’s toughness." + + " Return that card to the battlefield tapped and attacking. Sacrifice it at the beginning of the next end step"; + } + + public ThunderkinAwakenerEffect(final ThunderkinAwakenerEffect effect) { + super(effect); + } + + @Override + public ThunderkinAwakenerEffect copy() { + return new ThunderkinAwakenerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Card creatureCard = game.getCard(this.getTargetPointer().getFirst(game, source)); + if (controller != null && creatureCard != null) { + + // Return that card to the battlefield tapped and attacking + Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect(false, true, true); + effect.setTargetPointer(new FixedTarget(creatureCard.getId())); + effect.apply(game, source); + + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + // Sacrifice it at the beginning of the next end step + SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect("Sacrifice " + permanent.getName(), source.getControllerId()); + sacrificeEffect.setTargetPointer(new FixedTarget(permanent, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect); + game.addDelayedTriggeredAbility(delayedAbility, source); + + // info + InfoEffect.addInfoToPermanent(game, source, permanent, "Warning: It will be sacrificed at the beginning of the next end step"); + } + + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/CoreSet2020.java b/Mage.Sets/src/mage/sets/CoreSet2020.java index 07ff3b6a13e..6d1a215e670 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2020.java +++ b/Mage.Sets/src/mage/sets/CoreSet2020.java @@ -309,6 +309,7 @@ public final class CoreSet2020 extends ExpansionSet { cards.add(new SetCardInfo("Thornwood Falls", 258, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class)); cards.add(new SetCardInfo("Thought Distortion", 117, Rarity.UNCOMMON, mage.cards.t.ThoughtDistortion.class)); cards.add(new SetCardInfo("Thrashing Brontodon", 197, Rarity.UNCOMMON, mage.cards.t.ThrashingBrontodon.class)); + cards.add(new SetCardInfo("Thunderkin Awakener", 162, Rarity.RARE, mage.cards.t.ThunderkinAwakener.class)); cards.add(new SetCardInfo("Tomebound Lich", 219, Rarity.UNCOMMON, mage.cards.t.TomeboundLich.class)); cards.add(new SetCardInfo("Tranquil Cove", 259, Rarity.COMMON, mage.cards.t.TranquilCove.class)); cards.add(new SetCardInfo("Twinblade Paladin", 285, Rarity.UNCOMMON, mage.cards.t.TwinbladePaladin.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/InfoEffect.java b/Mage/src/main/java/mage/abilities/effects/common/InfoEffect.java index 64775d04ab2..7ac754b6097 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/InfoEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/InfoEffect.java @@ -1,14 +1,17 @@ - - package mage.abilities.effects.common; -import mage.constants.Outcome; import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** - * * @author BetaSteward_at_googlemail.com */ public class InfoEffect extends OneShotEffect { @@ -32,4 +35,11 @@ public class InfoEffect extends OneShotEffect { return new InfoEffect(this); } + public static void addInfoToPermanent(Game game, Ability source, Permanent permanent, String info) { + // add simple static info to permanent's rules + SimpleStaticAbility ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(info)); + GainAbilityTargetEffect gainAbilityEffect = new GainAbilityTargetEffect(ability, Duration.WhileOnBattlefield); + gainAbilityEffect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(gainAbilityEffect, source); + } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java index e8bd4ab47ae..547c62063c9 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToBattlefieldUnderYourControlTargetEffect.java @@ -1,7 +1,5 @@ - package mage.abilities.effects.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -15,32 +13,52 @@ import mage.game.Game; import mage.players.Player; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author noxx */ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffect { private boolean fromExileZone; + private boolean tapped; + private boolean attacking; public ReturnToBattlefieldUnderYourControlTargetEffect() { this(false); } - /** - * - * @param fromExileZone - the card will only be returned if it's still in - * the source object specific exile zone - */ public ReturnToBattlefieldUnderYourControlTargetEffect(boolean fromExileZone) { + this(fromExileZone, false, false); + } + + /** + * @param fromExileZone - the card will only be returned if it's still in + * the source object specific exile zone + */ + public ReturnToBattlefieldUnderYourControlTargetEffect(boolean fromExileZone, boolean tapped, boolean attacking) { super(Outcome.Benefit); - staticText = "return that card to the battlefield under your control"; this.fromExileZone = fromExileZone; + this.tapped = tapped; + this.attacking = attacking; + + updateText(); } public ReturnToBattlefieldUnderYourControlTargetEffect(final ReturnToBattlefieldUnderYourControlTargetEffect effect) { super(effect); this.fromExileZone = effect.fromExileZone; + this.tapped = effect.tapped; + this.attacking = effect.attacking; + + updateText(); + } + + private void updateText() { + this.staticText = "return that card to the battlefield under your control" + + (tapped ? " tapped" : "") + + (tapped && attacking ? " and" : "") + + (attacking ? " attacking" : ""); } @Override @@ -61,8 +79,7 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe for (UUID targetId : this.getTargetPointer().getTargets(game, source)) { if (exileZone.contains(targetId)) { cardsToBattlefield.add(targetId); - } - else { + } else { Card card = game.getCard(targetId); if (card instanceof MeldCard) { MeldCard meldCard = (MeldCard) card; @@ -82,8 +99,13 @@ public class ReturnToBattlefieldUnderYourControlTargetEffect extends OneShotEffe } else { cardsToBattlefield.addAll(getTargetPointer().getTargets(game, source)); } - if (!cardsToBattlefield.isEmpty()) { - controller.moveCards(cardsToBattlefield, Zone.BATTLEFIELD, source, game); + + for (Card card : cardsToBattlefield.getCards(game)) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game, tapped, false, false, null)) { + if (attacking) { + game.getCombat().addAttackingCreature(card.getId(), game); + } + } } return true; }