refactor and test 'greatest [quality] among [permanent filter]' (#13666)

This commit is contained in:
Susucre 2025-05-25 18:58:53 +02:00 committed by GitHub
parent 0b6a2b2546
commit 43c45238d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 1616 additions and 1638 deletions

View file

@ -0,0 +1,117 @@
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.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.function.ToIntFunction;
/**
* Dynamic value for "greatest [quality] among [permanent filter]"
* For the most common ones, add a static entry instead of using new GreatestAmongPermanentsValue(...).
*
* @author Susucr
*/
public class GreatestAmongPermanentsValue implements DynamicValue {
public static final GreatestAmongPermanentsValue POWER_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.Power, StaticFilters.FILTER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue POWER_OTHER_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.Power, StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue TOUGHNESS_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.Toughness, StaticFilters.FILTER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue TOUGHNESS_OTHER_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.Toughness, StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue POWER_OR_TOUGHNESS_OTHER_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.PowerOrToughness, StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue MANAVALUE_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue MANAVALUE_OTHER_CONTROLLED_CREATURES
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES);
public static final GreatestAmongPermanentsValue MANAVALUE_CONTROLLED_ARTIFACTS
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACTS);
public static final GreatestAmongPermanentsValue MANAVALUE_OTHER_CONTROLLED_ARTIFACTS
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_OTHER_CONTROLLED_ARTIFACTS);
public static final GreatestAmongPermanentsValue MANAVALUE_CONTROLLED_PERMANENTS
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_CONTROLLED_PERMANENTS);
public static final GreatestAmongPermanentsValue MANAVALUE_OTHER_CONTROLLED_PERMANENTS
= new GreatestAmongPermanentsValue(Quality.ManaValue, StaticFilters.FILTER_OTHER_CONTROLLED_PERMANENTS);
public enum Quality {
Power("power", (Permanent permanent) -> {
return permanent.getPower().getValue();
}),
Toughness("toughness", (Permanent permanent) -> {
return permanent.getToughness().getValue();
}),
ManaValue("mana value", Permanent::getManaValue),
PowerOrToughness("power and/or toughness",
(Permanent permanent) -> {
int power = permanent.getPower().getValue();
int toughness = permanent.getToughness().getValue();
return Math.max(power, toughness);
}
);
final String text;
final ToIntFunction<Permanent> mapToQuality;
Quality(String text, ToIntFunction<Permanent> mapToQuality) {
this.text = text;
this.mapToQuality = mapToQuality;
}
}
private final Quality quality;
private final FilterPermanent filter;
public GreatestAmongPermanentsValue(Quality quality, FilterPermanent filter) {
this.filter = filter;
this.quality = quality;
}
private GreatestAmongPermanentsValue(final GreatestAmongPermanentsValue value) {
super();
this.filter = value.filter;
this.quality = value.quality;
}
@Override
public GreatestAmongPermanentsValue copy() {
return new GreatestAmongPermanentsValue(this);
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game
.getBattlefield()
.getActivePermanents(
this.filter, sourceAbility.getControllerId(), sourceAbility, game
)
.stream()
.mapToInt(this.quality.mapToQuality)
.max()
.orElse(0);
}
@Override
public String getMessage() {
return "the greatest " + quality.text + " among " + this.filter.getMessage();
}
@Override
public String toString() {
return "X";
}
public Hint getHint() {
return new ValueHint("Greatest " + quality.text + " among " + filter.getMessage(), this);
}
}

View file

@ -1,53 +0,0 @@
package mage.abilities.dynamicvalue.common;
import mage.MageInt;
import mage.MageObject;
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.filter.StaticFilters;
import mage.game.Game;
/**
* @author Styxo
*/
public enum GreatestPowerAmongControlledCreaturesValue implements DynamicValue {
instance;
private static final Hint hint = new ValueHint("Greatest power among creatures you control", instance);
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game
.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
sourceAbility.getControllerId(), game
).stream()
.map(MageObject::getPower)
.mapToInt(MageInt::getValue)
.max()
.orElse(0);
}
@Override
public GreatestPowerAmongControlledCreaturesValue copy() {
return GreatestPowerAmongControlledCreaturesValue.instance;
}
@Override
public String getMessage() {
return "the greatest power among creatures you control";
}
@Override
public String toString() {
return "X";
}
public static Hint getHint() {
return hint;
}
}

View file

