mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge branch 'master' into AI_ATTACK_TIMEOUT
This commit is contained in:
@@ -43,6 +43,7 @@ import java.util.stream.Collectors;
|
|||||||
public final class CardDb implements ICardDatabase, IDeckGenPool {
|
public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||||
public final static String foilSuffix = "+";
|
public final static String foilSuffix = "+";
|
||||||
public final static char NameSetSeparator = '|';
|
public final static char NameSetSeparator = '|';
|
||||||
|
public final static String colorIDPrefix = "#";
|
||||||
private final String exlcudedCardName = "Concentrate";
|
private final String exlcudedCardName = "Concentrate";
|
||||||
private final String exlcudedCardSet = "DS0";
|
private final String exlcudedCardSet = "DS0";
|
||||||
|
|
||||||
@@ -91,13 +92,19 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
public int artIndex;
|
public int artIndex;
|
||||||
public boolean isFoil;
|
public boolean isFoil;
|
||||||
public String collectorNumber;
|
public String collectorNumber;
|
||||||
|
public Set<String> colorID;
|
||||||
|
|
||||||
private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber) {
|
private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber) {
|
||||||
|
this(name, edition, artIndex, isFoil, collectorNumber, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CardRequest(String name, String edition, int artIndex, boolean isFoil, String collectorNumber, Set<String> colorID) {
|
||||||
cardName = name;
|
cardName = name;
|
||||||
this.edition = edition;
|
this.edition = edition;
|
||||||
this.artIndex = artIndex;
|
this.artIndex = artIndex;
|
||||||
this.isFoil = isFoil;
|
this.isFoil = isFoil;
|
||||||
this.collectorNumber = collectorNumber;
|
this.collectorNumber = collectorNumber;
|
||||||
|
this.colorID = colorID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFoilCardName(final String cardName){
|
public static boolean isFoilCardName(final String cardName){
|
||||||
@@ -126,6 +133,14 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
return requestInfo + NameSetSeparator + artIndex;
|
return requestInfo + NameSetSeparator + artIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String compose(String cardName, String setCode, int artIndex, Set<String> colorID) {
|
||||||
|
String requestInfo = compose(cardName, setCode);
|
||||||
|
artIndex = Math.max(artIndex, IPaperCard.DEFAULT_ART_INDEX);
|
||||||
|
String cid = colorID == null ? "" : NameSetSeparator +
|
||||||
|
colorID.toString().replace("[", colorIDPrefix).replace(", ", colorIDPrefix).replace("]", "");
|
||||||
|
return requestInfo + NameSetSeparator + artIndex + cid;
|
||||||
|
}
|
||||||
|
|
||||||
public static String compose(String cardName, String setCode, String collectorNumber) {
|
public static String compose(String cardName, String setCode, String collectorNumber) {
|
||||||
String requestInfo = compose(cardName, setCode);
|
String requestInfo = compose(cardName, setCode);
|
||||||
// CollectorNumber will be wrapped in square brackets
|
// CollectorNumber will be wrapped in square brackets
|
||||||
@@ -155,6 +170,10 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
return s.startsWith("[") && s.endsWith("]");
|
return s.startsWith("[") && s.endsWith("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isColorIDString(String s) {
|
||||||
|
return s.startsWith(colorIDPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isArtIndex(String s) {
|
private static boolean isArtIndex(String s) {
|
||||||
return StringUtils.isNumeric(s) && s.length() <= 2 ; // only artIndex between 1-99
|
return StringUtils.isNumeric(s) && s.length() <= 2 ; // only artIndex between 1-99
|
||||||
}
|
}
|
||||||
@@ -172,7 +191,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
String cardName = info[0];
|
String cardName = info[0];
|
||||||
String setCode = info[1];
|
String setCode = info[1];
|
||||||
int artIndex = Integer.parseInt(info[2]);
|
int artIndex = Integer.parseInt(info[2]);
|
||||||
return new CardRequest(cardName, setCode, artIndex, isFoil, IPaperCard.NO_COLLECTOR_NUMBER);
|
return new CardRequest(cardName, setCode, artIndex, isFoil, IPaperCard.NO_COLLECTOR_NUMBER, null);
|
||||||
} catch (NumberFormatException ex){ return null; }
|
} catch (NumberFormatException ex){ return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,22 +203,29 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
int setPos;
|
int setPos;
|
||||||
int artPos;
|
int artPos;
|
||||||
int cNrPos;
|
int cNrPos;
|
||||||
|
int clrPos;
|
||||||
if (info.length >= 4) { // name|set|artIndex|[collNr]
|
if (info.length >= 4) { // name|set|artIndex|[collNr]
|
||||||
setPos = isSetCode(info[1]) ? 1 : -1;
|
setPos = isSetCode(info[1]) ? 1 : -1;
|
||||||
artPos = isArtIndex(info[2]) ? 2 : -1;
|
artPos = isArtIndex(info[2]) ? 2 : -1;
|
||||||
cNrPos = isCollectorNumber(info[3]) ? 3 : -1;
|
cNrPos = isCollectorNumber(info[3]) ? 3 : -1;
|
||||||
|
int pos = cNrPos > 0 ? -1 : 3;
|
||||||
|
clrPos = pos > 0 ? isColorIDString(info[pos]) ? pos : -1 : -1;
|
||||||
} else if (info.length == 3) { // name|set|artIndex (or CollNr)
|
} else if (info.length == 3) { // name|set|artIndex (or CollNr)
|
||||||
setPos = isSetCode(info[1]) ? 1 : -1;
|
setPos = isSetCode(info[1]) ? 1 : -1;
|
||||||
artPos = isArtIndex(info[2]) ? 2 : -1;
|
artPos = isArtIndex(info[2]) ? 2 : -1;
|
||||||
cNrPos = isCollectorNumber(info[2]) ? 2 : -1;
|
cNrPos = isCollectorNumber(info[2]) ? 2 : -1;
|
||||||
|
int pos = cNrPos > 0 ? -1 : 2;
|
||||||
|
clrPos = pos > 0 ? isColorIDString(info[pos]) ? pos : -1 : -1;
|
||||||
} else if (info.length == 2) { // name|set (or artIndex, even if not possible via compose)
|
} else if (info.length == 2) { // name|set (or artIndex, even if not possible via compose)
|
||||||
setPos = isSetCode(info[1]) ? 1 : -1;
|
setPos = isSetCode(info[1]) ? 1 : -1;
|
||||||
artPos = isArtIndex(info[1]) ? 1 : -1;
|
artPos = isArtIndex(info[1]) ? 1 : -1;
|
||||||
cNrPos = -1;
|
cNrPos = -1;
|
||||||
|
clrPos = -1;
|
||||||
} else {
|
} else {
|
||||||
setPos = -1;
|
setPos = -1;
|
||||||
artPos = -1;
|
artPos = -1;
|
||||||
cNrPos = -1;
|
cNrPos = -1;
|
||||||
|
clrPos = -1;
|
||||||
}
|
}
|
||||||
String cardName = info[0];
|
String cardName = info[0];
|
||||||
boolean isFoil = false;
|
boolean isFoil = false;
|
||||||
@@ -210,6 +236,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
int artIndex = artPos > 0 ? Integer.parseInt(info[artPos]) : IPaperCard.NO_ART_INDEX; // default: no art index
|
int artIndex = artPos > 0 ? Integer.parseInt(info[artPos]) : IPaperCard.NO_ART_INDEX; // default: no art index
|
||||||
String collectorNumber = cNrPos > 0 ? info[cNrPos].substring(1, info[cNrPos].length() - 1) : IPaperCard.NO_COLLECTOR_NUMBER;
|
String collectorNumber = cNrPos > 0 ? info[cNrPos].substring(1, info[cNrPos].length() - 1) : IPaperCard.NO_COLLECTOR_NUMBER;
|
||||||
String setCode = setPos > 0 ? info[setPos] : null;
|
String setCode = setPos > 0 ? info[setPos] : null;
|
||||||
|
Set<String> colorID = clrPos > 0 ? Arrays.stream(info[clrPos].substring(1).split(colorIDPrefix)).collect(Collectors.toSet()) : null;
|
||||||
if (setCode != null && setCode.equals(CardEdition.UNKNOWN.getCode())) { // ???
|
if (setCode != null && setCode.equals(CardEdition.UNKNOWN.getCode())) { // ???
|
||||||
setCode = null;
|
setCode = null;
|
||||||
}
|
}
|
||||||
@@ -225,7 +252,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
// finally, check whether any between artIndex and CollectorNumber has been set
|
// finally, check whether any between artIndex and CollectorNumber has been set
|
||||||
if (collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER) && artIndex == IPaperCard.NO_ART_INDEX)
|
if (collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER) && artIndex == IPaperCard.NO_ART_INDEX)
|
||||||
artIndex = IPaperCard.DEFAULT_ART_INDEX;
|
artIndex = IPaperCard.DEFAULT_ART_INDEX;
|
||||||
return new CardRequest(cardName, setCode, artIndex, isFoil, collectorNumber);
|
return new CardRequest(cardName, setCode, artIndex, isFoil, collectorNumber, colorID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,6 +597,13 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
return tryGetCard(request);
|
return tryGetCard(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaperCard getCard(final String cardName, String setCode, int artIndex, Set<String> colorID) {
|
||||||
|
String reqInfo = CardRequest.compose(cardName, setCode, artIndex, colorID);
|
||||||
|
CardRequest request = CardRequest.fromString(reqInfo);
|
||||||
|
return tryGetCard(request);
|
||||||
|
}
|
||||||
|
|
||||||
private PaperCard tryGetCard(CardRequest request) {
|
private PaperCard tryGetCard(CardRequest request) {
|
||||||
// Before doing anything, check that a non-null request has been provided
|
// Before doing anything, check that a non-null request has been provided
|
||||||
if (request == null)
|
if (request == null)
|
||||||
@@ -581,8 +615,9 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
// MOST of the extensions have two short codes, 141 out of 221 (so far)
|
// MOST of the extensions have two short codes, 141 out of 221 (so far)
|
||||||
// ALSO: Set Code are always UpperCase
|
// ALSO: Set Code are always UpperCase
|
||||||
CardEdition edition = editions.get(reqEditionCode.toUpperCase());
|
CardEdition edition = editions.get(reqEditionCode.toUpperCase());
|
||||||
|
|
||||||
return this.getCardFromSet(request.cardName, edition, request.artIndex,
|
return this.getCardFromSet(request.cardName, edition, request.artIndex,
|
||||||
request.collectorNumber, request.isFoil);
|
request.collectorNumber, request.isFoil, request.colorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Card lookup in edition with specified filter didn't work.
|
// 2. Card lookup in edition with specified filter didn't work.
|
||||||
@@ -624,8 +659,12 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex,
|
public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil) {
|
||||||
String collectorNumber, boolean isFoil) {
|
return getCardFromSet(cardName, edition, artIndex, collectorNumber, isFoil, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, Set<String> colorID) {
|
||||||
if (edition == null || cardName == null) // preview cards
|
if (edition == null || cardName == null) // preview cards
|
||||||
return null; // No cards will be returned
|
return null; // No cards will be returned
|
||||||
|
|
||||||
@@ -659,7 +698,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
while (!candidate.hasImage() && candidatesIterator.hasNext())
|
while (!candidate.hasImage() && candidatesIterator.hasNext())
|
||||||
candidate = candidatesIterator.next();
|
candidate = candidatesIterator.next();
|
||||||
candidate = candidate.hasImage() ? candidate : firstCandidate;
|
candidate = candidate.hasImage() ? candidate : firstCandidate;
|
||||||
return isFoil ? candidate.getFoiled() : candidate;
|
return isFoil ? candidate.getFoiled().getColorIDVersion(colorID) : candidate.getColorIDVersion(colorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -702,6 +741,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, filter);
|
return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex, Set<String> colorID) {
|
||||||
|
return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, null, false, null, colorID);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ===============================================
|
* ===============================================
|
||||||
* 4. SPECIALISED CARD LOOKUP BASED ON
|
* 4. SPECIALISED CARD LOOKUP BASED ON
|
||||||
@@ -776,6 +820,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
|
|
||||||
private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex,
|
private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex,
|
||||||
Date releaseDate, boolean releasedBeforeFlag, Predicate<PaperCard> filter){
|
Date releaseDate, boolean releasedBeforeFlag, Predicate<PaperCard> filter){
|
||||||
|
return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex, releaseDate, releasedBeforeFlag, filter, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PaperCard tryToGetCardFromEditions(String cardInfo, CardArtPreference artPreference, int artIndex,
|
||||||
|
Date releaseDate, boolean releasedBeforeFlag, Predicate<PaperCard> filter, Set<String> colorID){
|
||||||
if (cardInfo == null)
|
if (cardInfo == null)
|
||||||
return null;
|
return null;
|
||||||
final CardRequest cr = CardRequest.fromString(cardInfo);
|
final CardRequest cr = CardRequest.fromString(cardInfo);
|
||||||
@@ -856,7 +905,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
candidate = candidate.hasImage() ? candidate : firstCandidate;
|
candidate = candidate.hasImage() ? candidate : firstCandidate;
|
||||||
//If any, we're sure that at least one candidate is always returned despite it having any image
|
//If any, we're sure that at least one candidate is always returned despite it having any image
|
||||||
return cr.isFoil ? candidate.getFoiled() : candidate;
|
return cr.isFoil ? candidate.getFoiled().getColorIDVersion(colorID) : candidate.getColorIDVersion(colorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1129,6 +1178,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
if (artCount >= IPaperCard.DEFAULT_ART_INDEX) {
|
if (artCount >= IPaperCard.DEFAULT_ART_INDEX) {
|
||||||
sb.append(CardDb.NameSetSeparator).append(card.getArtIndex()); // indexes start at 1 to match image file name conventions
|
sb.append(CardDb.NameSetSeparator).append(card.getArtIndex()); // indexes start at 1 to match image file name conventions
|
||||||
}
|
}
|
||||||
|
if (card.getColorID() != null) {
|
||||||
|
sb.append(CardDb.NameSetSeparator);
|
||||||
|
for (String color : card.getColorID())
|
||||||
|
sb.append(CardDb.colorIDPrefix).append(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb;
|
return sb;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
private String meldWith;
|
private String meldWith;
|
||||||
private String partnerWith;
|
private String partnerWith;
|
||||||
private boolean addsWildCardColor;
|
private boolean addsWildCardColor;
|
||||||
|
private int setColorID;
|
||||||
private boolean custom;
|
private boolean custom;
|
||||||
|
|
||||||
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) {
|
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) {
|
||||||
@@ -72,6 +73,8 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
meldWith = "";
|
meldWith = "";
|
||||||
partnerWith = "";
|
partnerWith = "";
|
||||||
addsWildCardColor = false;
|
addsWildCardColor = false;
|
||||||
|
setColorID = 0;
|
||||||
|
|
||||||
|
|
||||||
//calculate color identity
|
//calculate color identity
|
||||||
byte colMask = calculateColorIdentity(mainPart);
|
byte colMask = calculateColorIdentity(mainPart);
|
||||||
@@ -95,6 +98,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
meldWith = newRules.meldWith;
|
meldWith = newRules.meldWith;
|
||||||
partnerWith = newRules.partnerWith;
|
partnerWith = newRules.partnerWith;
|
||||||
addsWildCardColor = newRules.addsWildCardColor;
|
addsWildCardColor = newRules.addsWildCardColor;
|
||||||
|
setColorID = newRules.setColorID;
|
||||||
tokens = newRules.tokens;
|
tokens = newRules.tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,6 +401,10 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
return addsWildCardColor;
|
return addsWildCardColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSetColorID() {
|
||||||
|
return setColorID;
|
||||||
|
}
|
||||||
|
|
||||||
// vanguard card fields, they don't use sides.
|
// vanguard card fields, they don't use sides.
|
||||||
private int deltaHand;
|
private int deltaHand;
|
||||||
private int deltaLife;
|
private int deltaLife;
|
||||||
@@ -448,6 +456,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
private String meldWith = "";
|
private String meldWith = "";
|
||||||
private String partnerWith = "";
|
private String partnerWith = "";
|
||||||
private boolean addsWildCardColor = false;
|
private boolean addsWildCardColor = false;
|
||||||
|
private int setColorID = 0;
|
||||||
private String handLife = null;
|
private String handLife = null;
|
||||||
private String normalizedName = "";
|
private String normalizedName = "";
|
||||||
private Set<String> supportedFunctionalVariants = null;
|
private Set<String> supportedFunctionalVariants = null;
|
||||||
@@ -512,6 +521,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
result.meldWith = this.meldWith;
|
result.meldWith = this.meldWith;
|
||||||
result.partnerWith = this.partnerWith;
|
result.partnerWith = this.partnerWith;
|
||||||
result.addsWildCardColor = this.addsWildCardColor;
|
result.addsWildCardColor = this.addsWildCardColor;
|
||||||
|
result.setColorID = this.setColorID;
|
||||||
if (!tokens.isEmpty()) {
|
if (!tokens.isEmpty()) {
|
||||||
result.tokens = tokens;
|
result.tokens = tokens;
|
||||||
}
|
}
|
||||||
@@ -687,6 +697,8 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
value = colonPos > 0 ? value.substring(1+colonPos) : null;
|
value = colonPos > 0 ? value.substring(1+colonPos) : null;
|
||||||
|
|
||||||
face.addSVar(variable, value);
|
face.addSVar(variable, value);
|
||||||
|
} else if (key.startsWith("SETCOLORID")) {
|
||||||
|
this.setColorID = Integer.parseInt(value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import forge.item.PaperCard;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface ICardDatabase extends Iterable<PaperCard> {
|
public interface ICardDatabase extends Iterable<PaperCard> {
|
||||||
/**
|
/**
|
||||||
@@ -50,18 +51,21 @@ public interface ICardDatabase extends Iterable<PaperCard> {
|
|||||||
// [NEW Methods] Including the card CollectorNumber as criterion for DB lookup
|
// [NEW Methods] Including the card CollectorNumber as criterion for DB lookup
|
||||||
PaperCard getCard(String cardName, String edition, String collectorNumber);
|
PaperCard getCard(String cardName, String edition, String collectorNumber);
|
||||||
PaperCard getCard(String cardName, String edition, int artIndex, String collectorNumber);
|
PaperCard getCard(String cardName, String edition, int artIndex, String collectorNumber);
|
||||||
|
PaperCard getCard(String cardName, String edition, int artIndex, Set<String> colorID);
|
||||||
|
|
||||||
// 2. Card Lookup from a single Expansion Set
|
// 2. Card Lookup from a single Expansion Set
|
||||||
PaperCard getCardFromSet(String cardName, CardEdition edition, boolean isFoil); // NOT yet used, included for API symmetry
|
PaperCard getCardFromSet(String cardName, CardEdition edition, boolean isFoil); // NOT yet used, included for API symmetry
|
||||||
PaperCard getCardFromSet(String cardName, CardEdition edition, String collectorNumber, boolean isFoil);
|
PaperCard getCardFromSet(String cardName, CardEdition edition, String collectorNumber, boolean isFoil);
|
||||||
PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, boolean isFoil);
|
PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, boolean isFoil);
|
||||||
PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil);
|
PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil);
|
||||||
|
PaperCard getCardFromSet(String cardName, CardEdition edition, int artIndex, String collectorNumber, boolean isFoil, Set<String> colorID);
|
||||||
|
|
||||||
// 3. Card lookup based on CardArtPreference Selection Policy
|
// 3. Card lookup based on CardArtPreference Selection Policy
|
||||||
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference);
|
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference);
|
||||||
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, Predicate<PaperCard> filter);
|
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, Predicate<PaperCard> filter);
|
||||||
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex);
|
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex);
|
||||||
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Predicate<PaperCard> filter);
|
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Predicate<PaperCard> filter);
|
||||||
|
PaperCard getCardFromEditions(String cardName, CardArtPreference artPreference, int artIndex, Set<String> colorID);
|
||||||
|
|
||||||
// 4. Specialised Card Lookup on CardArtPreference Selection and Release Date
|
// 4. Specialised Card Lookup on CardArtPreference Selection and Release Date
|
||||||
PaperCard getCardFromEditionsReleasedBefore(String cardName, CardArtPreference artPreference, Date releaseDate);
|
PaperCard getCardFromEditionsReleasedBefore(String cardName, CardArtPreference artPreference, Date releaseDate);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class CardPool extends ItemPool<PaperCard> {
|
|||||||
|
|
||||||
public void add(final String cardRequest, final int amount) {
|
public void add(final String cardRequest, final int amount) {
|
||||||
CardDb.CardRequest request = CardDb.CardRequest.fromString(cardRequest);
|
CardDb.CardRequest request = CardDb.CardRequest.fromString(cardRequest);
|
||||||
this.add(CardDb.CardRequest.compose(request.cardName, request.isFoil), request.edition, request.artIndex, amount);
|
this.add(CardDb.CardRequest.compose(request.cardName, request.isFoil), request.edition, request.artIndex, amount, false, request.colorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(final String cardName, final String setCode) {
|
public void add(final String cardName, final String setCode) {
|
||||||
@@ -66,14 +66,14 @@ public class CardPool extends ItemPool<PaperCard> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void add(final String cardName, final String setCode, final int amount, boolean addAny) {
|
public void add(final String cardName, final String setCode, final int amount, boolean addAny) {
|
||||||
this.add(cardName, setCode, IPaperCard.NO_ART_INDEX, amount, addAny);
|
this.add(cardName, setCode, IPaperCard.NO_ART_INDEX, amount, addAny, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: ART indices are "1" -based
|
// NOTE: ART indices are "1" -based
|
||||||
public void add(String cardName, String setCode, int artIndex, final int amount) {
|
public void add(String cardName, String setCode, int artIndex, final int amount) {
|
||||||
this.add(cardName, setCode, artIndex, amount, false);
|
this.add(cardName, setCode, artIndex, amount, false, null);
|
||||||
}
|
}
|
||||||
public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny) {
|
public void add(String cardName, String setCode, int artIndex, final int amount, boolean addAny, Set<String> colorID) {
|
||||||
Map<String, CardDb> dbs = StaticData.instance().getAvailableDatabases();
|
Map<String, CardDb> dbs = StaticData.instance().getAvailableDatabases();
|
||||||
PaperCard paperCard = null;
|
PaperCard paperCard = null;
|
||||||
String selectedDbName = "";
|
String selectedDbName = "";
|
||||||
@@ -83,7 +83,7 @@ public class CardPool extends ItemPool<PaperCard> {
|
|||||||
for (Map.Entry<String, CardDb> entry: dbs.entrySet()){
|
for (Map.Entry<String, CardDb> entry: dbs.entrySet()){
|
||||||
String dbName = entry.getKey();
|
String dbName = entry.getKey();
|
||||||
CardDb db = entry.getValue();
|
CardDb db = entry.getValue();
|
||||||
paperCard = db.getCard(cardName, setCode, artIndex);
|
paperCard = db.getCard(cardName, setCode, artIndex, colorID);
|
||||||
if (paperCard != null) {
|
if (paperCard != null) {
|
||||||
selectedDbName = dbName;
|
selectedDbName = dbName;
|
||||||
break;
|
break;
|
||||||
@@ -125,7 +125,7 @@ public class CardPool extends ItemPool<PaperCard> {
|
|||||||
int cnt = artGroups[i - 1];
|
int cnt = artGroups[i - 1];
|
||||||
if (cnt <= 0)
|
if (cnt <= 0)
|
||||||
continue;
|
continue;
|
||||||
PaperCard randomCard = cardDb.getCard(cardName, setCode, i);
|
PaperCard randomCard = cardDb.getCard(cardName, setCode, i, colorID);
|
||||||
this.add(randomCard, cnt);
|
this.add(randomCard, cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ public class Deck extends DeckBase implements Iterable<Entry<DeckSection, CardPo
|
|||||||
int amount = entry.getValue();
|
int amount = entry.getValue();
|
||||||
String poolCardRequest = CardDb.CardRequest.compose(
|
String poolCardRequest = CardDb.CardRequest.compose(
|
||||||
card.isFoil() ? CardDb.CardRequest.compose(card.getName(), true) : card.getName(),
|
card.isFoil() ? CardDb.CardRequest.compose(card.getName(), true) : card.getName(),
|
||||||
card.getEdition(), card.getArtIndex());
|
card.getEdition(), card.getArtIndex(), card.getColorID());
|
||||||
String originalRequestCandidate = null;
|
String originalRequestCandidate = null;
|
||||||
for (Pair<String, Integer> originalRequest : originalCardRequests){
|
for (Pair<String, Integer> originalRequest : originalCardRequests){
|
||||||
String cardRequest = originalRequest.getLeft();
|
String cardRequest = originalRequest.getLeft();
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ public interface IPaperCard extends InventoryItem, Serializable {
|
|||||||
String getEdition();
|
String getEdition();
|
||||||
String getCollectorNumber();
|
String getCollectorNumber();
|
||||||
String getFunctionalVariant();
|
String getFunctionalVariant();
|
||||||
|
Set<String> getColorID();
|
||||||
int getArtIndex();
|
int getArtIndex();
|
||||||
boolean isFoil();
|
boolean isFoil();
|
||||||
boolean isToken();
|
boolean isToken();
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lightweight version of a card that matches real-world cards, to use outside of games (eg. inventory, decks, trade).
|
* A lightweight version of a card that matches real-world cards, to use outside of games (eg. inventory, decks, trade).
|
||||||
@@ -55,6 +57,7 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
private final boolean foil;
|
private final boolean foil;
|
||||||
private Boolean hasImage;
|
private Boolean hasImage;
|
||||||
private final boolean noSell;
|
private final boolean noSell;
|
||||||
|
private Set<String> colorID;
|
||||||
private String sortableName;
|
private String sortableName;
|
||||||
private final String functionalVariant;
|
private final String functionalVariant;
|
||||||
|
|
||||||
@@ -85,6 +88,11 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
return functionalVariant;
|
return functionalVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getColorID() {
|
||||||
|
return colorID;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getArtIndex() {
|
public int getArtIndex() {
|
||||||
return artIndex;
|
return artIndex;
|
||||||
@@ -156,7 +164,16 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false);
|
this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, false);
|
||||||
return sellable;
|
return sellable;
|
||||||
}
|
}
|
||||||
|
public PaperCard getColorIDVersion(Set<String> colors) {
|
||||||
|
if (colors == null && this.colorID == null)
|
||||||
|
return this;
|
||||||
|
if (this.colorID != null && this.colorID.equals(colors))
|
||||||
|
return this;
|
||||||
|
if (colors != null && colors.equals(this.colorID))
|
||||||
|
return this;
|
||||||
|
return new PaperCard(this.rules, this.edition, this.rarity,
|
||||||
|
this.artIndex, this.foil, String.valueOf(collectorNumber), this.artist, this.functionalVariant, this.noSell, colors);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public String getItemType() {
|
public String getItemType() {
|
||||||
final Localizer localizer = Localizer.getInstance();
|
final Localizer localizer = Localizer.getInstance();
|
||||||
@@ -190,6 +207,12 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
||||||
final int artIndex0, final boolean foil0, final String collectorNumber0,
|
final int artIndex0, final boolean foil0, final String collectorNumber0,
|
||||||
final String artist0, final String functionalVariant, final boolean noSell0) {
|
final String artist0, final String functionalVariant, final boolean noSell0) {
|
||||||
|
this(rules0, edition0, rarity0, artIndex0, foil0, collectorNumber0, artist0, functionalVariant, noSell0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
||||||
|
final int artIndex0, final boolean foil0, final String collectorNumber0,
|
||||||
|
final String artist0, final String functionalVariant, final boolean noSell0, final Set<String> colorID0) {
|
||||||
if (rules0 == null || edition0 == null || rarity0 == null) {
|
if (rules0 == null || edition0 == null || rarity0 == null) {
|
||||||
throw new IllegalArgumentException("Cannot create card without rules, edition or rarity");
|
throw new IllegalArgumentException("Cannot create card without rules, edition or rarity");
|
||||||
}
|
}
|
||||||
@@ -206,6 +229,7 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName()));
|
sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName()));
|
||||||
this.functionalVariant = functionalVariant != null ? functionalVariant : IPaperCard.NO_FUNCTIONAL_VARIANT;
|
this.functionalVariant = functionalVariant != null ? functionalVariant : IPaperCard.NO_FUNCTIONAL_VARIANT;
|
||||||
noSell = noSell0;
|
noSell = noSell0;
|
||||||
|
colorID = colorID0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaperCard FAKE_CARD = new PaperCard(CardRules.getUnsupportedCardNamed("Fake Card"), "Fake Edition", CardRarity.Common);
|
public static PaperCard FAKE_CARD = new PaperCard(CardRules.getUnsupportedCardNamed("Fake Card"), "Fake Edition", CardRarity.Common);
|
||||||
@@ -232,6 +256,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
}
|
}
|
||||||
if (!getCollectorNumber().equals(other.getCollectorNumber()))
|
if (!getCollectorNumber().equals(other.getCollectorNumber()))
|
||||||
return false;
|
return false;
|
||||||
|
// colorID can be NULL
|
||||||
|
if (getColorID() != other.getColorID())
|
||||||
|
return false;
|
||||||
return (other.foil == foil) && (other.artIndex == artIndex);
|
return (other.foil == foil) && (other.artIndex == artIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,10 +271,11 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int code = (name.hashCode() * 11) + (edition.hashCode() * 59) +
|
final int code = (name.hashCode() * 11) + (edition.hashCode() * 59) +
|
||||||
(artIndex * 2) + (getCollectorNumber().hashCode() * 383);
|
(artIndex * 2) + (getCollectorNumber().hashCode() * 383);
|
||||||
|
final int id = Optional.ofNullable(colorID).map(Set::hashCode).orElse(0);
|
||||||
if (foil) {
|
if (foil) {
|
||||||
return code + 1;
|
return code + id + 1;
|
||||||
}
|
}
|
||||||
return code;
|
return code + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Check
|
// FIXME: Check
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.item;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import forge.card.*;
|
import forge.card.*;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -152,6 +153,11 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard {
|
|||||||
return IPaperCard.NO_FUNCTIONAL_VARIANT;
|
return IPaperCard.NO_FUNCTIONAL_VARIANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getColorID() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getArtIndex() {
|
public int getArtIndex() {
|
||||||
return artIndex;
|
return artIndex;
|
||||||
|
|||||||
@@ -572,6 +572,10 @@ public class GameAction {
|
|||||||
game.getTriggerHandler().registerActiveTrigger(copied, false);
|
game.getTriggerHandler().registerActiveTrigger(copied, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c.hasChosenColorSpire()) {
|
||||||
|
copied.setChosenColorID(ImmutableSet.copyOf(c.getChosenColorID()));
|
||||||
|
}
|
||||||
|
|
||||||
// update state for view
|
// update state for view
|
||||||
copied.updateStateForView();
|
copied.updateStateForView();
|
||||||
|
|
||||||
@@ -2223,14 +2227,18 @@ public class GameAction {
|
|||||||
c.setChosenNumber(chosen);
|
c.setChosenNumber(chosen);
|
||||||
}
|
}
|
||||||
for (Card c : spires) {
|
for (Card c : spires) {
|
||||||
if (!c.hasChosenColor()) {
|
// TODO: only do this for the AI, for the player part, get the encoded color from the deck file and pass
|
||||||
|
// it to either player or the papercard object so it feels like rule based for the player side..
|
||||||
|
if (!c.hasChosenColorSpire()) {
|
||||||
|
if (takesAction.isAI()) {
|
||||||
List<String> colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS);
|
List<String> colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS);
|
||||||
String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " +
|
String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " +
|
||||||
Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2));
|
Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2));
|
||||||
SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction);
|
SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction);
|
||||||
sa.putParam("AILogic", "MostProminentInComputerDeck");
|
sa.putParam("AILogic", "MostProminentInComputerDeck");
|
||||||
List<String> chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices);
|
Set<String> chosenColors = new HashSet<>(takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices));
|
||||||
c.setChosenColors(chosenColors);
|
c.setChosenColorID(chosenColors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
takesAction = game.getNextPlayerAfter(takesAction);
|
takesAction = game.getNextPlayerAfter(takesAction);
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ public class CloneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("RememberCloneOrigin")) {
|
if (sa.hasParam("RememberCloneOrigin")) {
|
||||||
tgtCard.addRemembered(cardToCopy);
|
tgtCard.addRemembered(cardToCopy);
|
||||||
}
|
}
|
||||||
|
// spire
|
||||||
|
tgtCard.setChosenColorID(cardToCopy.getChosenColorID());
|
||||||
|
|
||||||
game.fireEvent(new GameEventCardStatsChanged(tgtCard));
|
game.fireEvent(new GameEventCardStatsChanged(tgtCard));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,8 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
|||||||
copy.setState(copy.getCurrentStateName(), true, true);
|
copy.setState(copy.getCurrentStateName(), true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// spire
|
||||||
|
copy.setChosenColorID(original.getChosenColorID());
|
||||||
|
|
||||||
copy.setTokenSpawningAbility(sa);
|
copy.setTokenSpawningAbility(sa);
|
||||||
copy.setGamePieceType(GamePieceType.TOKEN);
|
copy.setGamePieceType(GamePieceType.TOKEN);
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (choiceString.toString().isEmpty() && "Combo ColorIdentity".equals(abMana.getOrigProduced())) {
|
if (choiceString.toString().isEmpty() && ("Combo ColorIdentity".equals(abMana.getOrigProduced()) || "Combo Spire".equals(abMana.getOrigProduced()))) {
|
||||||
// No mana could be produced here (non-EDH match?), so cut short
|
// No mana could be produced here (non-EDH match?), so cut short
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,6 +293,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
private String chosenType2 = "";
|
private String chosenType2 = "";
|
||||||
private List<String> notedTypes = new ArrayList<>();
|
private List<String> notedTypes = new ArrayList<>();
|
||||||
private List<String> chosenColors;
|
private List<String> chosenColors;
|
||||||
|
private Set<String> chosenColorID;
|
||||||
private List<String> chosenName = new ArrayList<>();
|
private List<String> chosenName = new ArrayList<>();
|
||||||
private Integer chosenNumber;
|
private Integer chosenNumber;
|
||||||
private Player chosenPlayer;
|
private Player chosenPlayer;
|
||||||
@@ -399,6 +400,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
view.updateSickness(this);
|
view.updateSickness(this);
|
||||||
view.updateClassLevel(this);
|
view.updateClassLevel(this);
|
||||||
view.updateDraftAction(this);
|
view.updateDraftAction(this);
|
||||||
|
if (paperCard != null)
|
||||||
|
setChosenColorID(paperCard.getColorID());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean changeToState(final CardStateName state) {
|
public boolean changeToState(final CardStateName state) {
|
||||||
@@ -2118,7 +2121,19 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
|||||||
public boolean hasChosenColor(String s) {
|
public boolean hasChosenColor(String s) {
|
||||||
return chosenColors != null && chosenColors.contains(s);
|
return chosenColors != null && chosenColors.contains(s);
|
||||||
}
|
}
|
||||||
|
public final Set<String> getChosenColorID() {
|
||||||
|
if (chosenColorID == null) {
|
||||||
|
return Sets.newHashSet();
|
||||||
|
}
|
||||||
|
return chosenColorID;
|
||||||
|
}
|
||||||
|
public final void setChosenColorID(final Set<String> s) {
|
||||||
|
chosenColorID = s;
|
||||||
|
view.updateChosenColorID(this);
|
||||||
|
}
|
||||||
|
public boolean hasChosenColorSpire() {
|
||||||
|
return chosenColorID != null && !chosenColorID.isEmpty();
|
||||||
|
}
|
||||||
public final Card getChosenCard() {
|
public final Card getChosenCard() {
|
||||||
return getChosenCards().getFirst();
|
return getChosenCards().getFirst();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -433,7 +433,12 @@ public class CardView extends GameEntityView {
|
|||||||
void updateChosenColors(Card c) {
|
void updateChosenColors(Card c) {
|
||||||
set(TrackableProperty.ChosenColors, c.getChosenColors());
|
set(TrackableProperty.ChosenColors, c.getChosenColors());
|
||||||
}
|
}
|
||||||
|
public Set<String> getChosenColorID() {
|
||||||
|
return get(TrackableProperty.ChosenColorID);
|
||||||
|
}
|
||||||
|
void updateChosenColorID(Card c) {
|
||||||
|
set(TrackableProperty.ChosenColorID, c.getChosenColorID());
|
||||||
|
}
|
||||||
public FCollectionView<CardView> getMergedCardsCollection() {
|
public FCollectionView<CardView> getMergedCardsCollection() {
|
||||||
return get(TrackableProperty.MergedCardsCollection);
|
return get(TrackableProperty.MergedCardsCollection);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -654,6 +654,10 @@ public class AbilityManaPart implements java.io.Serializable {
|
|||||||
if (origProduced.contains("Chosen")) {
|
if (origProduced.contains("Chosen")) {
|
||||||
origProduced = origProduced.replace("Chosen", getChosenColor(sa));
|
origProduced = origProduced.replace("Chosen", getChosenColor(sa));
|
||||||
}
|
}
|
||||||
|
// replace Chosen for Spire colors
|
||||||
|
if (origProduced.contains("ColorID")) {
|
||||||
|
origProduced = origProduced.replace("ColorID", getChosenColorID(sa));
|
||||||
|
}
|
||||||
if (origProduced.contains("NotedColors")) {
|
if (origProduced.contains("NotedColors")) {
|
||||||
// Should only be used for Paliano, the High City
|
// Should only be used for Paliano, the High City
|
||||||
if (sa.getActivatingPlayer() == null) {
|
if (sa.getActivatingPlayer() == null) {
|
||||||
@@ -697,6 +701,21 @@ public class AbilityManaPart implements java.io.Serializable {
|
|||||||
return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1);
|
return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getChosenColorID(SpellAbility sa) {
|
||||||
|
if (sa == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
Card card = sa.getHostCard();
|
||||||
|
if (card != null && card.hasChosenColorSpire()) {
|
||||||
|
StringBuilder values = new StringBuilder();
|
||||||
|
for (String s : card.getChosenColorID()) {
|
||||||
|
values.append(MagicColor.toShortString(MagicColor.fromName(s))).append(" ");
|
||||||
|
}
|
||||||
|
return values.toString();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public String getChosenColor(SpellAbility sa) {
|
public String getChosenColor(SpellAbility sa) {
|
||||||
if (sa == null) {
|
if (sa == null) {
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public enum TrackableProperty {
|
|||||||
ChosenType2(TrackableTypes.StringType),
|
ChosenType2(TrackableTypes.StringType),
|
||||||
NotedTypes(TrackableTypes.StringListType),
|
NotedTypes(TrackableTypes.StringListType),
|
||||||
ChosenColors(TrackableTypes.StringListType),
|
ChosenColors(TrackableTypes.StringListType),
|
||||||
|
ChosenColorID(TrackableTypes.StringSetType),
|
||||||
ChosenCards(TrackableTypes.CardViewCollectionType),
|
ChosenCards(TrackableTypes.CardViewCollectionType),
|
||||||
ChosenNumber(TrackableTypes.StringType),
|
ChosenNumber(TrackableTypes.StringType),
|
||||||
StoredRolls(TrackableTypes.StringListType),
|
StoredRolls(TrackableTypes.StringListType),
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ package forge.screens.deckeditor.controllers;
|
|||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
@@ -30,6 +32,7 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.card.MagicColor;
|
||||||
import forge.deck.CardPool;
|
import forge.deck.CardPool;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.DeckBase;
|
import forge.deck.DeckBase;
|
||||||
@@ -65,6 +68,7 @@ import forge.toolbox.FLabel;
|
|||||||
import forge.toolbox.FSkin;
|
import forge.toolbox.FSkin;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
import forge.util.ItemPool;
|
import forge.util.ItemPool;
|
||||||
|
import forge.util.Lang;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.view.FView;
|
import forge.view.FView;
|
||||||
|
|
||||||
@@ -576,5 +580,23 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
|
|||||||
InputEvent.SHIFT_DOWN_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(),
|
InputEvent.SHIFT_DOWN_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(),
|
||||||
InputEvent.ALT_DOWN_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
|
InputEvent.ALT_DOWN_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
|
||||||
}
|
}
|
||||||
|
public void addSetColorID() {
|
||||||
|
String label = localizer.getMessage("lblColorIdentity");
|
||||||
|
CardManager cardManager = (CardManager) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckManager();
|
||||||
|
PaperCard existingCard = cardManager.getSelectedItem();
|
||||||
|
int val;
|
||||||
|
if ((val = existingCard.getRules().getSetColorID()) > 0) {
|
||||||
|
GuiUtils.addMenuItem(menu, label, null, () -> {
|
||||||
|
Set<String> colors = new HashSet<>(GuiChoose.getChoices(localizer.getMessage("lblChooseNColors", Lang.getNumeral(val)), val, val, MagicColor.Constant.ONLY_COLORS));
|
||||||
|
// make an updated version
|
||||||
|
PaperCard updated = existingCard.getColorIDVersion(colors);
|
||||||
|
// remove *quantity* instances of existing card
|
||||||
|
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1);
|
||||||
|
// add *quantity* into the deck and set them as selected
|
||||||
|
cardManager.addItem(updated, 1);
|
||||||
|
cardManager.setSelectedItem(updated);
|
||||||
|
}, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ public final class CEditorConstructed extends CDeckEditor<Deck> {
|
|||||||
if (foilAvailable) {
|
if (foilAvailable) {
|
||||||
cmb.addMakeFoils();
|
cmb.addMakeFoils();
|
||||||
}
|
}
|
||||||
|
cmb.addSetColorID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import forge.Forge.KeyInputAdapter;
|
|||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
import forge.assets.*;
|
import forge.assets.*;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
|
import forge.card.MagicColor;
|
||||||
import forge.deck.io.DeckPreferences;
|
import forge.deck.io.DeckPreferences;
|
||||||
import forge.gamemodes.limited.BoosterDraft;
|
import forge.gamemodes.limited.BoosterDraft;
|
||||||
import forge.gamemodes.planarconquest.ConquestUtil;
|
import forge.gamemodes.planarconquest.ConquestUtil;
|
||||||
@@ -1799,6 +1800,8 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
CardManagerPage cardSourceSection;
|
CardManagerPage cardSourceSection;
|
||||||
DeckSection destination = DeckSection.matchingSection(card);
|
DeckSection destination = DeckSection.matchingSection(card);
|
||||||
final DeckSectionPage destinationPage = parentScreen.getPageForSection(destination);
|
final DeckSectionPage destinationPage = parentScreen.getPageForSection(destination);
|
||||||
|
// val for colorID setup
|
||||||
|
int val;
|
||||||
switch (deckSection) {
|
switch (deckSection) {
|
||||||
default:
|
default:
|
||||||
case Main:
|
case Main:
|
||||||
@@ -1841,6 +1844,19 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addCommanderItems(menu, card);
|
addCommanderItems(menu, card);
|
||||||
|
if ((val = card.getRules().getSetColorID()) > 0) {
|
||||||
|
menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> {
|
||||||
|
//sort options so current option is on top and selected by default
|
||||||
|
Set<String> colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS);
|
||||||
|
GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(val)), val, val, colorChoices, new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public void run(List<String> result) {
|
||||||
|
addCard(card.getColorIDVersion(new HashSet<>(result)));
|
||||||
|
removeCard(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Sideboard:
|
case Sideboard:
|
||||||
cardSourceSection = parentScreen.isLimitedEditor() ? parentScreen.getMainDeckPage() : parentScreen.getCatalogPage();
|
cardSourceSection = parentScreen.isLimitedEditor() ? parentScreen.getMainDeckPage() : parentScreen.getCatalogPage();
|
||||||
@@ -1880,6 +1896,19 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
addCommanderItems(menu, card);
|
addCommanderItems(menu, card);
|
||||||
|
if ((val = card.getRules().getSetColorID()) > 0) {
|
||||||
|
menu.addItem(new FMenuItem(Forge.getLocalizer().getMessage("lblColorIdentity"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, e -> {
|
||||||
|
//sort options so current option is on top and selected by default
|
||||||
|
Set<String> colorChoices = new HashSet<>(MagicColor.Constant.ONLY_COLORS);
|
||||||
|
GuiChoose.getChoices(Forge.getLocalizer().getMessage("lblChooseAColor", Lang.getNumeral(val)), val, val, colorChoices, new Callback<>() {
|
||||||
|
@Override
|
||||||
|
public void run(List<String> result) {
|
||||||
|
addCard(card.getColorIDVersion(new HashSet<>(result)));
|
||||||
|
removeCard(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Commander:
|
case Commander:
|
||||||
if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) {
|
if (parentScreen.editorType != EditorType.PlanarConquest || isPartnerCommander(card)) {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
private static final float PADDING = Utils.scale(5);
|
private static final float PADDING = Utils.scale(5);
|
||||||
private static final float PILE_SPACING_Y = 0.1f;
|
private static final float PILE_SPACING_Y = 0.1f;
|
||||||
private static final FSkinFont LABEL_FONT = FSkinFont.get(12);
|
private static final FSkinFont LABEL_FONT = FSkinFont.get(12);
|
||||||
|
private TextRenderer textRenderer = new TextRenderer(true);
|
||||||
|
|
||||||
private static FSkinColor getGroupHeaderForeColor() {
|
private static FSkinColor getGroupHeaderForeColor() {
|
||||||
if (Forge.isMobileAdventureMode)
|
if (Forge.isMobileAdventureMode)
|
||||||
@@ -1029,6 +1030,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
private boolean selected, deckSelectMode, showRanking;
|
private boolean selected, deckSelectMode, showRanking;
|
||||||
private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE;
|
private final float IMAGE_SIZE = CardRenderer.MANA_SYMBOL_SIZE;
|
||||||
private DeckProxy deckProxy = null;
|
private DeckProxy deckProxy = null;
|
||||||
|
private StringBuffer colorID = new StringBuffer();
|
||||||
private FImageComplex deckCover = null;
|
private FImageComplex deckCover = null;
|
||||||
private Texture dpImg = null;
|
private Texture dpImg = null;
|
||||||
//private TextureRegion tr;
|
//private TextureRegion tr;
|
||||||
@@ -1055,6 +1057,20 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
draftRankImage = FSkinImage.DRAFTRANK_C;
|
draftRankImage = FSkinImage.DRAFTRANK_C;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (((PaperCard) item).getColorID() != null) {
|
||||||
|
for (String s : ((PaperCard) item).getColorID()) {
|
||||||
|
if ("white".equalsIgnoreCase(s))
|
||||||
|
colorID.append("{W}");
|
||||||
|
if ("green".equalsIgnoreCase(s))
|
||||||
|
colorID.append("{G}");
|
||||||
|
if ("red".equalsIgnoreCase(s))
|
||||||
|
colorID.append("{R}");
|
||||||
|
if ("blue".equalsIgnoreCase(s))
|
||||||
|
colorID.append("{U}");
|
||||||
|
if ("black".equalsIgnoreCase(s))
|
||||||
|
colorID.append("{B}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1136,6 +1152,10 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// spire colors
|
||||||
|
if (!colorID.isEmpty()) {
|
||||||
|
textRenderer.drawText(g, colorID.toString(), FSkinFont.forHeight(w / 5), Color.WHITE, x, y + h / 4, w, h, y, h, false, Align.center, true);
|
||||||
|
}
|
||||||
} else if (item instanceof ConquestCommander) {
|
} else if (item instanceof ConquestCommander) {
|
||||||
CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos);
|
CardRenderer.drawCard(g, ((ConquestCommander) item).getCard(), x, y, w, h, pos);
|
||||||
} else if (deckSelectMode) {
|
} else if (deckSelectMode) {
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ Types:Land
|
|||||||
Text:As you create your deck, circle two of the colors below.
|
Text:As you create your deck, circle two of the colors below.
|
||||||
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped.
|
R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplacementResult$ Updated | ReplaceWith$ ETBTapped | Description$ CARDNAME enters tapped.
|
||||||
SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True
|
SVar:ETBTapped:DB$ Tap | Defined$ Self | ETB$ True
|
||||||
A:AB$ Mana | Cost$ T | Produced$ Combo Chosen | SpellDescription$ Add one mana of either of the circled colors.
|
A:AB$ Mana | Cost$ T | Produced$ Combo ColorID | SpellDescription$ Add one mana of either of the circled colors.
|
||||||
Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters tapped.\n{T}: Add one mana of either of the circled colors.
|
Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters tapped.\n{T}: Add one mana of either of the circled colors.
|
||||||
|
SETCOLORID:2
|
||||||
|
|||||||
@@ -487,6 +487,16 @@ public class CardDetailUtil {
|
|||||||
area.append(")");
|
area.append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chosen spire
|
||||||
|
if (card.getChosenColorID() != null && !card.getChosenColorID().isEmpty()) {
|
||||||
|
if (area.length() != 0) {
|
||||||
|
area.append("\n");
|
||||||
|
}
|
||||||
|
area.append("(").append(Localizer.getInstance().getMessage("lblSelected")).append(": ");
|
||||||
|
area.append(Lang.joinHomogenous(card.getChosenColorID().stream().map(DeckRecognizer::getLocalisedMagicColorName).collect(Collectors.toList())));
|
||||||
|
area.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
// chosen color
|
// chosen color
|
||||||
if (card.getChosenColors() != null && !card.getChosenColors().isEmpty()) {
|
if (card.getChosenColors() != null && !card.getChosenColors().isEmpty()) {
|
||||||
if (area.length() != 0) {
|
if (area.length() != 0) {
|
||||||
|
|||||||
@@ -57,8 +57,9 @@ public enum ColumnDef {
|
|||||||
NAME("lblName", "lblName", 180, false, SortState.ASC,
|
NAME("lblName", "lblName", 180, false, SortState.ASC,
|
||||||
from -> {
|
from -> {
|
||||||
if (from.getKey() instanceof PaperCard) {
|
if (from.getKey() instanceof PaperCard) {
|
||||||
|
String spire = ((PaperCard) from.getKey()).getColorID() == null ? "" : ((PaperCard) from.getKey()).getColorID().toString();
|
||||||
String sortableName = ((PaperCard)from.getKey()).getSortableName();
|
String sortableName = ((PaperCard)from.getKey()).getSortableName();
|
||||||
return sortableName == null ? TextUtil.toSortableName(from.getKey().getName()) : sortableName;
|
return sortableName == null ? TextUtil.toSortableName(from.getKey().getName() + spire) : sortableName + spire;
|
||||||
}
|
}
|
||||||
return TextUtil.toSortableName(from.getKey().getName());
|
return TextUtil.toSortableName(from.getKey().getName());
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user