mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 13:19:18 -08:00
Number of card types in graveyards - added card hint for cards like Tarmogoyf
This commit is contained in:
parent
4a960995f7
commit
25e4930bd5
94 changed files with 245 additions and 306 deletions
|
|
@ -3,14 +3,16 @@ package mage.abilities.dynamicvalue.common;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.abilities.hint.ValueHint;
|
||||
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.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
|
@ -20,16 +22,18 @@ public enum CardTypesInGraveyardCount implements DynamicValue {
|
|||
YOU("your graveyard"),
|
||||
ALL("all graveyards"),
|
||||
OPPONENTS("your opponents' graveyards");
|
||||
|
||||
private final String message;
|
||||
private final CardTypesInGraveyardHint hint;
|
||||
|
||||
CardTypesInGraveyardCount(String message) {
|
||||
this.message = "the number of card types among cards in " + message;
|
||||
this.hint = new CardTypesInGraveyardHint(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculate(Game game, Ability sourceAbility, Effect effect) {
|
||||
return getStream(game, sourceAbility)
|
||||
.filter(card -> !card.isCopy() && !(card instanceof PermanentToken))
|
||||
return getGraveyardCards(game, sourceAbility)
|
||||
.map(card -> card.getCardType(game))
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
|
|
@ -52,16 +56,16 @@ public enum CardTypesInGraveyardCount implements DynamicValue {
|
|||
return message;
|
||||
}
|
||||
|
||||
private final Stream<Card> getStream(Game game, Ability ability) {
|
||||
public Hint getHint() {
|
||||
return hint;
|
||||
}
|
||||
|
||||
public Stream<Card> getGraveyardCards(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();
|
||||
playerIds = Collections.singletonList(ability.getControllerId());
|
||||
break;
|
||||
case OPPONENTS:
|
||||
playerIds = game.getOpponents(ability.getControllerId());
|
||||
break;
|
||||
|
|
@ -69,13 +73,47 @@ public enum CardTypesInGraveyardCount implements DynamicValue {
|
|||
playerIds = game.getState().getPlayersInRange(ability.getControllerId(), game);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
throw new IllegalArgumentException("Wrong code usage: miss implementation for " + this);
|
||||
}
|
||||
return playerIds.stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getGraveyard)
|
||||
.map(graveyard -> graveyard.getCards(game))
|
||||
.flatMap(Collection::stream);
|
||||
.flatMap(Collection::stream)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(card -> !card.isCopy() && !(card instanceof PermanentToken));
|
||||
}
|
||||
}
|
||||
|
||||
class CardTypesInGraveyardHint implements Hint {
|
||||
|
||||
CardTypesInGraveyardCount value;
|
||||
|
||||
CardTypesInGraveyardHint(CardTypesInGraveyardCount value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private CardTypesInGraveyardHint(final CardTypesInGraveyardHint hint) {
|
||||
this.value = hint.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
Stream<Card> stream = this.value.getGraveyardCards(game, ability);
|
||||
List<String> types = stream
|
||||
.map(card -> card.getCardType(game))
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.map(CardType::toString)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
return "Card types in " + this.value.getMessage() + ": " + types.size()
|
||||
+ (types.size() > 0 ? " (" + String.join(", ", types) + ')' : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardTypesInGraveyardHint copy() {
|
||||
return new CardTypesInGraveyardHint(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ public class ConditionTrueHint implements Hint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
public ConditionTrueHint copy() {
|
||||
return new ConditionTrueHint(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class StaticHint implements Hint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
public StaticHint copy() {
|
||||
return new StaticHint(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
package mage.abilities.hint.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum CardTypesInGraveyardHint implements Hint {
|
||||
|
||||
YOU("your graveyard"),
|
||||
ALL("all graveyards"),
|
||||
OPPONENTS("your opponents' graveyards");
|
||||
private final String message;
|
||||
|
||||
CardTypesInGraveyardHint(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
Stream<Card> stream = getStream(game, ability);
|
||||
if (stream == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> types = stream
|
||||
.map(card -> card.getCardType(game))
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.map(CardType::toString)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
return "Card types in " + this.message + ": " + types.size()
|
||||
+ (types.size() > 0 ? " (" + String.join(", ", types) + ')' : "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
package mage.abilities.hint.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.CountersOnPermanentsCondition;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.counters.Counter;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.abilities.condition.common.CountersOnPermanentsCondition;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
/**
|
||||
* A hint which keeps track of how many counters of a specific type there are
|
||||
* among some type of permanents
|
||||
*
|
||||
*
|
||||
* @author alexander-novo
|
||||
*/
|
||||
public class CountersOnPermanentsHint implements Hint {
|
||||
|
|
@ -23,6 +23,10 @@ public class CountersOnPermanentsHint implements Hint {
|
|||
// Which counter type to count
|
||||
public final CounterType counterType;
|
||||
|
||||
public CountersOnPermanentsHint(CountersOnPermanentsCondition condition) {
|
||||
this(condition.filter, condition.counterType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filter Which permanents to consider counters on
|
||||
* @param counterType Which counter type to count
|
||||
|
|
@ -32,12 +36,9 @@ public class CountersOnPermanentsHint implements Hint {
|
|||
this.counterType = counterType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy parameters from a {@link CountersOnPermanentsCondition}
|
||||
*/
|
||||
public CountersOnPermanentsHint(CountersOnPermanentsCondition condition) {
|
||||
this.filter = condition.filter;
|
||||
this.counterType = condition.counterType;
|
||||
public CountersOnPermanentsHint(final CountersOnPermanentsHint hint) {
|
||||
this.filter = hint.filter.copy();
|
||||
this.counterType = hint.counterType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -56,7 +57,7 @@ public class CountersOnPermanentsHint implements Hint {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
return this;
|
||||
public CountersOnPermanentsHint copy() {
|
||||
return new CountersOnPermanentsHint(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ import mage.constants.Zone;
|
|||
*/
|
||||
public final class ConsumingBlobOozeToken extends TokenImpl {
|
||||
|
||||
private static final DynamicValue powerValue = CardTypesInGraveyardCount.YOU;
|
||||
|
||||
public ConsumingBlobOozeToken() {
|
||||
super("Ooze Token", "green Ooze creature token with \"This creature's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.\"");
|
||||
cardType.add(CardType.CREATURE);
|
||||
|
|
@ -26,7 +24,9 @@ public final class ConsumingBlobOozeToken extends TokenImpl {
|
|||
toughness = new MageInt(1);
|
||||
|
||||
// This creature's power is equal to the number of card types among cards in your graveyard and its toughness is equal to that number plus 1.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(powerValue)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL,
|
||||
new SetBasePowerToughnessPlusOneSourceEffect(CardTypesInGraveyardCount.YOU)
|
||||
).addHint(CardTypesInGraveyardCount.YOU.getHint()));
|
||||
}
|
||||
|
||||
private ConsumingBlobOozeToken(final ConsumingBlobOozeToken token) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ public final class TarmogoyfToken extends TokenImpl {
|
|||
toughness = new MageInt(1);
|
||||
|
||||
// Tarmogoyf's power is equal to the number of card types among cards in all graveyards and its toughness is equal to that number plus 1.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessPlusOneSourceEffect(CardTypesInGraveyardCount.ALL)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL,
|
||||
new SetBasePowerToughnessPlusOneSourceEffect(CardTypesInGraveyardCount.ALL)
|
||||
).addHint(CardTypesInGraveyardCount.ALL.getHint()));
|
||||
}
|
||||
|
||||
private TarmogoyfToken(final TarmogoyfToken token) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue