Merge branch 'master' into feature/implement-harmonize-ability

This commit is contained in:
theelk801 2025-03-30 09:54:23 -04:00
commit 891deebb92
56 changed files with 2507 additions and 486 deletions

View file

@ -5,10 +5,7 @@ import mage.constants.ColoredManaSymbol;
import mage.util.Copyable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.*;
public class ObjectColor implements Serializable, Copyable<ObjectColor>, Comparable<ObjectColor> {
@ -19,17 +16,13 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
public static final ObjectColor GREEN = new ObjectColor("G");
public static final ObjectColor COLORLESS = new ObjectColor();
public static final ObjectColor GOLD = new ObjectColor("O"); // Not multicolored - Sword of Dungeons & Dragons TODO: remove this, it shouldn't have been added
private static final List<ObjectColor>allColors= Arrays.asList(WHITE,BLUE,BLACK,RED,GREEN);
private boolean white;
private boolean blue;
private boolean black;
private boolean red;
private boolean green;
private boolean gold;
public ObjectColor() {
}
@ -51,10 +44,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
case 'G':
green = true;
break;
case 'O':
gold = true;
break;
}
}
}
@ -65,8 +54,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
black = color.black;
red = color.red;
green = color.green;
gold = color.gold;
}
/**
@ -83,8 +70,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
newColor.black = black || other.black;
newColor.red = red || other.red;
newColor.green = green || other.green;
newColor.gold = gold || other.gold;
return newColor;
}
@ -102,8 +87,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
newColor.black = black && other.black;
newColor.red = red && other.red;
newColor.green = green && other.green;
newColor.gold = gold && other.gold;
return newColor;
}
@ -124,10 +107,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (red) {
count++;
}
if (gold) {
count++;
}
return count;
}
@ -176,10 +155,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (colors.size() >= 2 && secondColor - firstColor >= 3) {
Collections.swap(colors, 0, 1);
}
if (this.isGold()) {
colors.add(ObjectColor.GOLD);
}
return colors;
}
@ -189,8 +164,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
this.setGreen(color != null && color.isGreen());
this.setRed(color != null && color.isRed());
this.setWhite(color != null && color.isWhite());
this.setGold(color != null && color.isGold());
}
public void addColor(ObjectColor color) {
@ -209,10 +182,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (color.isGreen()) {
setGreen(true);
}
if (color.isGold()) {
setGold(true);
}
}
public boolean isColorless() {
@ -220,32 +189,26 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
}
public boolean hasColor() {
return white || blue || black || red || green
|| gold;
return white || blue || black || red || green;
}
public boolean isMulticolored() {
if (isColorless()) {
return false;
}
if (white && (blue || black || red || green
|| gold)) {
return true;
if (white) {
return blue || black || red || green;
}
if (blue && (black || red || green
|| gold)) {
return true;
if (blue) {
return black || red || green;
}
if (black && (red || green
|| gold)) {
return true;
if (black) {
return red || green;
}
if (red && (green
|| gold)) {
return true;
if (red) {
return green;
}
return green
&& gold;
return false;
}
public boolean isWhite() {
@ -288,14 +251,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
this.green = green;
}
public boolean isGold() {
return gold;
}
public void setGold(boolean gold) {
this.gold = gold;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(5);
@ -314,36 +269,27 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (green) {
sb.append('G');
}
if (gold) {
sb.append('O');
}
return sb.toString();
}
public String getDescription() {
if (getColorCount() > 1) {
if (isMulticolored()) {
return "multicolored";
} else {
if (white) {
return "white";
}
if (blue) {
return "blue";
}
if (black) {
return "black";
}
if (red) {
return "red";
}
if (green) {
return "green";
}
if (gold) {
return "gold";
}
}
if (white) {
return "white";
}
if (blue) {
return "blue";
}
if (black) {
return "black";
}
if (red) {
return "red";
}
if (green) {
return "green";
}
return "colorless";
}
@ -372,10 +318,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (test.green != this.green) {
return false;
}
if (test.gold != this.gold) {
return false;
}
return true;
}
@ -387,8 +329,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
hash = 23 * hash + (this.black ? 1 : 0);
hash = 23 * hash + (this.red ? 1 : 0);
hash = 23 * hash + (this.green ? 1 : 0);
hash = 23 * hash + (this.gold ? 1 : 0);
return hash;
}
@ -411,10 +351,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
if (color.green && this.green) {
return true;
}
if (color.gold && this.gold) {
return true;
}
return false;
}
@ -422,8 +358,7 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
// 105.4. [...] Multicolored is not a color. Neither is colorless.
return !color.isColorless()
&& (color.white && white || color.blue && blue || color.black && black
|| color.red && red || color.green && green
|| color.gold && gold);
|| color.red && red || color.green && green);
}
@Override
@ -450,8 +385,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
o1 = 4;
} else if (this.isWhite()) {
o1 = 5;
} else if (this.isGold()) {
o1 = 6;
}
if (o.isMulticolored()) {
@ -468,8 +401,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
o2 = 4;
} else if (o.isWhite()) {
o2 = 5;
} else if (o.isGold()) {
o2 = 6;
}
return o1 - o2;
@ -482,7 +413,6 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
* @return null or
*/
public ColoredManaSymbol getOneColoredManaSymbol() {
if (isMulticolored()) {
throw new IllegalStateException("Found multicolor object, but was waiting for simple color.");
}
@ -503,19 +433,10 @@ public class ObjectColor implements Serializable, Copyable<ObjectColor>, Compara
return ColoredManaSymbol.W;
}
if (isGold()) {
return ColoredManaSymbol.O;
}
return null;
}
public static List<ObjectColor> getAllColors() {
List<ObjectColor> colors = new ArrayList<>();
colors.add(ObjectColor.WHITE);
colors.add(ObjectColor.BLUE);
colors.add(ObjectColor.BLACK);
colors.add(ObjectColor.RED);
colors.add(ObjectColor.GREEN);
return colors;
return allColors;
}
}