@ -1,58 +0,0 @@
package mage.abilities.dynamicvalue.common;
import mage.MageInt;
import mage.MageObject;
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.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
/**
* @author TheElk801
*/
public enum GreatestToughnessAmongControlledCreaturesValue implements DynamicValue {
ALL(StaticFilters.FILTER_CONTROLLED_CREATURES),
OTHER(StaticFilters.FILTER_OTHER_CONTROLLED_CREATURES);
private final FilterPermanent filter;
private final Hint hint;
GreatestToughnessAmongControlledCreaturesValue(FilterPermanent filter) {
this.filter = filter;
this.hint = new ValueHint("The greatest toughness among " + filter.getMessage(), this);
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return game
.getBattlefield()
.getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility, game)
.stream()
.map(MageObject::getToughness)
.mapToInt(MageInt::getValue)
.max()
.orElse(0);
}
@Override
public GreatestToughnessAmongControlledCreaturesValue copy() {
return this;
}
@Override
public String getMessage() {
return "the greatest toughness among " + filter.getMessage();
}
@Override
public String toString() {
return "X";
}
public Hint getHint() {
return hint;
}
}

View file

@ -1,61 +0,0 @@
package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author LevelX2
*/
public class HighestCMCOfPermanentValue implements DynamicValue {
private final FilterPermanent filter;
private final boolean onlyIfCanBeSacrificed;
public HighestCMCOfPermanentValue(FilterPermanent filter, boolean onlyIfCanBeSacrificed) {
super();
this.filter = filter;
this.onlyIfCanBeSacrificed = onlyIfCanBeSacrificed;
}
protected HighestCMCOfPermanentValue(final HighestCMCOfPermanentValue dynamicValue) {
this.filter = dynamicValue.filter;
this.onlyIfCanBeSacrificed = dynamicValue.onlyIfCanBeSacrificed;
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int value = 0;
Player controller = game.getPlayer(sourceAbility.getControllerId());
if (controller != null) {
for (Permanent permanent : game.getBattlefield()
.getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility, game)) {
if ((!onlyIfCanBeSacrificed || controller.canPaySacrificeCost(permanent, sourceAbility, sourceAbility.getControllerId(), game))
&& permanent.getManaValue() > value) {
value = permanent.getManaValue();
}
}
}
return value;
}
@Override
public HighestCMCOfPermanentValue copy() {
return new HighestCMCOfPermanentValue(this);
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return filter.getMessage();
}
}

View file

@ -1,60 +0,0 @@
package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
* @author nigelzor
*/
public class HighestManaValueCount implements DynamicValue {
private final FilterPermanent filter;
public HighestManaValueCount() {
this(StaticFilters.FILTER_PERMANENTS);
}
public HighestManaValueCount(FilterPermanent filter) {
this.filter = filter;
}
protected HighestManaValueCount(final HighestManaValueCount dynamicValue) {
super();
this.filter = dynamicValue.filter.copy();
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player controller = game.getPlayer(sourceAbility.getControllerId());
if (controller == null) {
return 0;
}
int highCMC = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
int cmc = permanent.getManaValue();
highCMC = Math.max(highCMC, cmc);
}
return highCMC;
}
@Override
public HighestManaValueCount copy() {
return new HighestManaValueCount(this);
}
@Override
public String getMessage() {
return "the highest mana value among " + filter.getMessage() + " you control";
}
@Override
public String toString() {
return "X";
}
}

View file

@ -643,6 +643,20 @@ public final class StaticFilters {
FILTER_OTHER_CONTROLLED_CREATURES.setLockedFilter(true);
}
public static final FilterControlledPermanent FILTER_OTHER_CONTROLLED_PERMANENTS = new FilterControlledPermanent("other permanents you control");
static {
FILTER_OTHER_CONTROLLED_PERMANENTS.add(AnotherPredicate.instance);
FILTER_OTHER_CONTROLLED_PERMANENTS.setLockedFilter(true);
}
public static final FilterControlledArtifactPermanent FILTER_OTHER_CONTROLLED_ARTIFACTS = new FilterControlledArtifactPermanent("other artifacts you control");
static {
FILTER_OTHER_CONTROLLED_ARTIFACTS.add(AnotherPredicate.instance);
FILTER_OTHER_CONTROLLED_ARTIFACTS.setLockedFilter(true);
}
public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_A_CREATURE = new FilterControlledCreaturePermanent("a creature you control");
static {

View file

@ -0,0 +1,29 @@
package mage.filter.predicate.permanent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.Optional;
/**
* @author Susucr
*/
public enum AttachedToSourcePredicate implements ObjectSourcePlayerPredicate<Permanent> {
instance;
@Override
public boolean apply(ObjectSourcePlayer<Permanent> input, Game game) {
return Optional.of(input.getObject())
.map(Permanent::getAttachedTo)
.filter(p -> p.equals(input.getSourceId()))
.isPresent();
}
@Override
public String toString() {
return "attached to {this}";
}
}