Merge pull request #13373 from Jmlundeen/implement-ketramose

[DFT] Implement Ketramose, the New Dawn
This commit is contained in:
Oleg Agafonov 2025-03-11 14:02:43 +03:00 committed by GitHub
commit b55ad3cdc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 262 additions and 0 deletions

View file

@ -0,0 +1,65 @@
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.CardsInExileCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.constants.ComparisonType;
import mage.game.Game;
import mage.util.CardUtil;
/**
* Cards in exile condition
*
* @author Jmlundeen
*/
public class CardsInExileCondition implements Condition
{
private final ComparisonType type;
private final int count;
private final DynamicValue cardsInExileCount;
public CardsInExileCondition(ComparisonType type, int count)
{
this(type, count, CardsInExileCount.ALL);
}
public CardsInExileCondition(ComparisonType type, int count, DynamicValue cardsInExileCount)
{
this.type = type;
this.count = count;
this.cardsInExileCount = cardsInExileCount;
}
@Override
public boolean apply(Game game, Ability source)
{
int exileCards = cardsInExileCount.calculate(game, source, null);
return ComparisonType.compare(exileCards, type, count);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("there are ");
String countString = CardUtil.numberToText(count);
switch (type) {
case MORE_THAN:
sb.append("more than ").append(countString).append(" ");
break;
case FEWER_THAN:
sb.append("fewer than ").append(countString).append(" ");
break;
case OR_LESS:
sb.append(countString).append(" or less ");
break;
case OR_GREATER:
sb.append(countString).append(" or more ");
break;
default:
throw new IllegalArgumentException("comparison rules for " + type + " missing");
}
sb.append("cards in exile");
return sb.toString();
}
}

View file

@ -0,0 +1,81 @@
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.game.Game;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;
/**
* @author Jmlundeen
*/
public enum CardsInExileCount implements DynamicValue {
YOU("you"),
ALL("all players"),
OPPONENTS("your opponents'");
private final String message;
private final ValueHint hint;
CardsInExileCount(String message) {
this.message = "The number of cards owned by " + message + " in exile";
this.hint = new ValueHint(this.message, this);
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return getExileCards(game, sourceAbility)
.mapToInt(x -> 1)
.sum();
}
@Override
public CardsInExileCount copy() {
return this;
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return message;
}
public Hint getHint() {
return hint;
}
public Stream<Card> getExileCards(Game game, Ability ability) {
Collection<UUID> playerIds;
switch (this) {
case YOU:
playerIds = Collections.singletonList(ability.getControllerId());
break;
case OPPONENTS:
playerIds = game.getOpponents(ability.getControllerId());
break;
case ALL:
playerIds = game.getState().getPlayersInRange(ability.getControllerId(), game);
break;
default:
throw new IllegalArgumentException("Wrong code usage: miss implementation for " + this);
}
return playerIds.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(player -> game.getExile().getAllCards(game, player.getId()))
.flatMap(Collection::stream)
.filter(Objects::nonNull);
}
}