View file

@ -4,72 +4,65 @@ import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* @author TheElk801
*/
public class MostCommonColorCondition implements Condition {
protected final ObjectColor compareColor;
protected final boolean isMono;
protected final Predicate predicate;
protected final FilterPermanent filter;
public MostCommonColorCondition(ObjectColor color) {
this(color, false, null);
}
//Use this one if you don't want a tie for most common and want to restrict to a player (literally only Call to Arms)
// Use this one if you don't want a tie for most common and want to restrict to a player (literally only Call to Arms)
public MostCommonColorCondition(ObjectColor color, boolean isMono, Predicate predicate) {
this.compareColor = color;
this.isMono = isMono;
this.predicate = predicate;
if (predicate == null) {
this.filter = StaticFilters.FILTER_PERMANENT;
} else {
this.filter = new FilterPermanent();
this.filter.add(predicate);
}
}
@Override
public boolean apply(Game game, Ability source) {
FilterPermanent[] colorFilters = new FilterPermanent[6];
int i = 0;
for (ObjectColor color : ObjectColor.getAllColors()) {
colorFilters[i] = new FilterPermanent();
colorFilters[i].add(new ColorPredicate(color));
if (predicate != null) {
colorFilters[i].add(predicate);
}
i++;
}
int[] colorCounts = new int[6];
i = 0;
for (ObjectColor color : ObjectColor.getAllColors()) {
colorFilters[i].add(new ColorPredicate(color));
colorCounts[i] = game.getBattlefield().count(colorFilters[i], source.getControllerId(), source, game);
i++;
}
int max = 0;
for (i = 0; i < 5; i++) {
if (colorCounts[i] > max) {
max = colorCounts[i] * 1;
Map<String, Integer> colorMap = new HashMap<>();
for (Permanent permanent : game
.getBattlefield()
.getActivePermanents(filter, source.getControllerId(), source, game)) {
for (char c : permanent.getColor(game).toString().toCharArray()) {
colorMap.compute("" + c, CardUtil::setOrIncrementValue);
}
}
i = 0;
ObjectColor commonest = new ObjectColor();
for (ObjectColor color : ObjectColor.getAllColors()) {
if (colorCounts[i] == max) {
commonest.addColor(color);
}
i++;
}
if (compareColor.shares(commonest)) {
if (isMono) {
return !commonest.isMulticolored();
} else {
return true;
}
}
return false;
int most = colorMap
.values()
.stream()
.mapToInt(x -> x)
.max()
.orElse(0);
ObjectColor common = new ObjectColor(
colorMap.entrySet()
.stream()
.filter(e -> e.getValue() == most)
.map(Map.Entry::getKey)
.collect(Collectors.joining())
);
return common.shares(compareColor) && (!isMono || common.getColorCount() == 1);
}
@Override

View file

@ -6,6 +6,8 @@ import mage.constants.CardType;
import mage.constants.SubType;
/**
* This token is supposed to be "gold" but the game rules don't support gold as a color in black border
*
* @author Saga
*/
public final class DragonTokenGold extends TokenImpl {
@ -13,7 +15,11 @@ public final class DragonTokenGold extends TokenImpl {
public DragonTokenGold() {
super("Dragon Token", "4/4 gold Dragon creature token with flying");
cardType.add(CardType.CREATURE);
color.setGold(true);
color.setWhite(true);
color.setBlue(true);
color.setBlack(true);
color.setRed(true);
color.setGreen(true);
subtype.add(SubType.DRAGON);
power = new MageInt(4);
toughness = new MageInt(4);
@ -27,4 +33,4 @@ public final class DragonTokenGold extends TokenImpl {
public DragonTokenGold copy() {
return new DragonTokenGold(this);
}
}
}

View file

@ -0,0 +1,29 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author PurpleCrowbar
*/
public final class NoFlyingSpiritWhiteToken extends TokenImpl {
public NoFlyingSpiritWhiteToken() {
super("Spirit Token", "1/1 white Spirit creature token");
cardType.add(CardType.CREATURE);
subtype.add(SubType.SPIRIT);
color.setWhite(true);
power = new MageInt(1);
toughness = new MageInt(1);
}
private NoFlyingSpiritWhiteToken(final NoFlyingSpiritWhiteToken token) {
super(token);
}
@Override
public NoFlyingSpiritWhiteToken copy() {
return new NoFlyingSpiritWhiteToken(this);
}
}

View file

@ -0,0 +1,29 @@
package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
/**
* @author PurpleCrowbar
*/
public final class Soldier22Token extends TokenImpl {
public Soldier22Token() {
super("Soldier Token", "2/2 white Soldier creature token");
cardType.add(CardType.CREATURE);
color.setWhite(true);
subtype.add(SubType.SOLDIER);
power = new MageInt(2);
toughness = new MageInt(2);
}
private Soldier22Token(final Soldier22Token token) {
super(token);
}
@Override
public Soldier22Token copy() {
return new Soldier22Token(this);
}
}