consolidated card type in graveyard count to a single class

This commit is contained in:
Evan Kranzler 2021-06-11 08:35:38 -04:00
parent f09e6cc9ac
commit 0acc2d4f36
6 changed files with 86 additions and 141 deletions

View file

@ -3,9 +3,9 @@ package mage.cards.a;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.hint.common.CardTypesInGraveyardHint;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -14,6 +14,7 @@ import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
@ -23,15 +24,10 @@ import java.util.UUID;
/**
* @author jmharmon
*/
public final class AltarOfTheGoyf extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("Lhurgoyf creatures");
static {
filter.add(CardType.CREATURE.getPredicate());
filter.add(SubType.LHURGOYF.getPredicate());
}
private static final FilterPermanent filter
= new FilterCreaturePermanent(SubType.LHURGOYF, "Lhurgoyf creatures");
public AltarOfTheGoyf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.ARTIFACT}, "{5}");
@ -39,10 +35,12 @@ public final class AltarOfTheGoyf extends CardImpl {
this.subtype.add(SubType.LHURGOYF);
// Whenever a creature you control attacks alone, it gets +X/+X until end of turn, where X is the number of card types among cards in all graveyard.
this.addAbility(new AltarOfTheGoyfAbility().addHint(CardTypesInGraveyardCount.ALL));
this.addAbility(new AltarOfTheGoyfAbility());
// Lhurgoyf creatures you control have trample.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter)));
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.WhileOnBattlefield, filter
)));
}
private AltarOfTheGoyf(final AltarOfTheGoyf card) {
@ -55,11 +53,13 @@ public final class AltarOfTheGoyf extends CardImpl {
}
}
class AltarOfTheGoyfAbility extends TriggeredAbilityImpl{
class AltarOfTheGoyfAbility extends TriggeredAbilityImpl {
public AltarOfTheGoyfAbility() {
super(Zone.BATTLEFIELD, new BoostTargetEffect(
CardTypesInGraveyardCount.instance, CardTypesInGraveyardCount.instance, Duration.EndOfTurn, true), false);
CardTypesInGraveyardCount.ALL, CardTypesInGraveyardCount.ALL, Duration.EndOfTurn, true
), false);
this.addHint(CardTypesInGraveyardHint.ALL);
}
public AltarOfTheGoyfAbility(final AltarOfTheGoyfAbility ability) {
@ -78,13 +78,9 @@ class AltarOfTheGoyfAbility extends TriggeredAbilityImpl{
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.isActivePlayer(this.controllerId)) {
if (game.getCombat().attacksAlone()) {
this.getEffects().setTargetPointer(new
FixedTarget(game.getCombat().getAttackers().get(0), game)); {
}
return true;
}
if (game.isActivePlayer(this.controllerId) && game.getCombat().attacksAlone()) {
this.getEffects().setTargetPointer(new FixedTarget(game.getCombat().getAttackers().get(0), game));
return true;
}
return false;
}
@ -93,6 +89,6 @@ class AltarOfTheGoyfAbility extends TriggeredAbilityImpl{
public String getRule() {
return "Whenever a creature you control attacks alone, " +
"it gets +X/+X until end of turn, " +
"where X is the number of card types among cards in all graveyard.";
"where X is the number of card types among cards in all graveyards.";
}
}

View file

@ -1,20 +1,13 @@
package mage.cards.l;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.hint.common.CardTypesInGraveyardHint;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
import mage.players.Player;
import java.util.Collection;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
@ -25,7 +18,7 @@ public final class LucidDreams extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}");
// Draw X cards, where X is the number of card types among cards in your graveyard.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(LucidDreamsValue.instance)
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(CardTypesInGraveyardCount.YOU)
.setText("draw X cards, where X is the number of card types among cards in your graveyard"));
this.getSpellAbility().addHint(CardTypesInGraveyardHint.YOU);
}
@ -39,29 +32,3 @@ public final class LucidDreams extends CardImpl {
return new LucidDreams(this);
}
}
enum LucidDreamsValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player player = game.getPlayer(sourceAbility.getControllerId());
return player == null ? 0 : player.getGraveyard()
.getCards(game)
.stream()
.map(MageObject::getCardType)
.flatMap(Collection::stream)
.collect(Collectors.toSet())
.size();
}
@Override
public LucidDreamsValue copy() {
return instance;
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -1,11 +1,11 @@
package mage.cards.n;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.AdditiveDynamicValue;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continuous.SetPowerSourceEffect;
import mage.abilities.hint.common.CardTypesInGraveyardHint;
import mage.abilities.keyword.DeathtouchAbility;
@ -17,19 +17,18 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.Collection;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class NighthawkScavenger extends CardImpl {
private static final DynamicValue xValue = new AdditiveDynamicValue(
CardTypesInGraveyardCount.OPPONENTS, StaticValue.get(1)
);
public NighthawkScavenger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
@ -49,10 +48,9 @@ public final class NighthawkScavenger extends CardImpl {
// Nighthawk Scavenger's power is equal to 1 plus the number of card types among cards in your opponents' graveyards.
this.addAbility(new SimpleStaticAbility(
Zone.ALL,
new SetPowerSourceEffect(
NighthawkScavengerValue.instance, Duration.EndOfGame
).setText("{this}'s power is equal to 1 plus the number of card types among cards in your opponents' graveyards.")
Zone.ALL, new SetPowerSourceEffect(xValue, Duration.EndOfGame)
.setText("{this}'s power is equal to 1 plus the number of " +
"card types among cards in your opponents' graveyards.")
).addHint(CardTypesInGraveyardHint.OPPONENTS));
}
@ -65,33 +63,3 @@ public final class NighthawkScavenger extends CardImpl {
return new NighthawkScavenger(this);
}
}
enum NighthawkScavengerValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return 1 + game.getOpponents(sourceAbility.getControllerId())
.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(Player::getGraveyard)
.map(g -> g.getCards(game))
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.map(MageObject::getCardType)
.flatMap(Collection::stream)
.collect(Collectors.toSet())
.size();
}
@Override
public NighthawkScavengerValue copy() {
return instance;
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -4,17 +4,14 @@ import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.CardTypesInGraveyardCount;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.hint.common.CardTypesInGraveyardHint;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import java.util.EnumSet;
import java.util.Set;
import java.util.UUID;
/**
@ -61,27 +58,13 @@ class TarmogoyfEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
MageObject target = game.getObject(source.getSourceId());
if (target != null) {
Set<CardType> foundCardTypes = EnumSet.noneOf(CardType.class);
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null) {
for (Card card : player.getGraveyard().getCards(game)) {
foundCardTypes.addAll(card.getCardType());
}
}
}
int number = foundCardTypes.size();
target.getPower().setValue(number);
target.getToughness().setValue(number + 1);
return true;
}
MageObject target = source.getSourceObject(game);
if (target == null) {
return false;
}
return false;
int number = CardTypesInGraveyardCount.ALL.calculate(game, source, this);
target.getPower().setValue(number);
target.getToughness().setValue(number + 1);
return true;
}
}

View file

@ -14,7 +14,7 @@ public enum DeliriumCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
return CardTypesInGraveyardCount.instance.calculate(game, source, null) >= 4;
return CardTypesInGraveyardCount.YOU.calculate(game, source, null) >= 4;
}
@Override

View file

@ -1,42 +1,46 @@
package mage.abilities.dynamicvalue.common;
import java.util.HashSet;
import java.util.Set;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.cards.Card;
import mage.constants.CardType;
import mage.game.Game;
import mage.game.permanent.PermanentToken;
import mage.players.Player;
import java.util.Collection;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;
/**
* @author JayDi85
*/
public enum CardTypesInGraveyardCount implements DynamicValue {
YOU("your graveyard"),
ALL("all graveyards"),
OPPONENTS("your opponents' graveyards");
private final String message;
instance;
CardTypesInGraveyardCount(String message) {
this.message = message;
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player controller = game.getPlayer(sourceAbility.getControllerId());
if (controller != null) {
Set<CardType> foundCardTypes = new HashSet<>();
for (Card card : controller.getGraveyard().getCards(game)) {
// 4/8/2016 In some rare cases, you can have a token or a copy of a spell in your graveyard at the moment that an objects delirium ability counts the card types among cards in your graveyard, before that token or copy ceases to exist. Because tokens and copies of spells are not cards, even if they are copies of cards, their types will never be counted.
if (!card.isCopy() && !(card instanceof PermanentToken)) {
foundCardTypes.addAll(card.getCardType());
}
}
return foundCardTypes.size();
}
return 0;
return getStream(game, sourceAbility)
.filter(card -> !card.isCopy() && !(card instanceof PermanentToken))
.map(MageObject::getCardType)
.flatMap(Collection::stream)
.distinct()
.mapToInt(x -> 1)
.sum();
}
@Override
public CardTypesInGraveyardCount copy() {
return instance;
return this;
}
@Override
@ -46,6 +50,33 @@ public enum CardTypesInGraveyardCount implements DynamicValue {
@Override
public String getMessage() {
return "the number of opponents you attacked this turn";
return "the number of card types in " + message;
}
private final Stream<Card> getStream(Game game, Ability ability) {
Collection<UUID> playerIds;
switch (this) {
case YOU:
Player player = game.getPlayer(ability.getControllerId());
return player == null
? null : player
.getGraveyard()
.getCards(game)
.stream();
case OPPONENTS:
playerIds = game.getOpponents(ability.getControllerId());
break;
case ALL:
playerIds = game.getState().getPlayersInRange(ability.getControllerId(), game);
break;
default:
return null;
}
return playerIds.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(Player::getGraveyard)
.map(graveyard -> graveyard.getCards(game))
.flatMap(Collection::stream);
}
}