From 2abe61643ca2bfd9da40d6ca922906c31386ca65 Mon Sep 17 00:00:00 2001 From: ssk97 Date: Mon, 27 Nov 2023 20:41:20 -0800 Subject: [PATCH] [LTC] Implementations part 2/4 (#11470) * Aragorn, Hornburg Hero * Minas Morgul, Dark Fortress * Rohirrim Chargers --- .../src/mage/cards/a/AragornHornburgHero.java | 96 ++++++++++++++++ .../mage/cards/m/MinasMorgulDarkFortress.java | 84 ++++++++++++++ .../src/mage/cards/r/RohirrimChargers.java | 103 ++++++++++++++++++ .../sets/TalesOfMiddleEarthCommander.java | 3 + ...ertCreatureControllerTriggeredAbility.java | 15 ++- .../main/java/mage/counters/CounterType.java | 3 + .../permanent/RenownedPredicate.java | 23 ++++ 7 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/a/AragornHornburgHero.java create mode 100644 Mage.Sets/src/mage/cards/m/MinasMorgulDarkFortress.java create mode 100644 Mage.Sets/src/mage/cards/r/RohirrimChargers.java create mode 100644 Mage/src/main/java/mage/filter/predicate/permanent/RenownedPredicate.java diff --git a/Mage.Sets/src/mage/cards/a/AragornHornburgHero.java b/Mage.Sets/src/mage/cards/a/AragornHornburgHero.java new file mode 100644 index 00000000000..1d9c5d3a2dd --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AragornHornburgHero.java @@ -0,0 +1,96 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsDamageToAPlayerAllTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.RenownAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.RenownedPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class AragornHornburgHero extends CardImpl { + + private static final FilterPermanent filter + = new FilterControlledCreaturePermanent("a renowned creature you control"); + + static { + filter.add(RenownedPredicate.instance); + } + public AragornHornburgHero(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Attacking creatures you control have first strike and renown 1. + Ability ability = new SimpleStaticAbility(new GainAbilityControlledEffect( + FirstStrikeAbility.getInstance(), Duration.WhileOnBattlefield, + StaticFilters.FILTER_ATTACKING_CREATURES + )); + ability.addEffect(new GainAbilityControlledEffect( + new RenownAbility(1), Duration.WhileOnBattlefield, + StaticFilters.FILTER_ATTACKING_CREATURES + ).setText("and renown 1")); + this.addAbility(ability); + // Whenever a renowned creature you control deals combat damage to a player, double the number of +1/+1 counters on it. + this.addAbility(new DealsDamageToAPlayerAllTriggeredAbility( + new AragornDoubleCountersTargetEffect(), filter, + false, SetTargetPointer.PERMANENT, true + )); + + } + + private AragornHornburgHero(final AragornHornburgHero card) { + super(card); + } + + @Override + public AragornHornburgHero copy() { + return new AragornHornburgHero(this); + } +} +//Copied from Elvish Vatkeeper +class AragornDoubleCountersTargetEffect extends OneShotEffect { + + AragornDoubleCountersTargetEffect() { + super(Outcome.Benefit); + staticText = "double the number of +1/+1 counters on it"; + } + + private AragornDoubleCountersTargetEffect(final AragornDoubleCountersTargetEffect effect) { + super(effect); + } + + @Override + public AragornDoubleCountersTargetEffect copy() { + return new AragornDoubleCountersTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + return permanent != null && permanent.addCounters(CounterType.P1P1.createInstance( + permanent.getCounters(game).getCount(CounterType.P1P1) + ), source.getControllerId(), source, game); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MinasMorgulDarkFortress.java b/Mage.Sets/src/mage/cards/m/MinasMorgulDarkFortress.java new file mode 100644 index 00000000000..3ef0a3dae90 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MinasMorgulDarkFortress.java @@ -0,0 +1,84 @@ +package mage.cards.m; + +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTappedAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.mana.BlackManaAbility; +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.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class MinasMorgulDarkFortress extends CardImpl { + + public MinasMorgulDarkFortress(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.supertype.add(SuperType.LEGENDARY); + + // Minas Morgul, Dark Fortress enters the battlefield tapped. + this.addAbility(new EntersBattlefieldTappedAbility()); + + // {T}: Add {B}. + this.addAbility(new BlackManaAbility()); + + // {3}{B}, {T}: Put a shadow counter on target creature. For as long as that creature has a shadow counter on it, it's a Wraith in addition to its other types. + Ability ability = new SimpleActivatedAbility(new AddCountersTargetEffect(CounterType.SHADOW.createInstance()),new ManaCostsImpl<>("{3}{B}")); + ability.addCost(new TapSourceCost()); + ability.addEffect(new MinasMorgulEffect()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private MinasMorgulDarkFortress(final MinasMorgulDarkFortress card) { + super(card); + } + + @Override + public MinasMorgulDarkFortress copy() { + return new MinasMorgulDarkFortress(this); + } +} +//Based on Aquitects Will +class MinasMorgulEffect extends AddCardSubTypeTargetEffect { + + MinasMorgulEffect() { + super(SubType.WRAITH, Duration.Custom); + staticText = "For as long as that creature has a shadow counter on it, it's a Wraith in addition to its other types"; + } + + private MinasMorgulEffect(final MinasMorgulEffect effect) { + super(effect); + } + + @Override + public MinasMorgulEffect copy() { + return new MinasMorgulEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = game.getPermanent(this.targetPointer.getFirst(game, source)); + if (creature == null || creature.getCounters(game).getCount(CounterType.SHADOW) < 1) { + discard(); + return false; + } + return super.apply(game, source); + } +} diff --git a/Mage.Sets/src/mage/cards/r/RohirrimChargers.java b/Mage.Sets/src/mage/cards/r/RohirrimChargers.java new file mode 100644 index 00000000000..a1dfde9cc43 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RohirrimChargers.java @@ -0,0 +1,103 @@ +package mage.cards.r; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ExertCreatureControllerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ExertAbility; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Library; +import mage.players.Player; + +import java.util.UUID; + +/** + * + * @author notgreat + */ +public final class RohirrimChargers extends CardImpl { + + public RohirrimChargers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.KNIGHT); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // You may exert Rohirrim Chargers as it attacks. + this.addAbility(new ExertAbility(null, false)); + // Whenever you exert a creature, reveal cards from the top of your library until you reveal an Equipment card. Put that card onto the battlefield attached to that creature, then put the rest on the bottom of your library in a random order. + this.addAbility(new ExertCreatureControllerTriggeredAbility(new RohirrimChargersEffect(), true)); + } + + private RohirrimChargers(final RohirrimChargers card) { + super(card); + } + + @Override + public RohirrimChargers copy() { + return new RohirrimChargers(this); + } +} + +class RohirrimChargersEffect extends OneShotEffect { + + RohirrimChargersEffect() { + super(Outcome.Benefit); + staticText = "reveal cards from the top of your library until you reveal an Equipment card. "+ + "Put that card onto the battlefield attached to that creature, then put the rest on the bottom of your library in a random order."; + } + + private RohirrimChargersEffect(final RohirrimChargersEffect effect) { + super(effect); + } + + @Override + public RohirrimChargersEffect copy() { + return new RohirrimChargersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + Library library = player.getLibrary(); + if (!library.hasCards()) { + return true; + } + Cards cards = new CardsImpl(); + Card toBattlefield = null; + for (Card card : library.getCards(game)) { + cards.add(card); + if (card.hasSubtype(SubType.EQUIPMENT, game)) { + toBattlefield = card; + break; + } + } + if (toBattlefield != null) { + Permanent attachTarget = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (attachTarget != null) { + game.getState().setValue("attachTo:" + toBattlefield.getId(), attachTarget); + } + player.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game); + if (attachTarget != null) { + attachTarget.addAttachment(toBattlefield.getId(), source, game); + } + } + player.revealCards(source, cards, game); + cards.remove(toBattlefield); + if (!cards.isEmpty()) { + player.putCardsOnBottomOfLibrary(cards, game, source, false); + } + return true; + } +} \ 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 0a5359d1fe0..3043c0433ba 100644 --- a/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java +++ b/Mage.Sets/src/mage/sets/TalesOfMiddleEarthCommander.java @@ -22,6 +22,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Anduril, Narsil Reforged", 491, Rarity.RARE, mage.cards.a.AndurilNarsilReforged.class)); cards.add(new SetCardInfo("Anger", 210, Rarity.UNCOMMON, mage.cards.a.Anger.class)); cards.add(new SetCardInfo("Anguished Unmaking", 265, Rarity.RARE, mage.cards.a.AnguishedUnmaking.class)); + cards.add(new SetCardInfo("Aragorn, Hornburg Hero", 492, Rarity.MYTHIC, mage.cards.a.AragornHornburgHero.class)); cards.add(new SetCardInfo("Aragorn, King of Gondor", 5, Rarity.MYTHIC, mage.cards.a.AragornKingOfGondor.class)); cards.add(new SetCardInfo("Arbor Elf", 232, Rarity.COMMON, mage.cards.a.ArborElf.class)); cards.add(new SetCardInfo("Arboreal Alliance", 497, Rarity.RARE, mage.cards.a.ArborealAlliance.class)); @@ -194,6 +195,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Merciless Executioner", 204, Rarity.UNCOMMON, mage.cards.m.MercilessExecutioner.class)); cards.add(new SetCardInfo("Merry, Warden of Isengard", 61, Rarity.RARE, mage.cards.m.MerryWardenOfIsengard.class)); cards.add(new SetCardInfo("Minamo, School at Water's Edge", 369, Rarity.MYTHIC, mage.cards.m.MinamoSchoolAtWatersEdge.class)); + cards.add(new SetCardInfo("Minas Morgul, Dark Fortress", 514, Rarity.RARE, mage.cards.m.MinasMorgulDarkFortress.class)); cards.add(new SetCardInfo("Mind Stone", 282, Rarity.UNCOMMON, mage.cards.m.MindStone.class)); cards.add(new SetCardInfo("Mirkwood Elk", 41, Rarity.RARE, mage.cards.m.MirkwoodElk.class)); cards.add(new SetCardInfo("Mirkwood Trapper", 62, Rarity.RARE, mage.cards.m.MirkwoodTrapper.class)); @@ -249,6 +251,7 @@ public final class TalesOfMiddleEarthCommander extends ExpansionSet { cards.add(new SetCardInfo("Rings of Brighthearth", 352, Rarity.MYTHIC, mage.cards.r.RingsOfBrighthearth.class)); cards.add(new SetCardInfo("River Kelpie", 524, Rarity.RARE, mage.cards.r.RiverKelpie.class)); cards.add(new SetCardInfo("Rogue's Passage", 326, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); + cards.add(new SetCardInfo("Rohirrim Chargers", 496, Rarity.RARE, mage.cards.r.RohirrimChargers.class)); cards.add(new SetCardInfo("Sail into the West", 68, Rarity.RARE, mage.cards.s.SailIntoTheWest.class)); 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)); diff --git a/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java index 4adbfb98e7e..435d79bf0b5 100644 --- a/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ExertCreatureControllerTriggeredAbility.java @@ -6,19 +6,26 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; /** * @author stravant */ public class ExertCreatureControllerTriggeredAbility extends TriggeredAbilityImpl { + protected final boolean setTargetPointer; public ExertCreatureControllerTriggeredAbility(Effect effect) { + this(effect, false); + } + public ExertCreatureControllerTriggeredAbility(Effect effect, boolean setTargetPointer) { super(Zone.BATTLEFIELD, effect); + this.setTargetPointer = setTargetPointer; setTriggerPhrase("Whenever you exert a creature, "); } protected ExertCreatureControllerTriggeredAbility(final ExertCreatureControllerTriggeredAbility ability) { super(ability); + this.setTargetPointer = ability.setTargetPointer; } @Override @@ -31,7 +38,13 @@ public class ExertCreatureControllerTriggeredAbility extends TriggeredAbilityImp boolean weAreExerting = isControlledBy(event.getPlayerId()); Permanent exerted = game.getPermanent(event.getTargetId()); boolean exertedIsCreature = (exerted != null) && exerted.isCreature(game); - return weAreExerting && exertedIsCreature; + if (weAreExerting && exertedIsCreature) { + if (setTargetPointer) { + getAllEffects().setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + return false; } @Override diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index b96ae1e0c2b..1201f6f5d9d 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -177,6 +177,7 @@ public enum CounterType { QUEST("quest"), SILVER("silver"), SCREAM("scream"), + SHADOW("shadow"), SHELL("shell"), SHIELD("shield"), SHRED("shred"), @@ -312,6 +313,8 @@ public enum CounterType { return new AbilityCounter(new MenaceAbility(), amount); case REACH: return new AbilityCounter(ReachAbility.getInstance(), amount); + case SHADOW: + return new AbilityCounter(ShadowAbility.getInstance(), amount); case TRAMPLE: return new AbilityCounter(TrampleAbility.getInstance(), amount); case VIGILANCE: diff --git a/Mage/src/main/java/mage/filter/predicate/permanent/RenownedPredicate.java b/Mage/src/main/java/mage/filter/predicate/permanent/RenownedPredicate.java new file mode 100644 index 00000000000..1bac7c2eddb --- /dev/null +++ b/Mage/src/main/java/mage/filter/predicate/permanent/RenownedPredicate.java @@ -0,0 +1,23 @@ + +package mage.filter.predicate.permanent; + +import mage.filter.predicate.Predicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * @author notgreat + */ +public enum RenownedPredicate implements Predicate { + instance; + + @Override + public boolean apply(Permanent input, Game game) { + return input.isRenowned(); + } + + @Override + public String toString() { + return "Renowned"; + } +}