[NEO] Implemented The Long Reach of Night / Animus of Night's Reach

This commit is contained in:
Evan Kranzler 2022-02-04 09:16:57 -05:00
parent 66148a92d1
commit 6c9fc1679d
4 changed files with 162 additions and 13 deletions

View file

@ -0,0 +1,92 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInAllGraveyardsCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.card.DefendingPlayerOwnsCardPredicate;
import mage.game.Game;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class AnimusOfNightsReach extends CardImpl {
private static final FilterCard filter
= new FilterCreatureCard("creature cards in defending player's graveyard");
static {
filter.add(DefendingPlayerOwnsCardPredicate.instance);
}
private static final DynamicValue xValue = new CardsInAllGraveyardsCount(filter);
public AnimusOfNightsReach(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(0);
this.toughness = new MageInt(4);
this.color.setBlack(true);
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility());
// Whenever Animus of Night's Reach attacks, it gets +X/+0 until end of turn, where X is the number of creature cards in defending player's graveyard.
this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(
xValue, StaticValue.get(0), Duration.EndOfTurn, true)
).addHint(AnimusOfNightsReachHint.instance));
}
private AnimusOfNightsReach(final AnimusOfNightsReach card) {
super(card);
}
@Override
public AnimusOfNightsReach copy() {
return new AnimusOfNightsReach(this);
}
}
enum AnimusOfNightsReachHint implements Hint {
instance;
@Override
public String getText(Game game, Ability ability) {
return "Cards in each opponent's graveyard:<br>"
+ game
.getOpponents(ability.getControllerId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(player -> player
.getName()
+ ": " + player
.getGraveyard()
.count(StaticFilters.FILTER_CARD_CREATURE, game))
.collect(Collectors.joining("<br>"));
}
@Override
public AnimusOfNightsReachHint copy() {
return instance;
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.t;
import mage.abilities.common.SagaAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
import mage.abilities.effects.common.SacrificeOpponentsUnlessPayEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TheLongReachOfNight extends CardImpl {
public TheLongReachOfNight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}");
this.subtype.add(SubType.SAGA);
this.secondSideCardClazz = mage.cards.a.AnimusOfNightsReach.class;
// (As this Saga enters and after your draw step, add a lore counter.)
SagaAbility sagaAbility = new SagaAbility(this);
// I, II Each opponent sacrifices a creature unless they discard a card.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II,
new SacrificeOpponentsUnlessPayEffect(
new DiscardCardCost(), StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT
)
);
// III Exile this Saga, then return it to the battlefield transformed under your control.
this.addAbility(new TransformAbility());
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect()
);
this.addAbility(sagaAbility);
}
private TheLongReachOfNight(final TheLongReachOfNight card) {
super(card);
}
@Override
public TheLongReachOfNight copy() {
return new TheLongReachOfNight(this);
}
}

View file

@ -31,6 +31,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("Akki War Paint", 132, Rarity.COMMON, mage.cards.a.AkkiWarPaint.class));
cards.add(new SetCardInfo("Ancestral Katana", 1, Rarity.COMMON, mage.cards.a.AncestralKatana.class));
cards.add(new SetCardInfo("Anchor to Reality", 45, Rarity.UNCOMMON, mage.cards.a.AnchorToReality.class));
cards.add(new SetCardInfo("Animus of Night's Reach", 109, Rarity.UNCOMMON, mage.cards.a.AnimusOfNightsReach.class));
cards.add(new SetCardInfo("Ao, the Dawn Sky", 2, Rarity.MYTHIC, mage.cards.a.AoTheDawnSky.class));
cards.add(new SetCardInfo("Architect of Restoration", 34, Rarity.RARE, mage.cards.a.ArchitectOfRestoration.class));
cards.add(new SetCardInfo("Armguard Familiar", 46, Rarity.COMMON, mage.cards.a.ArmguardFamiliar.class));
@ -159,6 +160,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("Teachings of the Kirin", 212, Rarity.RARE, mage.cards.t.TeachingsOfTheKirin.class));
cards.add(new SetCardInfo("Tempered in Solitude", 165, Rarity.UNCOMMON, mage.cards.t.TemperedInSolitude.class));
cards.add(new SetCardInfo("The Fall of Lord Konda", 12, Rarity.UNCOMMON, mage.cards.t.TheFallOfLordKonda.class));
cards.add(new SetCardInfo("The Long Reach of Night", 109, Rarity.UNCOMMON, mage.cards.t.TheLongReachOfNight.class));
cards.add(new SetCardInfo("The Modern Age", 66, Rarity.COMMON, mage.cards.t.TheModernAge.class));
cards.add(new SetCardInfo("The Restoration of Eiganjo", 34, Rarity.RARE, mage.cards.t.TheRestorationOfEiganjo.class));
cards.add(new SetCardInfo("The Shattered States Era", 162, Rarity.COMMON, mage.cards.t.TheShatteredStatesEra.class));

View file

@ -8,7 +8,7 @@ import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
import java.util.Objects;
/**
* @author North
@ -25,23 +25,22 @@ public class CardsInAllGraveyardsCount implements DynamicValue {
this.filter = filter;
}
public CardsInAllGraveyardsCount(final CardsInAllGraveyardsCount dynamicValue) {
private CardsInAllGraveyardsCount(final CardsInAllGraveyardsCount dynamicValue) {
this.filter = dynamicValue.filter.copy();
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int amount = 0;
Player controller = game.getPlayer(sourceAbility.getControllerId());
if (controller != null) {
for (UUID playerUUID : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerUUID);
if (player != null) {
amount += player.getGraveyard().count(filter, sourceAbility.getSourceId(), sourceAbility.getControllerId(), game);
}
}
}
return amount;
return game.getState()
.getPlayersInRange(sourceAbility.getControllerId(), game)
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(Player::getGraveyard)
.mapToInt(graveyard -> graveyard.count(
filter, sourceAbility.getSourceId(),
sourceAbility.getControllerId(), game
)).sum();
}
@Override