ColorSet: turn Set into an Enum (#8757)

This commit is contained in:
Hans Mackowiak
2025-10-09 15:03:45 +02:00
committed by GitHub
parent 1962a8d28b
commit f8d883d91f
28 changed files with 138 additions and 254 deletions

View File

@@ -710,9 +710,9 @@ public class ComputerUtilMana {
if (hasConverge &&
(toPay == ManaCostShard.GENERIC || toPay == ManaCostShard.X)) {
final int unpaidColors = cost.getUnpaidColors() + cost.getColorsPaid() ^ ManaCostShard.COLORS_SUPERPOSITION;
for (final byte b : ColorSet.fromMask(unpaidColors)) {
for (final MagicColor.Color b : ColorSet.fromMask(unpaidColors)) {
// try and pay other colors for converge
final ManaCostShard shard = ManaCostShard.valueOf(b);
final ManaCostShard shard = ManaCostShard.valueOf(b.getColorMask());
saList = sourcesForShards.get(shard);
if (saList != null && !saList.isEmpty()) {
toPay = shard;
@@ -896,7 +896,8 @@ public class ComputerUtilMana {
if (hasConverge) {
// add extra colors for paying converge
final int unpaidColors = cost.getUnpaidColors() + cost.getColorsPaid() ^ ManaCostShard.COLORS_SUPERPOSITION;
for (final byte b : ColorSet.fromMask(unpaidColors)) {
for (final MagicColor.Color color : ColorSet.fromMask(unpaidColors)) {
final byte b = color.getColorMask();
final ManaCostShard shard = ManaCostShard.valueOf(b);
if (!sourcesForShards.containsKey(shard)) {
if (ai.getManaPool().canPayForShardWithColor(shard, b)) {
@@ -923,7 +924,7 @@ public class ComputerUtilMana {
ColorSet shared = ColorSet.fromMask(toPay.getColorMask()).getSharedColors(ColorSet.fromNames(m.getComboColors(saPayment).split(" ")));
// but other effects might still lead to a more permissive payment
if (!shared.isColorless()) {
m.setExpressChoice(ColorSet.fromMask(shared.iterator().next()));
m.setExpressChoice(shared.iterator().next().getShortName());
}
getComboManaChoice(ai, saPayment, sa, cost);
}
@@ -1098,7 +1099,7 @@ public class ComputerUtilMana {
// * pay hybrids
// * pay phyrexian, keep mana for colorless
// * pay generic
return cost.getShardToPayByPriority(shardsToPay, ColorSet.ALL_COLORS.getColor());
return cost.getShardToPayByPriority(shardsToPay, ColorSet.WUBRG.getColor());
}
private static void adjustManaCostToAvoidNegEffects(ManaCostBeingPaid cost, final Card card, Player ai) {

View File

@@ -1028,13 +1028,13 @@ public class PlayerControllerAi extends PlayerController {
if ((colors.getColor() & chosenColorMask) != 0) {
return chosenColorMask;
}
return Iterables.getFirst(colors, (byte)0);
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS).getColorMask();
}
@Override
public byte chooseColor(String message, SpellAbility sa, ColorSet colors) {
if (colors.countColors() < 2) {
return Iterables.getFirst(colors, MagicColor.WHITE);
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
}
// You may switch on sa.getApi() here and use sa.getParam("AILogic")
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
@@ -1047,7 +1047,7 @@ public class PlayerControllerAi extends PlayerController {
if ((colors.getColor() & chosenColorMask) != 0) {
return chosenColorMask;
}
return Iterables.getFirst(colors, MagicColor.WHITE);
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
}
@Override

View File

@@ -17,14 +17,12 @@
*/
package forge.card;
import com.google.common.collect.UnmodifiableIterator;
import forge.card.MagicColor.Color;
import forge.card.mana.ManaCost;
import forge.util.BinaryUtil;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -37,90 +35,56 @@ import java.util.stream.Stream;
*
*
*/
public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Serializable {
public enum ColorSet implements Iterable<Color>, Serializable {
C(Color.COLORLESS),
W(Color.WHITE),
U(Color.BLUE),
WU(Color.WHITE, Color.BLUE),
B(Color.BLACK),
WB(Color.WHITE, Color.BLACK),
UB(Color.BLUE, Color.BLACK),
WUB(Color.WHITE, Color.BLUE, Color.BLACK),
R(Color.RED),
RW(Color.RED, Color.WHITE),
UR(Color.BLUE, Color.RED),
URW(Color.BLUE, Color.RED, Color.WHITE),
BR(Color.BLACK, Color.RED),
RWB(Color.RED, Color.WHITE, Color.BLACK),
UBR(Color.BLUE, Color.BLACK, Color.RED),
WUBR(Color.WHITE, Color.BLUE, Color.BLACK, Color.RED),
G(Color.GREEN),
GW(Color.GREEN, Color.WHITE),
GU(Color.GREEN, Color.BLUE),
GWU(Color.GREEN, Color.WHITE, Color.BLUE),
BG(Color.BLACK, Color.GREEN),
WBG(Color.WHITE, Color.BLACK, Color.GREEN),
BGU(Color.BLACK, Color.GREEN, Color.BLUE),
GWUB(Color.GREEN, Color.WHITE, Color.BLUE, Color.BLACK),
RG(Color.RED, Color.GREEN),
RGW(Color.RED, Color.GREEN, Color.WHITE),
GUR(Color.GREEN, Color.BLUE, Color.RED),
RGWU(Color.RED, Color.GREEN, Color.WHITE, Color.BLUE),
BRG(Color.BLACK, Color.RED, Color.GREEN),
BRGW(Color.BLACK, Color.RED, Color.GREEN, Color.WHITE),
UBRG(Color.BLUE, Color.BLACK, Color.RED, Color.GREEN),
WUBRG(Color.WHITE, Color.BLUE, Color.BLACK, Color.RED, Color.GREEN)
;
private static final long serialVersionUID = 794691267379929080L;
// needs to be before other static
private static final ColorSet[] cache = new ColorSet[MagicColor.ALL_COLORS + 1];
static {
byte COLORLESS = MagicColor.COLORLESS;
byte WHITE = MagicColor.WHITE;
byte BLUE = MagicColor.BLUE;
byte BLACK = MagicColor.BLACK;
byte RED = MagicColor.RED;
byte GREEN = MagicColor.GREEN;
Color C = Color.COLORLESS;
Color W = Color.WHITE;
Color U = Color.BLUE;
Color B = Color.BLACK;
Color R = Color.RED;
Color G = Color.GREEN;
//colorless
cache[COLORLESS] = new ColorSet(C);
//mono-color
cache[WHITE] = new ColorSet(W);
cache[BLUE] = new ColorSet(U);
cache[BLACK] = new ColorSet(B);
cache[RED] = new ColorSet(R);
cache[GREEN] = new ColorSet(G);
//two-color
cache[WHITE | BLUE] = new ColorSet(W, U);
cache[WHITE | BLACK] = new ColorSet(W, B);
cache[BLUE | BLACK] = new ColorSet(U, B);
cache[BLUE | RED] = new ColorSet(U, R);
cache[BLACK | RED] = new ColorSet(B, R);
cache[BLACK | GREEN] = new ColorSet(B, G);
cache[RED | GREEN] = new ColorSet(R, G);
cache[RED | WHITE] = new ColorSet(R, W);
cache[GREEN | WHITE] = new ColorSet(G, W);
cache[GREEN | BLUE] = new ColorSet(G, U);
//three-color
cache[WHITE | BLUE | BLACK] = new ColorSet(W, U, B);
cache[WHITE | BLACK | GREEN] = new ColorSet(W, B, G);
cache[BLUE | BLACK | RED] = new ColorSet(U, B, R);
cache[BLUE | RED | WHITE] = new ColorSet(U, R, W);
cache[BLACK | RED | GREEN] = new ColorSet(B, R, G);
cache[BLACK | GREEN | BLUE] = new ColorSet(B, G, U);
cache[RED | GREEN | WHITE] = new ColorSet(R, G, W);
cache[RED | WHITE | BLACK] = new ColorSet(R, W, B);
cache[GREEN | WHITE | BLUE] = new ColorSet(G, W, U);
cache[GREEN | BLUE | RED] = new ColorSet(G, U, R);
//four-color
cache[WHITE | BLUE | BLACK | RED] = new ColorSet(W, U, B, R);
cache[BLUE | BLACK | RED | GREEN] = new ColorSet(U, B, R, G);
cache[BLACK | RED | GREEN | WHITE] = new ColorSet(B, R, G, W);
cache[RED | GREEN | WHITE | BLUE] = new ColorSet(R, G, W, U);
cache[GREEN | WHITE | BLUE | BLACK] = new ColorSet(G, W, U, B);
//five-color
cache[WHITE | BLUE | BLACK | RED | GREEN] = new ColorSet(W, U, B, R, G);
}
private final Collection<Color> orderedShards;
private final byte myColor;
private final float orderWeight;
private final Set<Color> enumSet;
private final String desc;
public static final ColorSet ALL_COLORS = fromMask(MagicColor.ALL_COLORS);
public static final ColorSet NO_COLORS = fromMask(MagicColor.COLORLESS);
private ColorSet(final Color... ordered) {
this.orderedShards = Arrays.asList(ordered);
this.myColor = orderedShards.stream().map(Color::getColorMask).reduce((byte)0, (a, b) -> (byte)(a | b));
this.orderWeight = this.getOrderWeight();
this.enumSet = EnumSet.copyOf(orderedShards);
this.desc = orderedShards.stream().map(Color::getShortName).collect(Collectors.joining());
this.orderWeight = this.calcOrderWeight();
}
public static ColorSet fromMask(final int mask) {
final int mask32 = mask & MagicColor.ALL_COLORS;
return cache[mask32];
return values()[mask32];
}
public static ColorSet fromEnums(final Color... colors) {
@@ -167,7 +131,10 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if successful
*/
public boolean hasAnyColor(final int colormask) {
return (this.myColor & colormask) != 0;
return (this.ordinal() & colormask) != 0;
}
public boolean hasAnyColor(final Color c) {
return this.orderedShards.contains(c);
}
/**
@@ -178,12 +145,12 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if successful
*/
public boolean hasAllColors(final int colormask) {
return (this.myColor & colormask) == colormask;
return (this.ordinal() & colormask) == colormask;
}
/** this has exactly the colors defined by operand. */
public boolean hasExactlyColor(final int colormask) {
return this.myColor == colormask;
return this.ordinal() == colormask;
}
/** this has no other colors except defined by operand. */
@@ -193,17 +160,17 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
/** this has no other colors except defined by operand. */
public boolean hasNoColorsExcept(final int colormask) {
return (this.myColor & ~colormask) == 0;
return (this.ordinal() & ~colormask) == 0;
}
/** This returns the colors that colormask contains that are not in color */
public ColorSet getMissingColors(final byte colormask) {
return fromMask(this.myColor & ~colormask);
return fromMask(this.ordinal() & ~colormask);
}
/** Operand has no other colors except defined by this. */
public boolean containsAllColorsFrom(final int colorProfile) {
return (~this.myColor & colorProfile) == 0;
return (~this.ordinal() & colorProfile) == 0;
}
/**
@@ -212,7 +179,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return the int
*/
public int countColors() {
return BinaryUtil.bitCount(this.myColor);
return BinaryUtil.bitCount(this.ordinal());
} // bit count
// order has to be: W U B R G multi colorless - same as cards numbering
@@ -222,7 +189,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
*
* @return the order weight
*/
private float getOrderWeight() {
private float calcOrderWeight() {
float res = this.countColors();
if (hasWhite()) {
res += 0.0005f;
@@ -241,6 +208,10 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
}
return res;
}
public float getOrderWeight()
{
return orderWeight;
}
/**
* Checks if is colorless.
@@ -248,7 +219,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if is colorless
*/
public boolean isColorless() {
return this.myColor == 0;
return this == C;
}
/**
@@ -266,7 +237,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if is all colors
*/
public boolean isAllColors() {
return this == ALL_COLORS;
return this == WUBRG;
}
/**
@@ -286,17 +257,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if is equal
*/
public boolean isEqual(final byte color) {
return color == this.myColor;
}
/*
* (non-Javadoc)
*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(final ColorSet other) {
return Float.compare(this.orderWeight, other.orderWeight);
return color == this.ordinal();
}
// Presets
@@ -346,23 +307,13 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
}
public ColorSet inverse() {
byte mask = this.myColor;
byte mask = (byte)this.ordinal();
mask ^= MagicColor.ALL_COLORS;
return fromMask(mask);
}
public byte getColor() {
return myColor;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return desc;
return (byte)ordinal();
}
/**
@@ -372,7 +323,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
* @return true, if successful
*/
public boolean sharesColorWith(final ColorSet ccOther) {
return (this.myColor & ccOther.myColor) != 0;
return (this.ordinal() & ccOther.ordinal()) != 0;
}
public ColorSet getSharedColors(final ColorSet ccOther) {
@@ -380,50 +331,20 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
}
public ColorSet getOffColors(final ColorSet ccOther) {
return fromMask(~this.myColor & ccOther.myColor);
return fromMask(~this.ordinal() & ccOther.ordinal());
}
public Set<Color> toEnumSet() {
return EnumSet.copyOf(enumSet);
return EnumSet.copyOf(orderedShards);
}
@Override
public Iterator<Byte> iterator() {
return new ColorIterator();
}
private class ColorIterator extends UnmodifiableIterator<Byte> {
int currentBit = -1;
private int getIndexOfNextColor(){
int nextBit = currentBit + 1;
while (nextBit < MagicColor.NUMBER_OR_COLORS) {
if ((myColor & MagicColor.WUBRG[nextBit]) != 0) {
break;
}
nextBit++;
}
return nextBit;
}
@Override
public boolean hasNext() {
return getIndexOfNextColor() < MagicColor.NUMBER_OR_COLORS;
}
@Override
public Byte next() {
currentBit = getIndexOfNextColor();
if (currentBit >= MagicColor.NUMBER_OR_COLORS) {
throw new NoSuchElementException();
}
return MagicColor.WUBRG[currentBit];
}
//@Override
public Iterator<Color> iterator() {
return this.orderedShards.iterator();
}
public Stream<Color> stream() {
return this.toEnumSet().stream();
return this.orderedShards.stream();
}
//Get array of mana cost shards for color set in the proper order

View File

@@ -593,7 +593,7 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public PaperCardFlags withMarkedColors(ColorSet markedColors) {
if(markedColors == null)
markedColors = ColorSet.NO_COLORS;
markedColors = ColorSet.C;
return new PaperCardFlags(this, markedColors, null);
}

View File

@@ -112,26 +112,20 @@ public abstract class PaperCardPredicates {
}
private static final class PredicateColor implements Predicate<PaperCard> {
private final byte operand;
private final MagicColor.Color operand;
private PredicateColor(final byte color) {
private PredicateColor(final MagicColor.Color color) {
this.operand = color;
}
@Override
public boolean test(final PaperCard card) {
for (final byte color : card.getRules().getColor()) {
if (color == operand) {
if (card.getRules().getColor().hasAnyColor(operand)) {
return true;
}
}
if (card.getRules().getType().hasType(CardType.CoreType.Land)) {
for (final byte color : card.getRules().getColorIdentity()) {
if (color == operand) {
if (card.getRules().getType().hasType(CardType.CoreType.Land) && card.getRules().getColorIdentity().hasAnyColor(operand)) {
return true;
}
}
}
return false;
}
}
@@ -235,11 +229,11 @@ public abstract class PaperCardPredicates {
public static final Predicate<PaperCard> IS_RARE_OR_MYTHIC = PaperCardPredicates.IS_RARE.or(PaperCardPredicates.IS_MYTHIC_RARE);
public static final Predicate<PaperCard> IS_SPECIAL = new PredicateRarity(CardRarity.Special);
public static final Predicate<PaperCard> IS_BASIC_LAND_RARITY = new PredicateRarity(CardRarity.BasicLand);
public static final Predicate<PaperCard> IS_BLACK = new PredicateColor(MagicColor.BLACK);
public static final Predicate<PaperCard> IS_BLUE = new PredicateColor(MagicColor.BLUE);
public static final Predicate<PaperCard> IS_GREEN = new PredicateColor(MagicColor.GREEN);
public static final Predicate<PaperCard> IS_RED = new PredicateColor(MagicColor.RED);
public static final Predicate<PaperCard> IS_WHITE = new PredicateColor(MagicColor.WHITE);
public static final Predicate<PaperCard> IS_BLACK = new PredicateColor(MagicColor.Color.BLACK);
public static final Predicate<PaperCard> IS_BLUE = new PredicateColor(MagicColor.Color.BLUE);
public static final Predicate<PaperCard> IS_GREEN = new PredicateColor(MagicColor.Color.GREEN);
public static final Predicate<PaperCard> IS_RED = new PredicateColor(MagicColor.Color.RED);
public static final Predicate<PaperCard> IS_WHITE = new PredicateColor(MagicColor.Color.WHITE);
public static final Predicate<PaperCard> IS_COLORLESS = paperCard -> paperCard.getRules().getColor().isColorless();
public static final Predicate<PaperCard> IS_UNREBALANCED = PaperCard::isUnRebalanced;
public static final Predicate<PaperCard> IS_REBALANCED = PaperCard::isRebalanced;

View File

@@ -35,7 +35,7 @@ public class ForgeScript {
boolean withSource = property.endsWith("Source");
final ColorSet colors;
if (withSource && StaticAbilityColorlessDamageSource.colorlessDamageSource(cardState)) {
colors = ColorSet.NO_COLORS;
colors = ColorSet.C;
} else {
colors = cardState.getCard().getColor(cardState);
}

View File

@@ -34,7 +34,7 @@ public class ChangeTextEffect extends SpellAbilityEffect {
final String[] changedColorWordsArray = sa.getParam("ChangeColorWord").split(" ");
if (changedColorWordsArray[0].equals("Choose")) {
originalColor = sa.getActivatingPlayer().getController().chooseColor(
Localizer.getInstance().getMessage("lblChooseColorReplace"), sa, ColorSet.ALL_COLORS);
Localizer.getInstance().getMessage("lblChooseColorReplace"), sa, ColorSet.WUBRG);
changedColorWordOriginal = TextUtil.capitalize(MagicColor.toLongString(originalColor));
} else {
changedColorWordOriginal = changedColorWordsArray[0];
@@ -44,7 +44,7 @@ public class ChangeTextEffect extends SpellAbilityEffect {
if (changedColorWordsArray[1].equals("Choose")) {
final ColorSet possibleNewColors;
if (originalColor == 0) { // no original color (ie. any or absent)
possibleNewColors = ColorSet.ALL_COLORS;
possibleNewColors = ColorSet.WUBRG;
} else { // may choose any except original color
possibleNewColors = ColorSet.fromMask(originalColor).inverse();
}

View File

@@ -156,7 +156,7 @@ public class ManaEffect extends SpellAbilityEffect {
for (int nChar = 0; nChar < colorsNeeded.length(); nChar++) {
mask |= MagicColor.fromName(colorsNeeded.charAt(nChar));
}
colorMenu = mask == 0 ? ColorSet.ALL_COLORS : ColorSet.fromMask(mask);
colorMenu = mask == 0 ? ColorSet.WUBRG : ColorSet.fromMask(mask);
byte val = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
if (0 == val) {
throw new RuntimeException("ManaEffect::resolve() /*any mana*/ - " + p + " color mana choice is empty for " + card.getName());

View File

@@ -124,8 +124,8 @@ public class ProtectEffect extends SpellAbilityEffect {
}
} else if (sa.getParam("Gains").startsWith("Defined")) {
CardCollection def = AbilityUtils.getDefinedCards(host, sa.getParam("Gains").substring(8), sa);
for (final Byte color : def.get(0).getColor()) {
gains.add(MagicColor.toLongString(color));
for (final MagicColor.Color color : def.get(0).getColor()) {
gains.add(color.getName());
}
} else {
gains.addAll(choices);

View File

@@ -34,14 +34,14 @@ public class ReplaceManaEffect extends SpellAbilityEffect {
// replace type and amount
replaced = sa.getParam("ReplaceMana");
if ("Any".equals(replaced)) {
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.ALL_COLORS);
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
replaced = MagicColor.toShortString(rs);
}
} else if (sa.hasParam("ReplaceType")) {
// replace color and colorless
String color = sa.getParam("ReplaceType");
if ("Any".equals(color)) {
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.ALL_COLORS);
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
color = MagicColor.toShortString(rs);
} else {
// convert in case Color Word used

View File

@@ -2271,7 +2271,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
public final ColorSet getMarkedColors() {
if (markedColor == null) {
return ColorSet.NO_COLORS;
return ColorSet.C;
}
return markedColor;
}

View File

@@ -27,7 +27,7 @@ public class AchievementTracker {
activatedNonPWUltimates.add(card.getName());
}
}
if (card.getColor().equals(ColorSet.ALL_COLORS)) {
if (card.getColor().equals(ColorSet.WUBRG)) {
challengesCompleted.add("Chromatic");
}
}

View File

@@ -17,7 +17,6 @@
*/
package forge.game.spellability;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import forge.card.ColorSet;
import forge.card.GamePieceType;
@@ -49,9 +48,9 @@ import forge.game.zone.ZoneType;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
@@ -658,8 +657,8 @@ public class AbilityManaPart implements java.io.Serializable {
}
// replace Chosen for Spire colors
if (origProduced.contains("ColorID")) {
Iterator<String> colors = Iterators.transform(sa.getHostCard().getMarkedColors().iterator(), MagicColor::toLongString);
origProduced = origProduced.replace("ColorID", getChosenColor(sa, () -> colors));
String str = sa.getHostCard().getMarkedColors().stream().map(c -> c.getShortName()).collect(Collectors.joining(" "));
origProduced = origProduced.replace("ColorID", str);
}
if (origProduced.contains("NotedColors")) {
// Should only be used for Paliano, the High City

View File

@@ -207,12 +207,12 @@ public final class StaticAbilityContinuous {
if (input.contains("CommanderColorID")) {
if (!hostCard.getController().getCommanders().isEmpty()) {
if (input.contains("NotCommanderColorID")) {
for (Byte color : hostCard.getController().getNotCommanderColorID()) {
newKeywords.add(input.replace("NotCommanderColorID", MagicColor.toLongString(color)));
for (MagicColor.Color color : hostCard.getController().getNotCommanderColorID()) {
newKeywords.add(input.replace("NotCommanderColorID", color.getName()));
}
return true;
} else for (Byte color : hostCard.getController().getCommanderColorID()) {
newKeywords.add(input.replace("CommanderColorID", MagicColor.toLongString(color)));
} else for (MagicColor.Color color : hostCard.getController().getCommanderColorID()) {
newKeywords.add(input.replace("CommanderColorID", color.getName()));
}
return true;
}
@@ -220,12 +220,9 @@ public final class StaticAbilityContinuous {
}
// two variants for Red vs. red in keyword
if (input.contains("ColorsYouCtrl") || input.contains("colorsYouCtrl")) {
final ColorSet colorsYouCtrl = CardUtil.getColorsFromCards(controller.getCardsIn(ZoneType.Battlefield));
for (byte color : colorsYouCtrl) {
final String colorWord = MagicColor.toLongString(color);
String y = input.replaceAll("ColorsYouCtrl", StringUtils.capitalize(colorWord));
y = y.replaceAll("colorsYouCtrl", colorWord);
for (MagicColor.Color color : CardUtil.getColorsFromCards(controller.getCardsIn(ZoneType.Battlefield))) {
String y = input.replaceAll("ColorsYouCtrl", StringUtils.capitalize(color.getName()));
y = y.replaceAll("colorsYouCtrl", color.getName());
newKeywords.add(y);
}
return true;
@@ -709,8 +706,8 @@ public final class StaticAbilityContinuous {
newKeywords.removeIf(input -> {
// replace one Keyword with list of keywords
if (input.startsWith("Protection") && input.contains("CardColors")) {
for (Byte color : affectedCard.getColor()) {
extraKeywords.add(input.replace("CardColors", MagicColor.toLongString(color)));
for (MagicColor.Color color : affectedCard.getColor()) {
extraKeywords.add(input.replace("CardColors", color.getName()));
}
return true;
}
@@ -924,7 +921,7 @@ public final class StaticAbilityContinuous {
addColors = ColorSet.fromNames(hostCard.getChosenColors());
}
} else if (colors.equals("All")) {
addColors = ColorSet.ALL_COLORS;
addColors = ColorSet.WUBRG;
} else {
addColors = ColorSet.fromNames(colors.split(" & "));
}

View File

@@ -54,7 +54,7 @@ public class Zone implements java.io.Serializable, Iterable<Card> {
// might support different order via preference later
private static final Comparator<Card> COMPARATOR = Comparator.comparingInt((Card c) -> c.getCMC())
.thenComparing(c -> c.getColor())
.thenComparing(c -> c.getColor().getOrderWeight())
.thenComparing(Comparator.comparing(Card::getName))
.thenComparing(Card::hasPerpetual);

View File

@@ -464,7 +464,7 @@ public class TrackableTypes {
public static final TrackableType<ColorSet> ColorSetType = new TrackableType<ColorSet>() {
@Override
public ColorSet getDefaultValue() {
return ColorSet.NO_COLORS;
return ColorSet.C;
}
@Override

View File

@@ -33,7 +33,7 @@ public class ColorSetRenderer extends ItemCellRenderer {
this.cs = (ColorSet) value;
}
else {
this.cs = ColorSet.NO_COLORS;
this.cs = ColorSet.C;
}
this.setToolTipText(cs.toString());
return super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);

View File

@@ -214,22 +214,8 @@ public class VAssignGenericAmount {
pnlTargets.add(mp, "w 145px!, h 170px!, gap 5px 5px 3px 3px, ax center");
mp.addMouseListener(mad);
targetsMap.put(mp, at);
} else if (at.entity instanceof Byte) {
SkinImage manaSymbol;
byte color = (Byte) at.entity;
if (color == MagicColor.WHITE) {
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_W);
} else if (color == MagicColor.BLUE) {
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_U);
} else if (color == MagicColor.BLACK) {
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_B);
} else if (color == MagicColor.RED) {
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_R);
} else if (color == MagicColor.GREEN) {
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_G);
} else { // Should never come here, but add this to avoid compile error
manaSymbol = FSkin.getImage(FSkinProp.IMG_MANA_COLORLESS);
}
} else if (at.entity instanceof MagicColor.Color color) {
SkinImage manaSymbol = FSkin.getImage(FSkinProp.MANA_IMG.get(color.getShortName()));
final MiscCardPanel mp = new MiscCardPanel(matchUI, "", manaSymbol);
mp.setCardBounds(0, 0, 70, 70);
pnlTargets.add(mp, "w 100px!, h 150px!, gap 5px 5px 3px 3px, ax center");

View File

@@ -471,12 +471,12 @@ public class PlayerControllerForTests extends PlayerController {
@Override
public byte chooseColor(String message, SpellAbility sa, ColorSet colors) {
return Iterables.getFirst(colors, MagicColor.WHITE);
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
}
@Override
public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) {
return Iterables.getFirst(colors, (byte)0);
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS).getColorMask();
}
private CardCollection chooseItems(CardCollectionView items, int amount) {

View File

@@ -45,7 +45,7 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
private int heroRace;
private int avatarIndex;
private boolean isFemale;
private ColorSet colorIdentity = ColorSet.ALL_COLORS;
private ColorSet colorIdentity = ColorSet.WUBRG;
// Deck data
private Deck deck;
@@ -396,9 +396,9 @@ public class AdventurePlayer implements Serializable, SaveFileContent {
if (temp != null)
setColorIdentity(temp);
else
colorIdentity = ColorSet.ALL_COLORS;
colorIdentity = ColorSet.WUBRG;
} else
colorIdentity = ColorSet.ALL_COLORS;
colorIdentity = ColorSet.WUBRG;
gold = data.readInt("gold");
maxLife = data.readInt("maxLife");

View File

@@ -250,8 +250,7 @@ public class CardUtil {
this.colors = 0;
for (String color : type.colors) {
if ("colorID".equals(color))
for (byte c : Current.player().getColorIdentity())
colors |= c;
colors |= Current.player().getColorIdentity().getColor();
else
colors |= MagicColor.fromName(color.toLowerCase());
}

View File

@@ -37,7 +37,6 @@ import forge.card.CardZoom;
import forge.card.MagicColor;
import forge.game.card.CardView;
import forge.game.player.PlayerView;
import forge.localinstance.skin.FSkinProp;
import forge.screens.match.MatchController;
import forge.toolbox.FCardPanel;
import forge.toolbox.FContainer;
@@ -165,25 +164,10 @@ public class VAssignGenericAmount extends FDialog {
max = max0;
if (entity instanceof CardView) {
obj = add(new EffectSourcePanel((CardView)entity));
} else if (entity instanceof PlayerView) {
PlayerView player = (PlayerView)entity;
} else if (entity instanceof PlayerView player) {
obj = add(new MiscTargetPanel(player.getName(), MatchController.getPlayerAvatar(player), null));
} else if (entity instanceof Byte) {
FSkinImageInterface manaSymbol;
byte color = (Byte) entity;
if (color == MagicColor.WHITE) {
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_W);
} else if (color == MagicColor.BLUE) {
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_U);
} else if (color == MagicColor.BLACK) {
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_B);
} else if (color == MagicColor.RED) {
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_R);
} else if (color == MagicColor.GREEN) {
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_G);
} else { // Should never come here, but add this to avoid compile error
manaSymbol = Forge.getAssets().images().get(FSkinProp.IMG_MANA_COLORLESS);
}
} else if (entity instanceof MagicColor.Color color) {
FSkinImageInterface manaSymbol = Forge.getAssets().manaImages().get(color.getShortName());
obj = add(new MiscTargetPanel("", manaSymbol, entity));
} else {
obj = add(new MiscTargetPanel(entity.toString(), FSkinImage.UNKNOWN, null));

View File

@@ -276,7 +276,7 @@ public abstract class InputPayMana extends InputSyncronizedBase {
// If the card has any ability that tracks mana spent, skip express Mana choice
if (saPaidFor.tracksManaSpent()) {
colorCanUse = ColorSet.ALL_COLORS.getColor();
colorCanUse = ColorSet.WUBRG.getColor();
guessAbilityWithRequiredColors = false;
}

View File

@@ -105,7 +105,7 @@ public class ConquestRegion {
protected ConquestRegion read(String line) {
String name = null;
String artCardName = null;
ColorSet colorSet = ColorSet.ALL_COLORS;
ColorSet colorSet = ColorSet.WUBRG;
Predicate<PaperCard> pred = x -> true;
String key, value;

View File

@@ -560,7 +560,7 @@ public final class BoosterUtils {
public static void sort(List<PaperCard> cards) {
//sort cards alphabetically so colors appear together and rares appear on top
cards.sort(Comparator.comparing(PaperCard::getName));
cards.sort(Comparator.comparing(c -> c.getRules().getColor()));
cards.sort(Comparator.comparing(c -> c.getRules().getColor().getOrderWeight()));
cards.sort(Comparator.comparing(PaperCard::getRarity).reversed());
}
}

View File

@@ -91,7 +91,7 @@ public enum ColumnDef {
* The color column.
*/
COLOR("lblColor", "ttColor", 46, true, SortState.ASC,
from -> toColor(from.getKey()),
from -> toColor(from.getKey()).getOrderWeight(),
from -> toColor(from.getKey())),
/**
* The power column.
@@ -271,7 +271,7 @@ public enum ColumnDef {
* The deck color column.
*/
DECK_COLOR("lblColor", "ttColor", 70, true, SortState.ASC,
from -> toDeckColor(from.getKey()),
from -> toDeckColor(from.getKey()).getOrderWeight(),
from -> toDeckColor(from.getKey())),
/**
* The deck format column.
@@ -377,7 +377,7 @@ public enum ColumnDef {
}
private static ColorSet toColor(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.NO_COLORS;
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.C;
}
private static Integer toPower(final InventoryItem i) {

View File

@@ -441,7 +441,7 @@ public class SFilterUtil {
final byte colors = colors0;
final boolean wantColorless = buttonMap.get(StatTypes.COLORLESS).isSelected();
final boolean wantMulticolor = buttonMap.get(StatTypes.MULTICOLOR).isSelected();
final boolean wantAllColors = colors == ColorSet.ALL_COLORS.getColor();
final boolean wantAllColors = colors == ColorSet.WUBRG.getColor();
//Use color identity instead of color for lands, unless all colors are filtered out anyway.
final boolean filterLandsByCI = colors != 0 && FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_FILTER_LANDS_BY_COLOR_IDENTITY);

View File

@@ -353,16 +353,19 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
final CardView vSource = CardView.get(sa.getHostCard());
final Map<Object, Integer> vAffected = new LinkedHashMap<>(manaAmount);
Integer maxAmount = different ? 1 : manaAmount;
for (Byte color : colorSet) {
for (MagicColor.Color color : colorSet) {
if (color == MagicColor.Color.COLORLESS) {
continue;
}
vAffected.put(color, maxAmount);
}
final Map<Object, Integer> vResult = getGui().assignGenericAmount(vSource, vAffected, manaAmount, false,
localizer.getMessage("lblMana").toLowerCase());
Map<Byte, Integer> result = new HashMap<>();
if (vResult != null) { //fix for netplay
for (Byte color : colorSet) {
for (MagicColor.Color color : colorSet) {
if (vResult.containsKey(color)) {
result.put(color, vResult.get(color));
result.put(color.getColorMask(), vResult.get(color));
}
}
}
@@ -1868,8 +1871,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (withColorless) {
colorNamesBuilder.add(MagicColor.toLongString(MagicColor.COLORLESS));
}
for (final Byte b : colors) {
colorNamesBuilder.add(MagicColor.toLongString(b));
for (final MagicColor.Color color : colors) {
colorNamesBuilder.add(color.getName());
}
final ImmutableList<String> colorNames = colorNamesBuilder.build();
if (colorNames.size() > 2) {