refactor effects which care about the amount of colors among controlled permanents

This commit is contained in:
theelk801 2025-12-19 16:30:18 -05:00
parent 2a3b4aff7a
commit 0cf13c9a7a
14 changed files with 252 additions and 499 deletions

View file

@ -1479,7 +1479,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
/**
* Hardcoding here versus using Objects.hash in order to increase performance since this is
* called thousands of times by {@link mage.abilities.mana.ManaOptions#addManaWithCost(List, Game)}
* called thousands of times by {@link mage.abilities.mana.ManaOptions#addManaWithCost(List, mage.game.Game)}
*
* @return
*/
@ -1517,4 +1517,24 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
}
return value;
}
public static Mana fromColor(ObjectColor color) {
Mana mana = new Mana();
if (color.isWhite()) {
mana.increaseWhite();
}
if (color.isBlue()) {
mana.increaseBlue();
}
if (color.isBlack()) {
mana.increaseBlack();
}
if (color.isRed()) {
mana.increaseRed();
}
if (color.isGreen()) {
mana.increaseGreen();
}
return mana;
}
}

View file

@ -0,0 +1,114 @@
package mage.abilities.dynamicvalue.common;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.hint.Hint;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.mageobject.MonocoloredPredicate;
import mage.game.Game;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public enum ColorsAmongControlledPermanentsCount implements DynamicValue {
ALL_PERMANENTS(StaticFilters.FILTER_CONTROLLED_PERMANENTS),
MONOCOLORED_PERMANENTS(PermanentFilters.MONOCOLORED_PERMANENTS),
OTHER_LEGENDARY(PermanentFilters.OTHER_LEGENDARY),
ALLIES(new FilterControlledPermanent(SubType.ALLY, "Allies you control"));
private final FilterPermanent filter;
private final Hint hint;
ColorsAmongControlledPermanentsCount(FilterPermanent filter) {
this.filter = filter;
this.hint = new ColorsAmongControlledPermanentsHint(this);
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return getAllControlledColors(game, sourceAbility).getColorCount();
}
@Override
public ColorsAmongControlledPermanentsCount copy() {
return this;
}
@Override
public String getMessage() {
return "for each color among " + filter.getMessage();
}
@Override
public String toString() {
return "1";
}
public Hint getHint() {
return hint;
}
public FilterPermanent getFilter() {
return filter;
}
public ObjectColor getAllControlledColors(Game game, Ability source) {
return game
.getBattlefield()
.getActivePermanents(filter, source.getControllerId(), source, game)
.stream()
.map(permanent -> permanent.getColor(game))
.reduce(new ObjectColor(), (c1, c2) -> c1.union(c2));
}
}
class ColorsAmongControlledPermanentsHint implements Hint {
private final ColorsAmongControlledPermanentsCount count;
ColorsAmongControlledPermanentsHint(ColorsAmongControlledPermanentsCount count) {
this.count = count;
}
@Override
public String getText(Game game, Ability ability) {
List<String> colors = this
.count
.getAllControlledColors(game, ability)
.getColors()
.stream()
.map(ObjectColor::getDescription)
.collect(Collectors.toList());
return "Colors among " + this.count.getFilter().getMessage() + ": " + colors.size()
+ (colors.size() > 0 ? " (" + String.join(", ", colors) + ')' : "");
}
@Override
public Hint copy() {
return this;
}
}
class PermanentFilters {
static final FilterPermanent MONOCOLORED_PERMANENTS = new FilterControlledPermanent("monocolored permanents you control");
static {
MONOCOLORED_PERMANENTS.add(MonocoloredPredicate.instance);
}
static final FilterPermanent OTHER_LEGENDARY = new FilterControlledPermanent("other legendary permanents you control");
static {
OTHER_LEGENDARY.add(AnotherPredicate.instance);
OTHER_LEGENDARY.add(SuperType.LEGENDARY.getPredicate());
}
}

View file

@ -1,57 +0,0 @@
package mage.abilities.effects.common;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
public class DrawCardForEachColorAmongControlledPermanentsEffect extends OneShotEffect {
public DrawCardForEachColorAmongControlledPermanentsEffect() {
super(Outcome.DrawCard);
this.staticText = "Draw a card for each color among permanents you control";
}
protected DrawCardForEachColorAmongControlledPermanentsEffect(final DrawCardForEachColorAmongControlledPermanentsEffect effect) {
super(effect);
}
@Override
public DrawCardForEachColorAmongControlledPermanentsEffect copy() {
return new DrawCardForEachColorAmongControlledPermanentsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Set<ObjectColor> colors = new HashSet<>();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(controller.getId())) {
if (permanent.getColor(game).isBlack()) {
colors.add(ObjectColor.BLACK);
}
if (permanent.getColor(game).isBlue()) {
colors.add(ObjectColor.BLUE);
}
if (permanent.getColor(game).isRed()) {
colors.add(ObjectColor.RED);
}
if (permanent.getColor(game).isGreen()) {
colors.add(ObjectColor.GREEN);
}
if (permanent.getColor(game).isWhite()) {
colors.add(ObjectColor.WHITE);
}
}
controller.drawCards(colors.size(), source, game);
return true;
}
return false;
}
}

View file

@ -0,0 +1,54 @@
package mage.abilities.mana;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.common.ColorsAmongControlledPermanentsCount;
import mage.abilities.effects.mana.ManaEffect;
import mage.constants.Zone;
import mage.game.Game;
/**
* @author TheElk801
*/
public class AddEachControlledColorManaAbility extends ActivatedManaAbilityImpl {
public AddEachControlledColorManaAbility() {
super(Zone.BATTLEFIELD, new AddEachControlledColorManaEffect(), new TapSourceCost());
this.addHint(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getHint());
}
private AddEachControlledColorManaAbility(final AddEachControlledColorManaAbility ability) {
super(ability);
}
@Override
public AddEachControlledColorManaAbility copy() {
return new AddEachControlledColorManaAbility(this);
}
}
class AddEachControlledColorManaEffect extends ManaEffect {
AddEachControlledColorManaEffect() {
super();
staticText = "for each color among permanents you control, add one mana of that color";
}
private AddEachControlledColorManaEffect(final AddEachControlledColorManaEffect effect) {
super(effect);
}
@Override
public AddEachControlledColorManaEffect copy() {
return new AddEachControlledColorManaEffect(this);
}
@Override
public Mana produceMana(Game game, Ability source) {
if (game == null) {
return new Mana();
}
return Mana.fromColor(ColorsAmongControlledPermanentsCount.ALL_PERMANENTS.getAllControlledColors(game, source));
}
}