mirror of
https://github.com/magefree/mage.git
synced 2026-01-26 13:19:18 -08:00
Merge branch 'master' into feature/implement-harmonize-ability
This commit is contained in:
commit
891deebb92
56 changed files with 2507 additions and 486 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue