diff --git a/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java b/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java new file mode 100644 index 00000000000..a266101fac6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MinionOfTheMighty.java @@ -0,0 +1,97 @@ +package mage.cards.m; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +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 java.util.UUID; + +/** + * @author TheElk801 + */ +public final class MinionOfTheMighty extends CardImpl { + + public MinionOfTheMighty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}"); + + this.subtype.add(SubType.KOBOLD); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Menace + this.addAbility(new MenaceAbility()); + + // 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())); + } + + private MinionOfTheMighty(final MinionOfTheMighty card) { + super(card); + } + + @Override + public MinionOfTheMighty copy() { + 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(), 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 = game.getPermanent(card.getId()); + if (permanent != null) { + game.getCombat().addAttackingCreature(permanent.getId(), game); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java index 5795f4e914e..54f91df601e 100644 --- a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java +++ b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java @@ -39,6 +39,7 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet { cards.add(new SetCardInfo("Hive of the Eye Tyrant", 258, Rarity.RARE, mage.cards.h.HiveOfTheEyeTyrant.class)); cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Lolth, Spider Queen", 112, Rarity.MYTHIC, mage.cards.l.LolthSpiderQueen.class)); + cards.add(new SetCardInfo("Minion of the Mighty", 156, Rarity.RARE, mage.cards.m.MinionOfTheMighty.class)); cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nadaar, Selfless Paladin", 27, Rarity.RARE, mage.cards.n.NadaarSelflessPaladin.class)); cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/keyword/PackTacticsAbility.java b/Mage/src/main/java/mage/abilities/keyword/PackTacticsAbility.java new file mode 100644 index 00000000000..4993121b6df --- /dev/null +++ b/Mage/src/main/java/mage/abilities/keyword/PackTacticsAbility.java @@ -0,0 +1,91 @@ +package mage.abilities.keyword; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.AbilityWord; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class PackTacticsAbility extends TriggeredAbilityImpl { + + public PackTacticsAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + this.addWatcher(new PackTacticsAbilityWatcher()); + } + + private PackTacticsAbility(final PackTacticsAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ATTACKER_DECLARED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return getSourceId().equals(event.getSourceId()); + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return PackTacticsAbilityWatcher.checkPlayer(getControllerId(), game); + } + + @Override + public PackTacticsAbility copy() { + return new PackTacticsAbility(this); + } + + @Override + public String getRule() { + return AbilityWord.PACK_TACTICS.formatWord() + + "Whenever {this} attacks, if you attacked with creatures " + + "with total power 6 or greater this combat, " + super.getRule(); + } +} + +class PackTacticsAbilityWatcher extends Watcher { + + private final Map playerMap = new HashMap<>(); + + PackTacticsAbilityWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + switch (event.getType()) { + case BEGIN_COMBAT_STEP_PRE: + playerMap.clear(); + return; + case ATTACKER_DECLARED: + Permanent permanent = game.getPermanent(event.getSourceId()); + if (permanent == null) { + return; + } + playerMap.compute( + permanent.getControllerId(), + (u, i) -> i == null ? + permanent.getPower().getValue() : + Integer.sum(permanent.getPower().getValue(), i) + ); + } + } + + static boolean checkPlayer(UUID playerId, Game game) { + PackTacticsAbilityWatcher watcher = game.getState().getWatcher(PackTacticsAbilityWatcher.class); + return watcher != null && watcher.playerMap.getOrDefault(playerId, 0) >= 6; + } +} diff --git a/Mage/src/main/java/mage/constants/AbilityWord.java b/Mage/src/main/java/mage/constants/AbilityWord.java index 18a15835f04..f032bdb89b5 100644 --- a/Mage/src/main/java/mage/constants/AbilityWord.java +++ b/Mage/src/main/java/mage/constants/AbilityWord.java @@ -34,6 +34,7 @@ public enum AbilityWord { METALCRAFT("Metalcraft"), MAGECRAFT("Magecraft"), MORBID("Morbid"), + PACK_TACTICS("Pack tactics"), PARLEY("Parley"), RADIANCE("Radiance"), RAID("Raid"), @@ -53,6 +54,10 @@ public enum AbilityWord { this.text = text; } + public String formatWord() { + return "" + this + " — "; + } + @Override public String toString() { return text;