diff --git a/Mage.Sets/src/mage/cards/a/AjaniNacatlAvenger.java b/Mage.Sets/src/mage/cards/a/AjaniNacatlAvenger.java new file mode 100644 index 00000000000..ca79322f610 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AjaniNacatlAvenger.java @@ -0,0 +1,192 @@ +package mage.cards.a; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.delayed.ReflexiveTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.dynamicvalue.common.CreaturesYouControlCount; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.CatWarrior21Token; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetAnyTarget; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author Susucr + */ +public final class AjaniNacatlAvenger extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(SubType.CAT, "Cat you control"); + + public AjaniNacatlAvenger(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, ""); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.AJANI); + this.setStartingLoyalty(3); + + this.color.setRed(true); + this.color.setWhite(true); + this.nightCard = true; + + // +2: Put a +1/+1 counter on each Cat you control. + this.addAbility(new LoyaltyAbility( + new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), 2 + )); + + // 0: Create a 2/1 white Car Warrior creature token. When you do, if you control a red permanent other than Ajani, Nacatl Avenger, he deals damage equal to the number of creatures you control to any target. + this.addAbility(new LoyaltyAbility(new AjaniNacatlAvengerZeroEffect(), 0)); + + // -4: Each opponent chooses an artifact, a creature, an enchantment and a planeswalker from among the nonland permanents they control, then sacrifices the rest. + this.addAbility(new LoyaltyAbility(new AjaniNacatlAvengerMinusFourEffect(), -4)); + } + + private AjaniNacatlAvenger(final AjaniNacatlAvenger card) { + super(card); + } + + @Override + public AjaniNacatlAvenger copy() { + return new AjaniNacatlAvenger(this); + } +} + +class AjaniNacatlAvengerZeroEffect extends OneShotEffect { + + private static final FilterPermanent filter = new FilterPermanent("red permanent other than {this}"); + + static { + filter.add(new ColorPredicate(ObjectColor.RED)); + filter.add(AnotherPredicate.instance); + } + + private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter, true); + + AjaniNacatlAvengerZeroEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "Create a 2/1 white Car Warrior creature token. " + + "When you do, if you control a red permanent other than {this}, " + + "he deals damage equal to the number of creatures you control to any target."; + } + + private AjaniNacatlAvengerZeroEffect(final AjaniNacatlAvengerZeroEffect effect) { + super(effect); + } + + @Override + public AjaniNacatlAvengerZeroEffect copy() { + return new AjaniNacatlAvengerZeroEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!new CreateTokenEffect(new CatWarrior21Token()).apply(game, source)) { + return false; + } + + ReflexiveTriggeredAbility reflexive = new ReflexiveTriggeredAbility( + new DamageTargetEffect(CreaturesYouControlCount.instance), + false, + "When you do, if you control a red permanent other than {this}, " + + "he deals damage equal to the number of creatures you control to any target.", + condition + ); + reflexive.addTarget(new TargetAnyTarget()); + game.fireReflexiveTriggeredAbility(reflexive, source); + return true; + } +} + +// Inspired by Mythos of Snapdax +class AjaniNacatlAvengerMinusFourEffect extends OneShotEffect { + + private static final List cardTypes = Arrays.asList( + CardType.ARTIFACT, + CardType.CREATURE, + CardType.ENCHANTMENT, + CardType.PLANESWALKER + ); + + AjaniNacatlAvengerMinusFourEffect() { + super(Outcome.Benefit); + staticText = "Each opponent chooses an artifact, a creature, an enchantment and a planeswalker " + + "from among the nonland permanents they control, then sacrifices the rest."; + } + + private AjaniNacatlAvengerMinusFourEffect(final AjaniNacatlAvengerMinusFourEffect effect) { + super(effect); + } + + @Override + public AjaniNacatlAvengerMinusFourEffect copy() { + return new AjaniNacatlAvengerMinusFourEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + + List playerList = game + .getState() + .getPlayersInRange(source.getControllerId(), game) + .stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .filter(player -> controller.hasOpponent(player.getId(), game)) + .collect(Collectors.toList()); + + Set toKeep = new HashSet(); + for (Player player : playerList) { + for (CardType cardType : cardTypes) { + String message = cardType.toString().equals("Artifact") ? "an " : "a "; + message += cardType.toString().toLowerCase(Locale.ENGLISH); + FilterPermanent filter = new FilterNonlandPermanent(message); + filter.add(cardType.getPredicate()); + filter.add(new ControllerIdPredicate(player.getId())); + if (game.getBattlefield().count(filter, source.getControllerId(), source, game) == 0) { + continue; + } + TargetPermanent target = new TargetPermanent(filter); + target.withNotTarget(true); + player.choose(outcome, target, source, game); + toKeep.add(target.getFirstTarget()); + } + } + + for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_NON_LAND, source.getControllerId(), game)) { + if (permanent == null || toKeep.contains(permanent.getId()) || !controller.hasOpponent(permanent.getControllerId(), game)) { + continue; + } + permanent.sacrifice(source, game); + } + return true; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/a/AjaniNacatlPariah.java b/Mage.Sets/src/mage/cards/a/AjaniNacatlPariah.java new file mode 100644 index 00000000000..dc9a8e0b29c --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AjaniNacatlPariah.java @@ -0,0 +1,61 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.Pronoun; +import mage.abilities.common.DiesOneOrMoreCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ExileAndReturnSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.AnotherPredicate; +import mage.game.permanent.token.CatWarrior21Token; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class AjaniNacatlPariah extends CardImpl { + + public static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.CAT, "other Cats you control"); + + static { + filter.add(AnotherPredicate.instance); + filter.add(TargetController.YOU.getControllerPredicate()); + } + + public AjaniNacatlPariah(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.CAT); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + this.secondSideCardClazz = mage.cards.a.AjaniNacatlAvenger.class; + + // When Ajani, Nacatl Pariah enters the battlefield, create a 2/1 white Cat Warrior creature token. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new CatWarrior21Token()))); + + // Whenever one or more other Cats you control die, you may exile Ajani, then return him to the battlefield transformed under his owner's control. + this.addAbility(new TransformAbility()); + this.addAbility(new DiesOneOrMoreCreatureTriggeredAbility( + new ExileAndReturnSourceEffect(PutCards.BATTLEFIELD_TRANSFORMED, Pronoun.HE), + filter + )); + } + + private AjaniNacatlPariah(final AjaniNacatlPariah card) { + super(card); + } + + @Override + public AjaniNacatlPariah copy() { + return new AjaniNacatlPariah(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3.java b/Mage.Sets/src/mage/sets/ModernHorizons3.java index 505765bde27..a8249702e74 100644 --- a/Mage.Sets/src/mage/sets/ModernHorizons3.java +++ b/Mage.Sets/src/mage/sets/ModernHorizons3.java @@ -21,6 +21,8 @@ public final class ModernHorizons3 extends ExpansionSet { this.hasBasicLands = true; this.hasBoosters = false; // temporary + cards.add(new SetCardInfo("Ajani, Nacatl Avenger", 237, Rarity.MYTHIC, mage.cards.a.AjaniNacatlAvenger.class)); + cards.add(new SetCardInfo("Ajani, Nacatl Pariah", 237, Rarity.MYTHIC, mage.cards.a.AjaniNacatlPariah.class)); cards.add(new SetCardInfo("Bloodstained Mire", 216, Rarity.RARE, mage.cards.b.BloodstainedMire.class)); cards.add(new SetCardInfo("Flare of Cultivation", 154, Rarity.RARE, mage.cards.f.FlareOfCultivation.class)); cards.add(new SetCardInfo("Flooded Strand", 220, Rarity.RARE, mage.cards.f.FloodedStrand.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/CatWarrior21Token.java b/Mage/src/main/java/mage/game/permanent/token/CatWarrior21Token.java new file mode 100644 index 00000000000..88e1019d1ab --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/CatWarrior21Token.java @@ -0,0 +1,30 @@ +package mage.game.permanent.token; + +import mage.MageInt; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * @author Susucr + */ +public final class CatWarrior21Token extends TokenImpl { + + public CatWarrior21Token() { + super("Cat Warrior Token", "2/1 white Cat Warrior creature token"); + + this.power = new MageInt(2); + this.toughness = new MageInt(1); + this.color.setWhite(true); + this.subtype.add(SubType.CAT); + this.subtype.add(SubType.WARRIOR); + this.cardType.add(CardType.CREATURE); + } + + private CatWarrior21Token(final CatWarrior21Token token) { + super(token); + } + + public CatWarrior21Token copy() { + return new CatWarrior21Token(this); + } +}