mirror of
https://github.com/correl/mage.git
synced 2024-12-26 11:09:27 +00:00
[NEO] Implemented The Long Reach of Night / Animus of Night's Reach
This commit is contained in:
parent
66148a92d1
commit
6c9fc1679d
4 changed files with 162 additions and 13 deletions
92
Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java
Normal file
92
Mage.Sets/src/mage/cards/a/AnimusOfNightsReach.java
Normal 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;
|
||||
}
|
||||
}
|
56
Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java
Normal file
56
Mage.Sets/src/mage/cards/t/TheLongReachOfNight.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue