diff --git a/Mage.Sets/src/mage/cards/m/MoriaScavenger.java b/Mage.Sets/src/mage/cards/m/MoriaScavenger.java new file mode 100644 index 00000000000..55fda67714c --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoriaScavenger.java @@ -0,0 +1,82 @@ +package mage.cards.m; + +import java.util.Collection; +import java.util.UUID; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.keyword.AmassEffect; +import mage.constants.SubType; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; +import mage.target.common.TargetCardInHand; +import mage.util.CardUtil; + +/** + * @author rullinoiz + */ +public final class MoriaScavenger extends CardImpl { + + public MoriaScavenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); + + this.subtype.add(SubType.ORC); + this.subtype.add(SubType.ROGUE); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Deathtouch + this.addAbility(DeathtouchAbility.getInstance()); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // {T}, Discard a card: Draw a card. + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), + new TapSourceCost()); + ability.addCost(new DiscardTargetCost(new TargetCardInHand())); + + // If the discarded card was a creature card, amass Orcs 1. + ability.addEffect(new ConditionalOneShotEffect( + new AmassEffect(1, SubType.ORC), + MoriaScavengerCondition.instance + )); + + this.addAbility(ability); + } + + private MoriaScavenger(final MoriaScavenger card) { + super(card); + } + + @Override + public MoriaScavenger copy() { + return new MoriaScavenger(this); + } +} + +enum MoriaScavengerCondition implements Condition { + instance; + + // code "somewhat" stolen from Necromancers Stockpile + @Override + public boolean apply(Game game, Ability source) { + return CardUtil.castStream(source.getCosts().stream(), DiscardTargetCost.class) + .map(DiscardTargetCost::getCards) + .flatMap(Collection::stream) + .anyMatch(card -> card.isCreature(game)); + } + + @Override + public String toString() { return "the discarded card was a creature card"; } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SarumanTheWhiteHand.java b/Mage.Sets/src/mage/cards/s/SarumanTheWhiteHand.java new file mode 100644 index 00000000000..16e3c906f39 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SarumanTheWhiteHand.java @@ -0,0 +1,91 @@ +package mage.cards.s; + +import java.util.UUID; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.keyword.AmassEffect; +import mage.abilities.keyword.WardAbility; +import mage.constants.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.predicate.Predicates; + +import mage.game.Game; +import mage.game.stack.Spell; + +/** + * @author rullinoiz + */ +public final class SarumanTheWhiteHand extends CardImpl { + + private static final FilterPermanent orcAndGoblinFilter = new FilterPermanent("Goblins and Orcs"); + + static { + orcAndGoblinFilter.add(Predicates.or( + SubType.ORC.getPredicate(), + SubType.GOBLIN.getPredicate() + )); + } + + public SarumanTheWhiteHand(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.AVATAR); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + + // Whenever you cast a noncreature spell, amass Orcs X, where X is that spell's mana value. + this.addAbility(new SpellCastControllerTriggeredAbility( + new SarumanTheWhiteHandEffect(), + StaticFilters.FILTER_SPELL_A_NON_CREATURE, + false + )); + + // Goblins and Orcs you control have ward {2}. + this.addAbility(new SimpleStaticAbility( + new GainAbilityControlledEffect( + new WardAbility(new GenericManaCost(2), false), + Duration.WhileOnBattlefield, + orcAndGoblinFilter + ) + )); + } + + private SarumanTheWhiteHand(final SarumanTheWhiteHand card) { + super(card); + } + + @Override + public SarumanTheWhiteHand copy() { + return new SarumanTheWhiteHand(this); + } +} + +class SarumanTheWhiteHandEffect extends OneShotEffect { + + public SarumanTheWhiteHandEffect() { + super(Outcome.Benefit); + staticText = "amass Orcs X, where X is that spell's mana value"; + } + + private SarumanTheWhiteHandEffect(final SarumanTheWhiteHandEffect effect) { super(effect); } + + @Override + public SarumanTheWhiteHandEffect copy() { return new SarumanTheWhiteHandEffect(this); } + + @Override + public boolean apply(Game game, Ability source) { + Spell spell = (Spell) getValue("spellCast"); + return spell != null && AmassEffect.doAmass(spell.getManaValue(), SubType.ORC, game, source) != null; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/w/WakeTheDragon.java b/Mage.Sets/src/mage/cards/w/WakeTheDragon.java new file mode 100644 index 00000000000..ff72e2755f5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WakeTheDragon.java @@ -0,0 +1,37 @@ +package mage.cards.w; + +import java.util.UUID; + +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.DragonMenaceAndStealArtifactToken; + +/** + * @author rullinoiz + */ +public final class WakeTheDragon extends CardImpl { + + public WakeTheDragon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}{R}"); + + + // Create a 6/6 black and red Dragon creature token with flying, menace, and "Whenever this creature deals combat damage to a player, gain control of target artifact that player controls." + this.getSpellAbility().addEffect(new CreateTokenEffect(new DragonMenaceAndStealArtifactToken())); + + // Flashback {6}{B}{R} + this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{6}{B}{R}"))); + } + + private WakeTheDragon(final WakeTheDragon card) { + super(card); + } + + @Override + public WakeTheDragon copy() { + return new WakeTheDragon(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java index 95769f8ffe6..8ecae5fbf26 100644 --- a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java +++ b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java @@ -159,6 +159,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Mirkwood Elk", 41, Rarity.RARE, mage.cards.m.MirkwoodElk.class)); cards.add(new SetCardInfo("Model of Unity", 78, Rarity.RARE, mage.cards.m.ModelOfUnity.class)); cards.add(new SetCardInfo("Monstrosity of the Lake", 22, Rarity.RARE, mage.cards.m.MonstrosityOfTheLake.class)); + cards.add(new SetCardInfo("Moria Scavenger", 63, Rarity.RARE, mage.cards.m.MoriaScavenger.class)); cards.add(new SetCardInfo("Mortify", 269, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); cards.add(new SetCardInfo("Mouth of Ronom", 370, Rarity.MYTHIC, mage.cards.m.MouthOfRonom.class)); cards.add(new SetCardInfo("Murmuring Bosk", 320, Rarity.RARE, mage.cards.m.MurmuringBosk.class)); @@ -198,6 +199,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Sam, Loyal Attendant", 7, Rarity.MYTHIC, mage.cards.s.SamLoyalAttendant.class)); cards.add(new SetCardInfo("Sandsteppe Citadel", 327, Rarity.UNCOMMON, mage.cards.s.SandsteppeCitadel.class)); cards.add(new SetCardInfo("Sanguine Bond", 208, Rarity.RARE, mage.cards.s.SanguineBond.class)); + cards.add(new SetCardInfo("Saruman, the White Hand", 8, Rarity.MYTHIC, mage.cards.s.SarumanTheWhiteHand.class)); cards.add(new SetCardInfo("Sauron, Lord of the Rings", 4, Rarity.MYTHIC, mage.cards.s.SauronLordOfTheRings.class)); cards.add(new SetCardInfo("Savvy Hunter", 271, Rarity.UNCOMMON, mage.cards.s.SavvyHunter.class)); cards.add(new SetCardInfo("Scattered Groves", 328, Rarity.RARE, mage.cards.s.ScatteredGroves.class)); @@ -254,6 +256,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Village Bell-Ringer", 181, Rarity.COMMON, mage.cards.v.VillageBellRinger.class)); cards.add(new SetCardInfo("Vineglimmer Snarl", 343, Rarity.RARE, mage.cards.v.VineglimmerSnarl.class)); cards.add(new SetCardInfo("Visions of Glory", 182, Rarity.RARE, mage.cards.v.VisionsOfGlory.class)); + cards.add(new SetCardInfo("Wake the Dragon", 74, Rarity.RARE, mage.cards.w.WakeTheDragon.class)); cards.add(new SetCardInfo("Wasteland", 376, Rarity.MYTHIC, mage.cards.w.Wasteland.class)); cards.add(new SetCardInfo("Wayfarer's Bauble", 290, Rarity.COMMON, mage.cards.w.WayfarersBauble.class)); cards.add(new SetCardInfo("Weathered Wayfarer", 183, Rarity.RARE, mage.cards.w.WeatheredWayfarer.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java b/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java new file mode 100644 index 00000000000..f86e1af2174 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DragonMenaceAndStealArtifactToken.java @@ -0,0 +1,81 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.MenaceAbility; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterArtifactPermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.DamagedPlayerEvent; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.common.TargetArtifactPermanent; + +public class DragonMenaceAndStealArtifactToken extends TokenImpl { + + public DragonMenaceAndStealArtifactToken() { + super("Dragon Token", "6/6 black and red Dragon creature token with flying, menace, and \"Whenever this creature deals combat damage to a player, gain control of target artifact that player controls.\""); + cardType.add(CardType.CREATURE); + color.setBlack(true); + color.setRed(true); + subtype.add(SubType.DRAGON); + power = new MageInt(6); + toughness = new MageInt(6); + addAbility(FlyingAbility.getInstance()); + addAbility(new MenaceAbility(false)); + + addAbility(new DragonTokenTriggeredAbility()); + } + + public DragonMenaceAndStealArtifactToken(final DragonMenaceAndStealArtifactToken token) { super(token); } + + public DragonMenaceAndStealArtifactToken copy() { return new DragonMenaceAndStealArtifactToken(this); } + +} + +class DragonTokenTriggeredAbility extends TriggeredAbilityImpl { + + public DragonTokenTriggeredAbility() { + super(Zone.BATTLEFIELD, new GainControlTargetEffect(Duration.EndOfGame)); + this.addTarget(new TargetArtifactPermanent()); + } + + public DragonTokenTriggeredAbility(final DragonTokenTriggeredAbility ability) { super(ability); } + + @Override + public DragonTokenTriggeredAbility copy() { return new DragonTokenTriggeredAbility(this); } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; + if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) { + Player opponent = game.getPlayer(event.getPlayerId()); + if (opponent != null) { + FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact " + opponent.getLogName() + " controls"); + filter.add(new ControllerIdPredicate(opponent.getId())); + + this.getTargets().clear(); + this.addTarget(new TargetArtifactPermanent(filter)); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever this creature deals combat damage to a player, gain control of target artifact that player controls."; + } + +}