ColorSet: add combine function (#8960)

This commit is contained in:
Hans Mackowiak
2025-10-20 09:45:57 +02:00
committed by GitHub
parent a8d494d2d8
commit 5efd7e6e7c
16 changed files with 49 additions and 39 deletions

View File

@@ -235,7 +235,7 @@ public final class CardRules implements ICardCharacteristics {
public ColorSet getColor() {
switch (splitType.getAggregationMethod()) {
case COMBINE:
return ColorSet.fromMask(mainPart.getColor().getColor() | otherPart.getColor().getColor());
return ColorSet.combine(mainPart.getColor(), otherPart.getColor());
default:
return mainPart.getColor();
}

View File

@@ -123,6 +123,14 @@ public enum ColorSet implements Iterable<Color>, Serializable {
return fromMask(mana.getColorProfile());
}
public static ColorSet combine(final ColorSet... colors) {
byte mask = 0;
for (ColorSet c : colors) {
mask |= c.getColor();
}
return fromMask(mask);
}
/**
* Checks for any color.
*

View File

@@ -19,8 +19,9 @@ package forge.game;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import forge.card.ColorSet;
import forge.card.GamePieceType;
import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils;
@@ -787,7 +788,7 @@ public final class GameActionUtil {
eff.setOwner(controller);
eff.setImageKey(sourceCard.getImageKey());
eff.setColor(MagicColor.COLORLESS);
eff.setColor(ColorSet.C);
eff.setGamePieceType(GamePieceType.EFFECT);
// try to get the SpellAbility from the mana ability
//eff.setEffectSource((SpellAbility)null);

View File

@@ -6,8 +6,8 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Table;
import forge.GameCommand;
import forge.card.CardRarity;
import forge.card.ColorSet;
import forge.card.GamePieceType;
import forge.card.MagicColor;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.GameObject;
@@ -617,10 +617,10 @@ public abstract class SpellAbilityEffect {
if (name.startsWith("Emblem")) {
eff.setEmblem(true);
// Emblem needs to be colorless
eff.setColor(MagicColor.COLORLESS);
eff.setColor(ColorSet.C);
eff.setRarity(CardRarity.Common);
} else {
eff.setColor(hostCard.getColor().getColor());
eff.setColor(hostCard.getColor());
eff.setRarity(hostCard.getRarity());
}

View File

@@ -4409,9 +4409,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
}
public final void setColor(final String... color) {
setColor(ColorSet.fromNames(color).getColor());
setColor(ColorSet.fromNames(color));
}
public final void setColor(final byte color) {
public final void setColor(final ColorSet color) {
currentState.setColor(color);
}
@@ -4419,7 +4419,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
return getColor(currentState);
}
public final ColorSet getColor(CardState state) {
byte colors = state.getColor();
byte colors = state.getColor().getColor();
for (final CardColor cc : Iterables.concat(changedCardColorsByText.values(), changedCardColorsCharacterDefining.values(), changedCardColors.values())) {
if (cc.additional()) {
colors |= cc.color().getColor();

View File

@@ -303,7 +303,7 @@ public class CardCopyService {
newCopy.setCounters(Maps.newHashMap(copyFrom.getCounters()));
newCopy.setColor(copyFrom.getColor().getColor());
newCopy.setColor(copyFrom.getColor());
newCopy.setPhasedOut(copyFrom.getPhasedOut());
newCopy.setTapped(copyFrom.isTapped());
newCopy.setTributed(copyFrom.isTributed());

View File

@@ -339,12 +339,10 @@ public class CardFactory {
card.setName(rules.getName());
// Combined mana cost
ManaCost combinedManaCost = ManaCost.combine(rules.getMainPart().getManaCost(), rules.getOtherPart().getManaCost());
card.setManaCost(combinedManaCost);
card.setManaCost(rules.getManaCost());
// Combined card color
final byte combinedColor = (byte) (rules.getMainPart().getColor().getColor() | rules.getOtherPart().getColor().getColor());
card.setColor(combinedColor);
card.setColor(rules.getColor());
card.setType(new CardType(rules.getType()));
// Combined text based on Oracle text - might not be necessary
@@ -407,7 +405,7 @@ public class CardFactory {
// Super and 'middle' types should use enums.
c.setType(new CardType(face.getType()));
c.setColor(face.getColor().getColor());
c.setColor(face.getColor());
if (face.getIntPower() != Integer.MAX_VALUE) {
c.setBasePower(face.getIntPower());
@@ -593,11 +591,11 @@ public class CardFactory {
}
if (cause.hasParam("AddColors")) {
state.addColor(colors.getColor());
state.addColor(colors);
}
if (cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) {
state.setColor(colors.getColor());
state.setColor(colors);
}
if (cause.hasParam("NonLegendary")) {

View File

@@ -60,7 +60,7 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
private String name = "";
private CardType type = new CardType(false);
private ManaCost manaCost = ManaCost.NO_COST;
private byte color = MagicColor.COLORLESS;
private ColorSet color = ColorSet.C;
private String oracleText = "";
private String functionalVariantName = null;
private int basePower = 0;
@@ -191,14 +191,14 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
view.updateManaCost(this);
}
public final byte getColor() {
public final ColorSet getColor() {
return color;
}
public final void addColor(final byte color) {
this.color |= color;
public final void addColor(final ColorSet color) {
this.color = ColorSet.combine(this.color, color);
view.updateColors(card);
}
public final void setColor(final byte color) {
public final void setColor(final ColorSet color) {
this.color = color;
view.updateColors(card);
}

View File

@@ -1308,7 +1308,7 @@ public class CardView extends GameEntityView {
set(TrackableProperty.Colors, c.getColor());
}
void updateColors(CardState c) {
set(TrackableProperty.Colors, ColorSet.fromMask(c.getColor()));
set(TrackableProperty.Colors, c.getColor());
}
void setOriginalColors(Card c) {
set(TrackableProperty.OriginalColors, c.getColor());

View File

@@ -6,8 +6,11 @@ import com.google.common.collect.Lists;
import forge.ImageKeys;
import forge.StaticData;
import forge.card.CardType;
import forge.card.ColorSet;
import forge.card.GamePieceType;
import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
@@ -32,14 +35,14 @@ public class TokenInfo {
final String[] intrinsicKeywords;
final int basePower;
final int baseToughness;
final String color;
final ColorSet color;
public TokenInfo(Card c) {
// TODO: Figure out how to handle legacy images?
this.name = c.getName();
this.imageName = ImageKeys.getTokenImageName(c.getImageKey());
this.manaCost = c.getManaCost().toString();
this.color = MagicColor.toShortString(c.getCurrentState().getColor());
this.color = c.getCurrentState().getColor();
this.types = getCardTypes(c);
List<String> list = Lists.newArrayList();
@@ -60,7 +63,7 @@ public class TokenInfo {
String[] types = null;
String[] keywords = null;
String imageName = null;
String color = "";
ColorSet color = null;
for (String info : tokenInfo) {
int index = info.indexOf(':');
if (index == -1) {
@@ -80,7 +83,7 @@ public class TokenInfo {
} else if (info.startsWith("Image:")) {
imageName = remainder;
} else if (info.startsWith("Color:")) {
color = remainder;
color = ColorSet.fromNames(remainder);
}
}
@@ -115,7 +118,7 @@ public class TokenInfo {
c.setName(name);
c.setImageKey(ImageKeys.getTokenKey(imageName));
c.setColor(color.isEmpty() ? manaCost : color);
c.setColor(color == null ? ColorSet.fromManaCost(new ManaCost(new ManaCostParser(manaCost))) : color);
c.setGamePieceType(GamePieceType.TOKEN);
for (final String t : types) {
@@ -189,7 +192,7 @@ public class TokenInfo {
}
}
result.setColor(color);
result.setColor(ColorSet.fromMask(color));
}
}
if (!typeMap.isEmpty()) {

View File

@@ -253,7 +253,7 @@ public class AbilityManaPart implements java.io.Serializable {
eff.setOwner(sourceCard.getController());
eff.setImageKey(sourceCard.getImageKey());
eff.setColor(MagicColor.COLORLESS);
eff.setColor(ColorSet.C);
eff.setGamePieceType(GamePieceType.EFFECT);
String cantcounterstr = "Event$ Counter | ValidSA$ Spell.IsRemembered | Description$ That spell can't be countered.";

View File

@@ -623,7 +623,7 @@ public final class StaticAbilityContinuous {
// Mana cost
affectedCard.addChangedManaCost(state.getManaCost(), se.getTimestamp(), stAb.getId());
// color
affectedCard.addColorByText(ColorSet.fromMask(state.getColor()), se.getTimestamp(), stAb);
affectedCard.addColorByText(state.getColor(), se.getTimestamp(), stAb);
// type
affectedCard.addChangedCardTypesByText(new CardType(state.getType()), se.getTimestamp(), stAb.getId());
// abilities

View File

@@ -34,9 +34,9 @@ public class CardThemedCommanderDeckBuilder extends CardThemedDeckBuilder {
this.availableList.removeAll(aiPlayables);
targetSize=format.getMainRange().getMinimum();
colors = keyCard.getRules().getColorIdentity();
colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, keyCard.getRules().getColorIdentity());
if (secondKeyCard != null && !format.equals(DeckFormat.Oathbreaker)) {
colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, secondKeyCard.getRules().getColorIdentity());
targetSize--;
}
numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue();

View File

@@ -39,9 +39,9 @@ public class CardThemedConquestDeckBuilder extends CardThemedDeckBuilder {
this.availableList.removeAll(aiPlayables);
targetSize=format.getMainRange().getMinimum();
colors = keyCard.getRules().getColorIdentity();
colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, keyCard.getRules().getColorIdentity());
if(secondKeyCard!=null) {
colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, secondKeyCard.getRules().getColorIdentity());
targetSize--;
}
numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue();

View File

@@ -133,11 +133,11 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
System.out.println("Pre Colors: " + colors.toEnumSet().toString());
}
if(!colors.hasAllColors(keyCard.getRules().getColorIdentity().getColor())){
colors = ColorSet.fromMask(colors.getColor() | keyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, keyCard.getRules().getColorIdentity());
}
if(secondKeyCard!=null) {
if (!colors.hasAllColors(secondKeyCard.getRules().getColorIdentity().getColor())) {
colors = ColorSet.fromMask(colors.getColor() | secondKeyCard.getRules().getColorIdentity().getColor());
colors = ColorSet.combine(colors, secondKeyCard.getRules().getColorIdentity());
}
}
numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue();
@@ -462,7 +462,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
// Want a card that has just one "off" color.
final ColorSet off = colors.getOffColors(card.getRules().getColor());
if (off.isMonoColor()) {
colors = ColorSet.fromMask(colors.getColor() | off.getColor());
colors = ColorSet.combine(colors, off);
break;
}
}

View File

@@ -484,7 +484,7 @@ public class LimitedDeckBuilder extends DeckGeneratorBase {
// Want a card that has just one "off" color.
final ColorSet off = colors.getOffColors(card.getRules().getColor());
if (off.isMonoColor()) {
colors = ColorSet.fromMask(colors.getColor() | off.getColor());
colors = ColorSet.combine(colors, off);
break;
}
}