Compare commits

...

2 Commits

Author SHA1 Message Date
Hans Mackowiak
f14454e992 fix Tests for now 2025-06-01 23:21:49 +02:00
Hans Mackowiak
e4799a4f73 ImageKeys: unify PaperCard imageKeys 2025-06-01 23:09:27 +02:00
20 changed files with 331 additions and 364 deletions

View File

@@ -33,11 +33,6 @@ public final class ImageKeys {
public static final String RADIATION_IMAGE = "radiation"; public static final String RADIATION_IMAGE = "radiation";
public static final String BACKFACE_POSTFIX = "$alt"; public static final String BACKFACE_POSTFIX = "$alt";
public static final String SPECFACE_W = "$wspec";
public static final String SPECFACE_U = "$uspec";
public static final String SPECFACE_B = "$bspec";
public static final String SPECFACE_R = "$rspec";
public static final String SPECFACE_G = "$gspec";
private static String CACHE_CARD_PICS_DIR, CACHE_TOKEN_PICS_DIR, CACHE_ICON_PICS_DIR, CACHE_BOOSTER_PICS_DIR, private static String CACHE_CARD_PICS_DIR, CACHE_TOKEN_PICS_DIR, CACHE_ICON_PICS_DIR, CACHE_BOOSTER_PICS_DIR,
CACHE_FATPACK_PICS_DIR, CACHE_BOOSTERBOX_PICS_DIR, CACHE_PRECON_PICS_DIR, CACHE_TOURNAMENTPACK_PICS_DIR; CACHE_FATPACK_PICS_DIR, CACHE_BOOSTERBOX_PICS_DIR, CACHE_PRECON_PICS_DIR, CACHE_TOURNAMENTPACK_PICS_DIR;
@@ -97,13 +92,28 @@ public final class ImageKeys {
return cachedCards.get(key); return cachedCards.get(key);
} }
public static File getImageFile(String key) { public static File getImageFile(String key) {
return getImageFile(key, false);
}
public static File getImageFile(String key, boolean artCrop) {
if (StringUtils.isEmpty(key)) if (StringUtils.isEmpty(key))
return null; return null;
final String dir; final String dir;
final String filename; final String filename;
String[] tempdata = null; String[] tempdata = null;
if (key.startsWith(ImageKeys.TOKEN_PREFIX)) { if (key.startsWith(ImageKeys.CARD_PREFIX)) {
tempdata = key.substring(ImageKeys.CARD_PREFIX.length()).split("\\|");
String tokenname = tempdata[0];
if (tempdata.length > 1) {
tokenname += "_" + tempdata[1];
}
if (tempdata.length > 2) {
tokenname += "_" + tempdata[2];
}
filename = tokenname ;
dir = CACHE_CARD_PICS_DIR;
} else if (key.startsWith(ImageKeys.TOKEN_PREFIX)) {
tempdata = key.substring(ImageKeys.TOKEN_PREFIX.length()).split("\\|"); tempdata = key.substring(ImageKeys.TOKEN_PREFIX.length()).split("\\|");
String tokenname = tempdata[0]; String tokenname = tempdata[0];
if (tempdata.length > 1) { if (tempdata.length > 1) {
@@ -154,7 +164,31 @@ public final class ImageKeys {
cachedCards.put(filename, file); cachedCards.put(filename, file);
return file; return file;
} }
if (dir.equals(CACHE_TOKEN_PICS_DIR)) { if (tempdata != null && dir.equals(CACHE_CARD_PICS_DIR)) {
String setlessFilename = tempdata[0] + (artCrop ? ".artcrop" : ".fullborder");
String setCode = tempdata.length > 1 ? tempdata[1] : "";
String collectorNumber = tempdata.length > 2 ? tempdata[2] : "";
if (!setCode.isEmpty()) {
if (!collectorNumber.isEmpty()) {
file = findFile(dir, setCode + "/" + collectorNumber + "_" + setlessFilename);
if (file != null) {
cachedCards.put(filename, file);
return file;
}
}
file = findFile(dir, setCode + "/" + setlessFilename);
if (file != null) {
cachedCards.put(filename, file);
return file;
}
}
file = findFile(dir, setlessFilename);
if (file != null) {
cachedCards.put(filename, file);
return file;
}
}
if (tempdata != null && dir.equals(CACHE_TOKEN_PICS_DIR)) {
String setlessFilename = tempdata[0]; String setlessFilename = tempdata[0];
String setCode = tempdata.length > 1 ? tempdata[1] : ""; String setCode = tempdata.length > 1 ? tempdata[1] : "";
String collectorNumber = tempdata.length > 2 ? tempdata[2] : ""; String collectorNumber = tempdata.length > 2 ? tempdata[2] : "";

View File

@@ -433,6 +433,17 @@ public final class CardEdition implements Comparable<CardEdition> {
public Multimap<String, EditionEntry> getTokens() { return tokenMap; } public Multimap<String, EditionEntry> getTokens() { return tokenMap; }
public EditionEntry getTokenFromCollectorNumber(String collectorNumber) {
if(collectorNumber == null || collectorNumber.isEmpty())
return null;
for(EditionEntry c : this.tokenMap.values()) {
//Could build a map for this one too if it's used for more than one-offs.
if (c.collectorNumber.equalsIgnoreCase(collectorNumber))
return c;
}
return null;
}
public String getTokenSet(String token) { public String getTokenSet(String token) {
if (tokenMap.containsKey(token)) { if (tokenMap.containsKey(token)) {
return this.getCode(); return this.getCode();

View File

@@ -20,6 +20,8 @@ package forge.card;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import forge.StaticData;
import forge.card.mana.IParserManaCost; import forge.card.mana.IParserManaCost;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
@@ -149,6 +151,10 @@ public final class CardRules implements ICardCharacteristics {
return splitType; return splitType;
} }
public boolean hasBackSide() {
return CardSplitType.DUAL_FACED_CARDS.contains(splitType) || splitType == CardSplitType.Flip;
}
public ICardFace getMainPart() { public ICardFace getMainPart() {
return mainPart; return mainPart;
} }
@@ -165,20 +171,32 @@ public final class CardRules implements ICardCharacteristics {
return Iterables.concat(Arrays.asList(mainPart, otherPart), specializedParts.values()); return Iterables.concat(Arrays.asList(mainPart, otherPart), specializedParts.values());
} }
public ICardFace getWSpecialize() { public String getImageName(CardStateName state) {
return specializedParts.get(CardStateName.SpecializeW); if (splitType == CardSplitType.Split) {
} return mainPart.getName() + otherPart.getName();
public ICardFace getUSpecialize() { } else if (state.equals(splitType.getChangedStateName())) {
return specializedParts.get(CardStateName.SpecializeU); if (otherPart != null) {
} return otherPart.getName();
public ICardFace getBSpecialize() { } else if (this.hasBackSide()) {
return specializedParts.get(CardStateName.SpecializeB); if (!getMeldWith().isEmpty()) {
} final CardDb db = StaticData.instance().getCommonCards();
public ICardFace getRSpecialize() { return db.getRules(getMeldWith()).getOtherPart().getName();
return specializedParts.get(CardStateName.SpecializeR); }
} return null;
public ICardFace getGSpecialize() { }
return specializedParts.get(CardStateName.SpecializeG); }
switch (state) {
case SpecializeW:
case SpecializeU:
case SpecializeB:
case SpecializeR:
case SpecializeG:
ICardFace face = specializedParts.get(state);
return face != null ? face.getName() : null;
default:
return getName();
}
} }
public String getName() { public String getName() {

View File

@@ -24,7 +24,6 @@ import forge.util.CardTranslation;
import forge.util.ImageUtil; import forge.util.ImageUtil;
import forge.util.Localizer; import forge.util.Localizer;
import forge.util.TextUtil; import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
@@ -364,20 +363,14 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
@Override @Override
public String getImageKey(boolean altState) { public String getImageKey(boolean altState) {
String normalizedName = StringUtils.stripAccents(name); return altState ? this.getCardAltImageKey() : this.getCardImageKey();
String imageKey = ImageKeys.CARD_PREFIX + normalizedName + CardDb.NameSetSeparator
+ edition + CardDb.NameSetSeparator + artIndex;
if (altState) {
imageKey += ImageKeys.BACKFACE_POSTFIX;
}
return imageKey;
} }
private String cardImageKey = null; private String cardImageKey = null;
@Override @Override
public String getCardImageKey() { public String getCardImageKey() {
if (this.cardImageKey == null) if (this.cardImageKey == null)
this.cardImageKey = ImageUtil.getImageKey(this, "", true); this.cardImageKey = ImageUtil.getImageKey(this, CardStateName.Original);
return cardImageKey; return cardImageKey;
} }
@@ -386,9 +379,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardAltImageKey() { public String getCardAltImageKey() {
if (this.cardAltImageKey == null){ if (this.cardAltImageKey == null){
if (this.hasBackFace()) if (this.hasBackFace())
this.cardAltImageKey = ImageUtil.getImageKey(this, "back", true); this.cardAltImageKey = ImageUtil.getImageKey(this, this.getRules().getSplitType().getChangedStateName());
else // altImageKey will be the same as cardImageKey else // altImageKey will be the same as cardImageKey
this.cardAltImageKey = ImageUtil.getImageKey(this, "", true); this.cardAltImageKey = getCardImageKey();
} }
return cardAltImageKey; return cardAltImageKey;
} }
@@ -398,9 +391,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardWSpecImageKey() { public String getCardWSpecImageKey() {
if (this.cardWSpecImageKey == null) { if (this.cardWSpecImageKey == null) {
if (this.rules.getSplitType() == CardSplitType.Specialize) if (this.rules.getSplitType() == CardSplitType.Specialize)
this.cardWSpecImageKey = ImageUtil.getImageKey(this, "white", true); this.cardWSpecImageKey = ImageUtil.getImageKey(this, CardStateName.SpecializeW);
else // just use cardImageKey else // just use cardImageKey
this.cardWSpecImageKey = ImageUtil.getImageKey(this, "", true); this.cardWSpecImageKey = getCardImageKey();
} }
return cardWSpecImageKey; return cardWSpecImageKey;
} }
@@ -410,9 +403,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardUSpecImageKey() { public String getCardUSpecImageKey() {
if (this.cardUSpecImageKey == null) { if (this.cardUSpecImageKey == null) {
if (this.rules.getSplitType() == CardSplitType.Specialize) if (this.rules.getSplitType() == CardSplitType.Specialize)
this.cardUSpecImageKey = ImageUtil.getImageKey(this, "blue", true); this.cardUSpecImageKey = ImageUtil.getImageKey(this, CardStateName.SpecializeU);
else // just use cardImageKey else // just use cardImageKey
this.cardUSpecImageKey = ImageUtil.getImageKey(this, "", true); this.cardUSpecImageKey = getCardImageKey();
} }
return cardUSpecImageKey; return cardUSpecImageKey;
} }
@@ -422,9 +415,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardBSpecImageKey() { public String getCardBSpecImageKey() {
if (this.cardBSpecImageKey == null) { if (this.cardBSpecImageKey == null) {
if (this.rules.getSplitType() == CardSplitType.Specialize) if (this.rules.getSplitType() == CardSplitType.Specialize)
this.cardBSpecImageKey = ImageUtil.getImageKey(this, "black", true); this.cardBSpecImageKey = ImageUtil.getImageKey(this, CardStateName.SpecializeB);
else // just use cardImageKey else // just use cardImageKey
this.cardBSpecImageKey = ImageUtil.getImageKey(this, "", true); this.cardBSpecImageKey = getCardImageKey();
} }
return cardBSpecImageKey; return cardBSpecImageKey;
} }
@@ -434,9 +427,9 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardRSpecImageKey() { public String getCardRSpecImageKey() {
if (this.cardRSpecImageKey == null) { if (this.cardRSpecImageKey == null) {
if (this.rules.getSplitType() == CardSplitType.Specialize) if (this.rules.getSplitType() == CardSplitType.Specialize)
this.cardRSpecImageKey = ImageUtil.getImageKey(this, "red", true); this.cardRSpecImageKey = ImageUtil.getImageKey(this, CardStateName.SpecializeR);
else // just use cardImageKey else // just use cardImageKey
this.cardRSpecImageKey = ImageUtil.getImageKey(this, "", true); this.cardRSpecImageKey = getCardImageKey();
} }
return cardRSpecImageKey; return cardRSpecImageKey;
} }
@@ -446,18 +439,16 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public String getCardGSpecImageKey() { public String getCardGSpecImageKey() {
if (this.cardGSpecImageKey == null) { if (this.cardGSpecImageKey == null) {
if (this.rules.getSplitType() == CardSplitType.Specialize) if (this.rules.getSplitType() == CardSplitType.Specialize)
this.cardGSpecImageKey = ImageUtil.getImageKey(this, "green", true); this.cardGSpecImageKey = ImageUtil.getImageKey(this, CardStateName.SpecializeG);
else // just use cardImageKey else // just use cardImageKey
this.cardGSpecImageKey = ImageUtil.getImageKey(this, "", true); this.cardGSpecImageKey = getCardImageKey();
} }
return cardGSpecImageKey; return cardGSpecImageKey;
} }
@Override @Override
public boolean hasBackFace(){ public boolean hasBackFace(){
CardSplitType cst = this.rules.getSplitType(); return this.rules.hasBackSide();
return cst == CardSplitType.Transform || cst == CardSplitType.Flip || cst == CardSplitType.Meld
|| cst == CardSplitType.Modal;
} }
@Override @Override

View File

@@ -5,6 +5,7 @@ import forge.StaticData;
import forge.card.CardDb; import forge.card.CardDb;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardSplitType; import forge.card.CardSplitType;
import forge.card.CardStateName;
import forge.item.IPaperCard; import forge.item.IPaperCard;
import forge.item.PaperCard; import forge.item.PaperCard;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -24,20 +25,17 @@ public class ImageUtil {
key = imageKey.substring(ImageKeys.CARD_PREFIX.length()); key = imageKey.substring(ImageKeys.CARD_PREFIX.length());
else else
return null; return null;
if (key.endsWith(ImageKeys.BACKFACE_POSTFIX)) {
key = key.substring(0, key.length() - ImageKeys.BACKFACE_POSTFIX.length());
}
if (key.isEmpty()) if (key.isEmpty())
return null; return null;
CardDb db = StaticData.instance().getCommonCards(); String[] tempdata = key.split("\\|");
PaperCard cp = null; PaperCard cp = StaticData.instance().fetchCard(tempdata[0], tempdata[1], tempdata[2]);
//db shouldn't be null
if (db != null) {
cp = db.getCard(key);
if (cp == null) {
db = StaticData.instance().getVariantCards();
if (db != null)
cp = db.getCard(key);
}
}
if (cp == null) if (cp == null)
System.err.println("Can't find PaperCard from key: " + key); System.err.println("Can't find PaperCard from key: " + key);
// return cp regardless if it's null // return cp regardless if it's null
@@ -54,6 +52,21 @@ public class ImageUtil {
return key; return key;
} }
public static String getImageRelativePath(String name, String set, String collectorNumber, boolean artChop) {
StringBuilder sb = new StringBuilder();
sb.append(set).append("/");
if (!collectorNumber.isEmpty() && !collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
sb.append(collectorNumber).append("_");
}
sb.append(StringUtils.stripAccents(name));
sb.append(artChop ? ".artcrop" : ".fullborder");
sb.append(".jpg");
return sb.toString();
}
public static String getImageRelativePath(PaperCard cp, String face, boolean includeSet, boolean isDownloadUrl) { public static String getImageRelativePath(PaperCard cp, String face, boolean includeSet, boolean isDownloadUrl) {
final String nameToUse = cp == null ? null : getNameToUse(cp, face); final String nameToUse = cp == null ? null : getNameToUse(cp, face);
if (nameToUse == null) { if (nameToUse == null) {
@@ -123,25 +136,15 @@ public class ImageUtil {
else else
return null; return null;
} else if (face.equals("white")) { } else if (face.equals("white")) {
if (card.getWSpecialize() != null) { return card.getImageName(CardStateName.SpecializeW);
return card.getWSpecialize().getName();
}
} else if (face.equals("blue")) { } else if (face.equals("blue")) {
if (card.getUSpecialize() != null) { return card.getImageName(CardStateName.SpecializeU);
return card.getUSpecialize().getName();
}
} else if (face.equals("black")) { } else if (face.equals("black")) {
if (card.getBSpecialize() != null) { return card.getImageName(CardStateName.SpecializeB);
return card.getBSpecialize().getName();
}
} else if (face.equals("red")) { } else if (face.equals("red")) {
if (card.getRSpecialize() != null) { return card.getImageName(CardStateName.SpecializeR);
return card.getRSpecialize().getName();
}
} else if (face.equals("green")) { } else if (face.equals("green")) {
if (card.getGSpecialize() != null) { return card.getImageName(CardStateName.SpecializeG);
return card.getGSpecialize().getName();
}
} else if (CardSplitType.Split == cp.getRules().getSplitType()) { } else if (CardSplitType.Split == cp.getRules().getSplitType()) {
return card.getMainPart().getName() + card.getOtherPart().getName(); return card.getMainPart().getName() + card.getOtherPart().getName();
} else if (!IPaperCard.NO_FUNCTIONAL_VARIANT.equals(cp.getFunctionalVariant())) { } else if (!IPaperCard.NO_FUNCTIONAL_VARIANT.equals(cp.getFunctionalVariant())) {
@@ -150,50 +153,86 @@ public class ImageUtil {
return cp.getName(); return cp.getName();
} }
public static String getNameToUse(PaperCard cp, CardStateName face) {
if (!IPaperCard.NO_FUNCTIONAL_VARIANT.equals(cp.getFunctionalVariant())) {
return cp.getFunctionalVariant();
}
final CardRules card = cp.getRules();
return card.getImageName(face);
}
public static String getImageKey(PaperCard cp, String face, boolean includeSet) { public static String getImageKey(PaperCard cp, String face, boolean includeSet) {
return getImageRelativePath(cp, face, includeSet, false); return getImageRelativePath(cp, face, includeSet, false);
} }
public static String getImageKey(PaperCard cp, CardStateName face) {
String name = getNameToUse(cp, face);
String number = cp.getCollectorNumber();
String suffix = "";
switch (face) {
case SpecializeB:
number += "b";
break;
case SpecializeG:
number += "g";
break;
case SpecializeR:
number += "r";
break;
case SpecializeU:
number += "u";
break;
case SpecializeW:
number += "w";
break;
case Meld:
case Modal:
case Secondary:
case Transformed:
suffix = ImageKeys.BACKFACE_POSTFIX;
break;
case Flipped:
break; // add info to rotate the image?
default:
break;
};
return ImageKeys.CARD_PREFIX + name + CardDb.NameSetSeparator + cp.getEdition()
+ CardDb.NameSetSeparator + number + CardDb.NameSetSeparator + cp.getArtIndex() + suffix;
}
public static String getDownloadUrl(PaperCard cp, String face) { public static String getDownloadUrl(PaperCard cp, String face) {
return getImageRelativePath(cp, face, true, true); return getImageRelativePath(cp, face, true, true);
} }
public static String getScryfallDownloadUrl(PaperCard cp, String face, String setCode, String langCode, boolean useArtCrop){ public static String getScryfallDownloadUrl(String collectorNumber, String setCode, String langCode, String faceParam, boolean useArtCrop){
return getScryfallDownloadUrl(cp, face, setCode, langCode, useArtCrop, false); return getScryfallDownloadUrl(collectorNumber, setCode, langCode, faceParam, useArtCrop, false);
} }
public static String getScryfallDownloadUrl(PaperCard cp, String face, String setCode, String langCode, boolean useArtCrop, boolean hyphenateAlchemy){ public static String getScryfallDownloadUrl(String collectorNumber, String setCode, String langCode, String faceParam, boolean useArtCrop, boolean hyphenateAlchemy){
String editionCode;
if ((setCode != null) && (setCode.length() > 0))
editionCode = setCode;
else
editionCode = cp.getEdition().toLowerCase();
String cardCollectorNumber = cp.getCollectorNumber();
// Hack to account for variations in Arabian Nights // Hack to account for variations in Arabian Nights
cardCollectorNumber = cardCollectorNumber.replace("+", ""); collectorNumber = collectorNumber.replace("+", "");
// override old planechase sets from their modified id since scryfall move the planechase cards outside their original setcode // override old planechase sets from their modified id since scryfall move the planechase cards outside their original setcode
if (cardCollectorNumber.startsWith("OHOP")) { if (collectorNumber.startsWith("OHOP")) {
editionCode = "ohop"; setCode = "ohop";
cardCollectorNumber = cardCollectorNumber.substring("OHOP".length()); collectorNumber = collectorNumber.substring("OHOP".length());
} else if (cardCollectorNumber.startsWith("OPCA")) { } else if (collectorNumber.startsWith("OPCA")) {
editionCode = "opca"; setCode = "opca";
cardCollectorNumber = cardCollectorNumber.substring("OPCA".length()); collectorNumber = collectorNumber.substring("OPCA".length());
} else if (cardCollectorNumber.startsWith("OPC2")) { } else if (collectorNumber.startsWith("OPC2")) {
editionCode = "opc2"; setCode = "opc2";
cardCollectorNumber = cardCollectorNumber.substring("OPC2".length()); collectorNumber = collectorNumber.substring("OPC2".length());
} else if (hyphenateAlchemy) { } else if (hyphenateAlchemy) {
if (!cardCollectorNumber.startsWith("A")) { if (!collectorNumber.startsWith("A")) {
return null; return null;
} }
cardCollectorNumber = cardCollectorNumber.replace("A", "A-"); collectorNumber = collectorNumber.replace("A", "A-");
} }
String versionParam = useArtCrop ? "art_crop" : "normal"; String versionParam = useArtCrop ? "art_crop" : "normal";
String faceParam = ""; if (!faceParam.isEmpty()) {
if (cp.getRules().getOtherPart() != null) { faceParam = (faceParam.equals("back") ? "&face=back" : "&face=front");
faceParam = (face.equals("back") ? "&face=back" : "&face=front");
} }
return String.format("%s/%s/%s?format=image&version=%s%s", editionCode, cardCollectorNumber, return String.format("%s/%s/%s?format=image&version=%s%s", setCode, collectorNumber,
langCode, versionParam, faceParam); langCode, versionParam, faceParam);
} }

View File

@@ -6515,29 +6515,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
if(uiCard != null) if(uiCard != null)
uiCard.currentState.setImageKey(iFN); uiCard.currentState.setImageKey(iFN);
} }
public final void setImageKey(final IPaperCard ipc, final CardStateName stateName) {
if (ipc == null)
return;
switch (stateName) {
case SpecializeB:
setImageKey(ipc.getCardBSpecImageKey());
break;
case SpecializeR:
setImageKey(ipc.getCardRSpecImageKey());
break;
case SpecializeG:
setImageKey(ipc.getCardGSpecImageKey());
break;
case SpecializeU:
setImageKey(ipc.getCardUSpecImageKey());
break;
case SpecializeW:
setImageKey(ipc.getCardWSpecImageKey());
break;
default:
break;
}
}
public String getImageKey(CardStateName state) { public String getImageKey(CardStateName state) {
if (!getRenderForUI()) { if (!getRenderForUI()) {
@@ -6837,7 +6814,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
} }
public final void setSpecialized(final boolean bool) { public final void setSpecialized(final boolean bool) {
specialized = bool; specialized = bool;
setImageKey(getPaperCard(), getCurrentStateName());
} }
public final boolean canSpecialize() { public final boolean canSpecialize() {
return getRules() != null && getRules().getSplitType() == CardSplitType.Specialize; return getRules() != null && getRules().getSplitType() == CardSplitType.Specialize;

View File

@@ -187,7 +187,7 @@ public class CardFactory {
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
// Would like to move this away from in-game entities // Would like to move this away from in-game entities
String originalPicture = cp.getImageKey(false); String originalPicture = cp.getCardImageKey();
c.setImageKey(originalPicture); c.setImageKey(originalPicture);
if(cp.isToken()) if(cp.isToken())
@@ -198,11 +198,11 @@ public class CardFactory {
if (c.hasAlternateState()) { if (c.hasAlternateState()) {
if (c.isFlipCard()) { if (c.isFlipCard()) {
c.setState(CardStateName.Flipped, false); c.setState(CardStateName.Flipped, false);
c.setImageKey(cp.getImageKey(true)); c.setImageKey(cp.getCardAltImageKey());
} }
else if (c.isDoubleFaced() && cardRules != null) { else if (c.isDoubleFaced() && cardRules != null) {
c.setState(cardRules.getSplitType().getChangedStateName(), false); c.setState(cardRules.getSplitType().getChangedStateName(), false);
c.setImageKey(cp.getImageKey(true)); c.setImageKey(cp.getCardAltImageKey());
} }
else if (c.isSplitCard()) { else if (c.isSplitCard()) {
c.setState(CardStateName.LeftSplit, false); c.setState(CardStateName.LeftSplit, false);
@@ -216,23 +216,23 @@ public class CardFactory {
c.setImageKey(originalPicture); c.setImageKey(originalPicture);
} else if (c.canSpecialize()) { } else if (c.canSpecialize()) {
c.setState(CardStateName.SpecializeW, false); c.setState(CardStateName.SpecializeW, false);
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_W); c.setImageKey(cp.getCardWSpecImageKey());
c.setSetCode(cp.getEdition()); c.setSetCode(cp.getEdition());
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
c.setState(CardStateName.SpecializeU, false); c.setState(CardStateName.SpecializeU, false);
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_U); c.setImageKey(cp.getCardUSpecImageKey());
c.setSetCode(cp.getEdition()); c.setSetCode(cp.getEdition());
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
c.setState(CardStateName.SpecializeB, false); c.setState(CardStateName.SpecializeB, false);
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_B); c.setImageKey(cp.getCardBSpecImageKey());
c.setSetCode(cp.getEdition()); c.setSetCode(cp.getEdition());
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
c.setState(CardStateName.SpecializeR, false); c.setState(CardStateName.SpecializeR, false);
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_R); c.setImageKey(cp.getCardRSpecImageKey());
c.setSetCode(cp.getEdition()); c.setSetCode(cp.getEdition());
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
c.setState(CardStateName.SpecializeG, false); c.setState(CardStateName.SpecializeG, false);
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_G); c.setImageKey(cp.getCardGSpecImageKey());
c.setSetCode(cp.getEdition()); c.setSetCode(cp.getEdition());
c.setRarity(cp.getRarity()); c.setRarity(cp.getRarity());
} }

View File

@@ -1335,9 +1335,29 @@ public class CardView extends GameEntityView {
} }
void updateImageKey(Card c) { void updateImageKey(Card c) {
set(TrackableProperty.ImageKey, c.getImageKey()); set(TrackableProperty.ImageKey, c.getImageKey());
// currently only works for Cards
if (!c.getGamePieceType().equals(GamePieceType.CARD)) {
return;
}
IPaperCard pc = c.getPaperCard();
if (pc != null) {
set(TrackableProperty.Artist, pc.getArtist());
}
} }
void updateImageKey(CardState c) { void updateImageKey(CardState c) {
set(TrackableProperty.ImageKey, c.getImageKey()); set(TrackableProperty.ImageKey, c.getImageKey());
// currently only works for Cards
if (!c.getCard().getGamePieceType().equals(GamePieceType.CARD)) {
return;
}
IPaperCard pc = c.getCard().getPaperCard();
if (pc != null) { // currently Artist is per Card
set(TrackableProperty.Artist, pc.getArtist());
}
}
public String getArtist() {
return get(TrackableProperty.Artist);
} }
public CardTypeView getType() { public CardTypeView getType() {

View File

@@ -118,6 +118,7 @@ public enum TrackableProperty {
//Card State //Card State
Name(TrackableTypes.StringType), Name(TrackableTypes.StringType),
Artist(TrackableTypes.StringType),
Colors(TrackableTypes.ColorSetType), Colors(TrackableTypes.ColorSetType),
OriginalColors(TrackableTypes.ColorSetType), OriginalColors(TrackableTypes.ColorSetType),
LeftSplitColors(TrackableTypes.ColorSetType), LeftSplitColors(TrackableTypes.ColorSetType),

View File

@@ -40,7 +40,7 @@ import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.mortennobel.imagescaling.ResampleOp; import com.mortennobel.imagescaling.ResampleOp;
import forge.card.CardSplitType; import forge.card.CardEdition;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardView; import forge.game.card.CardView;
import forge.game.player.PlayerView; import forge.game.player.PlayerView;
@@ -56,8 +56,8 @@ import forge.model.FModel;
import forge.toolbox.FSkin; import forge.toolbox.FSkin;
import forge.toolbox.FSkin.SkinIcon; import forge.toolbox.FSkin.SkinIcon;
import forge.toolbox.imaging.FCardImageRenderer; import forge.toolbox.imaging.FCardImageRenderer;
import forge.util.Aggregates;
import forge.util.ImageUtil; import forge.util.ImageUtil;
import forge.util.TextUtil;
/** /**
* This class stores ALL card images in a cache with soft values. this means * This class stores ALL card images in a cache with soft values. this means
@@ -171,65 +171,41 @@ public class ImageCache {
IPaperCard ipc = null; IPaperCard ipc = null;
boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX); boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX);
String specColor = ""; boolean useArtCrop = "Crop".equals(FModel.getPreferences().getPref(ForgePreferences.FPref.UI_CARD_ART_FORMAT));
if (imageKey.endsWith(ImageKeys.SPECFACE_W)) { String fileName = imageKey;
specColor = "white";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_U)) {
specColor = "blue";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_B)) {
specColor = "black";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_R)) {
specColor = "red";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_G)) {
specColor = "green";
}
if (altState) if (altState)
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length()); imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
if (!specColor.isEmpty())
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.SPECFACE_W.length());
if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) { if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) {
ipc = ImageUtil.getPaperCardFromImageKey(imageKey); String[] tempdata = imageKey.substring(2).split("\\|"); //We want to check the edition first.
if (ipc != null) {
if (altState) { String name = tempdata[0];
imageKey = ipc.getCardAltImageKey(); String setCode = tempdata.length > 1 ? tempdata[1] : CardEdition.UNKNOWN_CODE;
} else if (!specColor.isEmpty()) { String collectorNumber = tempdata.length > 3 ? tempdata[2] : IPaperCard.NO_COLLECTOR_NUMBER;
switch (specColor) {
case "white": CardEdition edition = StaticData.instance().getEditions().get(setCode);
imageKey = ipc.getCardWSpecImageKey();
break; if (useArtCrop) {
case "blue": CardEdition.EditionEntry ee;
imageKey = ipc.getCardUSpecImageKey(); if (!collectorNumber.isEmpty() && !collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
break; ee = edition.getCardFromCollectorNumber(collectorNumber);
case "black": if (ee != null) { // TODO handle Specialize Collector number
imageKey = ipc.getCardBSpecImageKey(); ee = edition.getCardFromCollectorNumber(collectorNumber.substring(0, collectorNumber.length() - 1));
break;
case "red":
imageKey = ipc.getCardRSpecImageKey();
break;
case "green":
imageKey = ipc.getCardGSpecImageKey();
break;
} }
} else { } else {
imageKey = ipc.getCardImageKey(); ee = Aggregates.random(edition.getCardInSet(name));
} }
if (StringUtils.isBlank(imageKey))
return Pair.of(_defaultImage, true);
}
}
// Replace .full to .artcrop if art crop is preferred // Skip fetching if artist info is not available for art crop
// Only allow use art if the artist info is available if (ee != null && ee.artistName().isEmpty()) {
boolean useArtCrop = "Crop".equals(FModel.getPreferences().getPref(ForgePreferences.FPref.UI_CARD_ART_FORMAT)) useArtCrop = false;
&& ipc != null && !ipc.getArtist().isEmpty(); }
String originalKey = imageKey;
if (useArtCrop) {
if (ipc != null && ipc.getRules().getSplitType() == CardSplitType.Flip) {
// Art crop will always use front face as image key for flip cards
imageKey = ipc.getCardImageKey();
} }
imageKey = TextUtil.fastReplace(imageKey, ".full", ".artcrop"); ipc = StaticData.instance().fetchCard(name, setCode, collectorNumber);
}
fileName = ImageUtil.getImageRelativePath(name, setCode, collectorNumber, useArtCrop);
} // TODO add artCrop for Token
String originalKey = imageKey;
// Load from file and add to cache if not found in cache initially. // Load from file and add to cache if not found in cache initially.
BufferedImage original = getImage(imageKey); BufferedImage original = getImage(imageKey);
@@ -239,16 +215,11 @@ public class ImageCache {
} }
// if art crop is exist, check also if the full card image is also cached. // if art crop is exist, check also if the full card image is also cached.
if (useArtCrop && original != null) {
BufferedImage cached = _CACHE.getIfPresent(originalKey);
if (cached != null)
return Pair.of(cached, false);
}
boolean noBorder = !useArtCrop && !isPreferenceEnabled(ForgePreferences.FPref.UI_RENDER_BLACK_BORDERS); boolean noBorder = !useArtCrop && !isPreferenceEnabled(ForgePreferences.FPref.UI_RENDER_BLACK_BORDERS);
boolean fetcherEnabled = isPreferenceEnabled(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER); boolean fetcherEnabled = isPreferenceEnabled(ForgePreferences.FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER);
boolean isPlaceholder = (original == null) && fetcherEnabled; boolean isPlaceholder = (original == null) && fetcherEnabled;
String setCode = imageKey.split("/")[0].trim().toUpperCase(); String setCode = fileName.split("/")[0].trim().toUpperCase();
// If the user has indicated that they prefer Forge NOT render a black border, round the image corners // If the user has indicated that they prefer Forge NOT render a black border, round the image corners
// to account for JPEG images that don't have a transparency. // to account for JPEG images that don't have a transparency.
@@ -301,7 +272,7 @@ public class ImageCache {
CardView card = ipc != null ? Card.getCardForUi(ipc).getView() : cardView; CardView card = ipc != null ? Card.getCardForUi(ipc).getView() : cardView;
String legalString = null; String legalString = null;
original = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); original = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
if (art != null) { if (art != null && ipc != null) {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(StaticData.instance().getCardEdition(ipc.getEdition()).getDate()); cal.setTime(StaticData.instance().getCardEdition(ipc.getEdition()).getDate());
int year = cal.get(Calendar.YEAR); int year = cal.get(Calendar.YEAR);

View File

@@ -18,7 +18,8 @@ final class ImageLoader extends CacheLoader<String, BufferedImage> {
if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_CARD_IMAGES)) if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_DISABLE_CARD_IMAGES))
return null; return null;
File file = ImageKeys.getImageFile(key); boolean useArtCrop = "Crop".equals(FModel.getPreferences().getPref(ForgePreferences.FPref.UI_CARD_ART_FORMAT));
File file = ImageKeys.getImageFile(key, useArtCrop);
if (file != null) { if (file != null) {
if (!file.exists()) { if (!file.exists()) {
return null; return null;

View File

@@ -77,41 +77,11 @@ public final class FImageUtil {
} }
boolean altState = key.endsWith(ImageKeys.BACKFACE_POSTFIX); boolean altState = key.endsWith(ImageKeys.BACKFACE_POSTFIX);
String specColor = "";
if (key.endsWith(ImageKeys.SPECFACE_W)) {
specColor = "white";
} else if (key.endsWith(ImageKeys.SPECFACE_U)) {
specColor = "blue";
} else if (key.endsWith(ImageKeys.SPECFACE_B)) {
specColor = "black";
} else if (key.endsWith(ImageKeys.SPECFACE_R)) {
specColor = "red";
} else if (key.endsWith(ImageKeys.SPECFACE_G)) {
specColor = "green";
}
String imageKey = key; String imageKey = key;
if (prefix.equals(ImageKeys.CARD_PREFIX)) { if (prefix.equals(ImageKeys.CARD_PREFIX)) {
PaperCard card = ImageUtil.getPaperCardFromImageKey(key); PaperCard card = ImageUtil.getPaperCardFromImageKey(key);
if (altState) { if (altState) {
imageKey = card.getCardAltImageKey(); imageKey = card.getCardAltImageKey();
} else if (!specColor.isEmpty()) {
switch (specColor) {
case "white":
imageKey = card.getCardWSpecImageKey();
break;
case "blue":
imageKey = card.getCardUSpecImageKey();
break;
case "black":
imageKey = card.getCardBSpecImageKey();
break;
case "red":
imageKey = card.getCardRSpecImageKey();
break;
case "green":
imageKey = card.getCardGSpecImageKey();
break;
}
} else { } else {
imageKey = card.getCardImageKey(); imageKey = card.getCardImageKey();
} }
@@ -119,9 +89,6 @@ public final class FImageUtil {
if(altState) { if(altState) {
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length()); imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
imageKey += "full.jpg"; imageKey += "full.jpg";
} else if (!specColor.isEmpty()) {
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.SPECFACE_W.length());
imageKey += "full.jpg";
} }
File file = ImageKeys.getImageFile(imageKey); File file = ImageKeys.getImageFile(imageKey);

View File

@@ -34,10 +34,14 @@ public class SwingImageFetcher extends ImageFetcher {
return false; return false;
} }
String newdespath = urlToDownload.contains(".fullborder.jpg") || urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) ? String newdespath = destPath;
TextUtil.fastReplace(destPath, ".full.jpg", ".fullborder.jpg") : destPath; if (!destPath.contains(".artcrop")) {
if (!newdespath.contains(".full") && urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) && !destPath.startsWith(ForgeConstants.CACHE_TOKEN_PICS_DIR)) newdespath = urlToDownload.contains(".fullborder.jpg") || urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) ?
newdespath = newdespath.replace(".jpg", ".fullborder.jpg"); //fix planes/phenomenon for round border options TextUtil.fastReplace(destPath, ".full.jpg", ".fullborder.jpg") : destPath;
if (!newdespath.contains(".full") && urlToDownload.startsWith(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD) && !destPath.startsWith(ForgeConstants.CACHE_TOKEN_PICS_DIR))
newdespath = newdespath.replace(".jpg", ".fullborder.jpg"); //fix planes/phenomenon for round border options
}
URL url = new URL(urlToDownload); URL url = new URL(urlToDownload);
System.out.println("Attempting to fetch: " + url); System.out.println("Attempting to fetch: " + url);
BufferedImage image = ImageIO.read(url); BufferedImage image = ImageIO.read(url);

View File

@@ -124,8 +124,6 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
if(reward.type.equals(Reward.Type.Card)) { if(reward.type.equals(Reward.Type.Card)) {
imageKey = reward.getCard().getImageKey(false); imageKey = reward.getCard().getImageKey(false);
PaperCard card = ImageUtil.getPaperCardFromImageKey(imageKey);
imageKey = card.getCardImageKey();
int count = 0; int count = 0;
@@ -248,8 +246,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
hasbackface = reward.getCard().hasBackFace(); hasbackface = reward.getCard().hasBackFace();
if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(false)) && !Forge.enableUIMask.equals("Art")) { if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(false)) && !Forge.enableUIMask.equals("Art")) {
int count = 0; int count = 0;
PaperCard card = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(false)); File frontFace = ImageKeys.getImageFile(reward.getCard().getImageKey(false));
File frontFace = ImageKeys.getImageFile(card.getCardImageKey());
if (frontFace != null) { if (frontFace != null) {
try { try {
Texture front = Forge.getAssets().manager().get(frontFace.getPath(), Texture.class, false); Texture front = Forge.getAssets().manager().get(frontFace.getPath(), Texture.class, false);
@@ -275,8 +272,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
//preload card back for performance //preload card back for performance
if (hasbackface) { if (hasbackface) {
if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(true))) { if (ImageCache.getInstance().imageKeyFileExists(reward.getCard().getImageKey(true))) {
PaperCard cardBack = ImageUtil.getPaperCardFromImageKey(reward.getCard().getImageKey(true)); File backFace = ImageKeys.getImageFile(reward.getCard().getImageKey(true));
File backFace = ImageKeys.getImageFile(cardBack.getCardAltImageKey());
if (backFace != null) { if (backFace != null) {
try { try {
Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false); Texture back = Forge.getAssets().manager().get(backFace.getPath(), Texture.class, false);
@@ -400,8 +396,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
if (imageKey != "") { if (imageKey != "") {
isBooster = true; isBooster = true;
File file = new File(IMAGE_LIST_QUEST_BOOSTERS_FILE); File file = new File(IMAGE_LIST_QUEST_BOOSTERS_FILE);
try { try (Scanner scanner = new Scanner(file)) {
Scanner scanner = new Scanner(file);
String boosterPath = ""; String boosterPath = "";
while(scanner.hasNextLine()) while(scanner.hasNextLine())
{ {

View File

@@ -247,9 +247,6 @@ public class ImageCache {
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length()); imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
} }
if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) { if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) {
PaperCard card = ImageUtil.getPaperCardFromImageKey(imageKey);
if (card != null)
imageKey = altState ? card.getCardAltImageKey() : card.getCardImageKey();
if (StringUtils.isBlank(imageKey)) { if (StringUtils.isBlank(imageKey)) {
if (useDefaultIfNotFound) if (useDefaultIfNotFound)
return getDefaultImage(); return getDefaultImage();

View File

@@ -9,9 +9,9 @@ import java.util.List;
import forge.ImageKeys; import forge.ImageKeys;
import forge.assets.*; import forge.assets.*;
import forge.item.PaperCard;
import forge.util.ImageUtil;
import forge.util.TextBounds; import forge.util.TextBounds;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
@@ -156,13 +156,7 @@ public class CardImageRenderer {
} }
//space for artist //space for artist
textBoxHeight -= 2 * PT_FONT.getCapHeight(); textBoxHeight -= 2 * PT_FONT.getCapHeight();
PaperCard paperCard = null; String artist = ObjectUtils.firstNonNull(state.getArtist(), "WOTC");
try {
paperCard = ImageUtil.getPaperCardFromImageKey(state.getImageKey());
} catch (Exception e) {}
String artist = "WOTC";
if (paperCard != null && !paperCard.getArtist().isEmpty())
artist = paperCard.getArtist();
float minTextBoxHeight = 2 * headerHeight; float minTextBoxHeight = 2 * headerHeight;
if (textBoxHeight < minTextBoxHeight) { if (textBoxHeight < minTextBoxHeight) {
artHeight -= (minTextBoxHeight - textBoxHeight); //subtract from art height if text box not big enough otherwise artHeight -= (minTextBoxHeight - textBoxHeight); //subtract from art height if text box not big enough otherwise

View File

@@ -103,27 +103,22 @@ public class CardZoom extends FOverlay {
if (pc != null) { if (pc != null) {
Card cardW = Card.fromPaperCard(pc, null); Card cardW = Card.fromPaperCard(pc, null);
cardW.setState(CardStateName.SpecializeW, true); cardW.setState(CardStateName.SpecializeW, true);
cardW.setImageKey(pc, CardStateName.SpecializeW);
list.add(cardW.getView()); list.add(cardW.getView());
Card cardU = Card.fromPaperCard(pc, null); Card cardU = Card.fromPaperCard(pc, null);
cardU.setState(CardStateName.SpecializeU, true); cardU.setState(CardStateName.SpecializeU, true);;
cardU.setImageKey(pc, CardStateName.SpecializeU);
list.add(cardU.getView()); list.add(cardU.getView());
Card cardB = Card.fromPaperCard(pc, null); Card cardB = Card.fromPaperCard(pc, null);
cardB.setState(CardStateName.SpecializeB, true); cardB.setState(CardStateName.SpecializeB, true);
cardB.setImageKey(pc, CardStateName.SpecializeB);
list.add(cardB.getView()); list.add(cardB.getView());
Card cardR = Card.fromPaperCard(pc, null); Card cardR = Card.fromPaperCard(pc, null);
cardR.setState(CardStateName.SpecializeR, true); cardR.setState(CardStateName.SpecializeR, true);
cardR.setImageKey(pc, CardStateName.SpecializeR);
list.add(cardR.getView()); list.add(cardR.getView());
Card cardG = Card.fromPaperCard(pc, null); Card cardG = Card.fromPaperCard(pc, null);
cardG.setState(CardStateName.SpecializeG, true); cardG.setState(CardStateName.SpecializeG, true);
cardG.setImageKey(pc, CardStateName.SpecializeG);
list.add(cardG.getView()); list.add(cardG.getView());
} }
if (!list.isEmpty()) if (!list.isEmpty())

View File

@@ -1384,13 +1384,9 @@ public class HumanCostDecision extends CostDecisionMakerBase {
try { try {
//for cards like Sword-Point Diplomacy and others that uses imprinted as container for their ability //for cards like Sword-Point Diplomacy and others that uses imprinted as container for their ability
if (cardView != null && cardView.getImprintedCards() != null && cardView.getImprintedCards().size() == 1) if (cardView != null && cardView.getImprintedCards() != null && cardView.getImprintedCards().size() == 1)
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getImprintedCards().get(0).getCurrentState().getTrackableImageKey())); cardView = cardView.getImprintedCards().get(0);
else if (ability.getTargets() != null && ability.getTargets().isTargetingAnyCard() && ability.getTargets().size() == 1) else if (ability.getTargets() != null && ability.getTargets().isTargetingAnyCard() && ability.getTargets().size() == 1)
cardView = CardView.get(ability.getTargetCard()); cardView = CardView.get(ability.getTargetCard());
else if (cardView.getZone() == null || cardView.getZone().isHidden()) {
if (!cardView.hasAlternateState()) //don't override if it has alternatestate since it maybe showing alternate view
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(cardView.getCurrentState().getTrackableImageKey()));
}
} catch (Exception e) { } catch (Exception e) {
//prevent NPE when overriding the cardView, the getPaperCardFromImageKey can return null making the GUI freeze, reset the view if error happens //prevent NPE when overriding the cardView, the getPaperCardFromImageKey can return null making the GUI freeze, reset the view if error happens
cardView = ability.getCardView(); cardView = ability.getCardView();

View File

@@ -1931,7 +1931,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
if (GuiBase.getInterface().isLibgdxPort()) { if (GuiBase.getInterface().isLibgdxPort()) {
CardView cardView; CardView cardView;
try { try {
cardView = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(sa.getView().getHostCard().getCurrentState().getTrackableImageKey())); cardView = sa.getView().getHostCard();
} catch (Exception e) { } catch (Exception e) {
SpellAbilityView spellAbilityView = sa.getView(); SpellAbilityView spellAbilityView = sa.getView();
if (spellAbilityView != null) //updated view if (spellAbilityView != null) //updated view

View File

@@ -35,49 +35,25 @@ public abstract class ImageFetcher {
langCodeMap.put("zh-HK", "zht"); langCodeMap.put("zh-HK", "zht");
}; };
private HashMap<String, HashSet<Callback>> currentFetches = new HashMap<>(); private HashMap<String, HashSet<Callback>> currentFetches = new HashMap<>();
private HashMap<String, String> tokenImages;
private String getScryfallDownloadURL(PaperCard c, String face, boolean useArtCrop, boolean hasSetLookup, String imagePath, ArrayList<String> downloadUrls) { private String getScryfallDownloadURL(String collectorNumber, CardEdition edition, String face, boolean useArtCrop, ArrayList<String> downloadUrls) {
StaticData data = StaticData.instance();
CardEdition edition = data.getEditions().get(c.getEdition());
if (edition == null) // edition does not exist - some error occurred with card data if (edition == null) // edition does not exist - some error occurred with card data
return null; return null;
if (hasSetLookup) {
List<PaperCard> clones = StaticData.instance().getCommonCards().getAllCards(c.getName());
for (PaperCard pc : clones) {
if (clones.size() > 1) {//clones only
if (!c.getEdition().equalsIgnoreCase(pc.getEdition())) {
CardEdition ed = data.getEditions().get(pc.getEdition());
if (ed != null) {
String setCode =ed.getScryfallCode();
String langCode = ed.getCardsLangCode();
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, face, setCode, langCode, useArtCrop));
}
}
} else {// original from set
CardEdition ed = data.getEditions().get(pc.getEdition());
if (ed != null) {
String setCode =ed.getScryfallCode();
String langCode = ed.getCardsLangCode();
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, face, setCode, langCode, useArtCrop));
}
}
}
} else {
String setCode = edition.getScryfallCode();
String langCode = edition.getCardsLangCode();
String primaryUrl = ImageUtil.getScryfallDownloadUrl(c, face, setCode, langCode, useArtCrop);
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + primaryUrl);
// It seems like the scryfall lookup might be better if we didn't include the language code at all? String setCode = edition.getScryfallCode();
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(c, face, setCode, "", useArtCrop)); String langCode = edition.getCardsLangCode();
String primaryUrl = ImageUtil.getScryfallDownloadUrl(collectorNumber, setCode, langCode, face, useArtCrop);
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + primaryUrl);
String alternateUrl = ImageUtil.getScryfallDownloadUrl(c, face, setCode, langCode, useArtCrop, true); // It seems like the scryfall lookup might be better if we didn't include the language code at all?
if (alternateUrl != null && !alternateUrl.equals(primaryUrl)) { downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(collectorNumber, setCode, "", face, useArtCrop));
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + alternateUrl);
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(c, face, setCode, "", useArtCrop, true)); String alternateUrl = ImageUtil.getScryfallDownloadUrl(collectorNumber, setCode, langCode, face, useArtCrop, true);
} if (alternateUrl != null && !alternateUrl.equals(primaryUrl)) {
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + alternateUrl);
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(collectorNumber, setCode, "", face, useArtCrop, true));
} }
return null; return null;
} }
@@ -131,7 +107,45 @@ public abstract class ImageFetcher {
File destFile = null; File destFile = null;
String face = ""; String face = "";
if (prefix.equals(ImageKeys.CARD_PREFIX)) { if (prefix.equals(ImageKeys.CARD_PREFIX)) {
PaperCard paperCard = ImageUtil.getPaperCardFromImageKey(imageKey); String tmp = imageKey;
if (tmp.endsWith(ImageKeys.BACKFACE_POSTFIX)) {
face = "back";
tmp = tmp.substring(0, tmp.length() - ImageKeys.BACKFACE_POSTFIX.length());
}
String[] tempdata = tmp.substring(2).split("\\|"); //We want to check the edition first.
String name = tempdata[0];
String setCode = tempdata.length > 1 ? tempdata[1] : CardEdition.UNKNOWN_CODE;
String collectorNumber = tempdata.length > 3 ? tempdata[2] : IPaperCard.NO_COLLECTOR_NUMBER;
CardEdition edition = StaticData.instance().getEditions().get(setCode);
if (edition == null || edition.getType() == CardEdition.Type.CUSTOM_SET) return; //Custom set token, skip fetching.
if (useArtCrop) {
CardEdition.EditionEntry ee;
if (!collectorNumber.isEmpty() && !collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
ee = edition.getCardFromCollectorNumber(collectorNumber);
if (ee == null) { // TODO handle Specialize Collector number
ee = edition.getCardFromCollectorNumber(collectorNumber.substring(0, collectorNumber.length() - 1));
}
} else {
ee = Aggregates.random(edition.getCardInSet(name));
}
// Skip fetching if artist info is not available for art crop
if (ee != null && ee.artistName().isEmpty()) {
return;
}
}
//TODO i don't want from imageKey to PaperCard, just to check for isCustom
PaperCard paperCard = StaticData.instance().fetchCard(name, setCode, collectorNumber);
// TODO handle Specialize Collector number
if (paperCard == null && !collectorNumber.isEmpty() && !collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
paperCard = StaticData.instance().fetchCard(name, setCode, collectorNumber.substring(0, collectorNumber.length() - 1));
}
//PaperCard paperCard = ImageUtil.getPaperCardFromImageKey(tmp);
if (paperCard == null) { if (paperCard == null) {
System.err.println("Paper card not found for: " + imageKey); System.err.println("Paper card not found for: " + imageKey);
return; return;
@@ -143,71 +157,21 @@ public abstract class ImageFetcher {
// Skip fetching if artist info is not available for art crop // Skip fetching if artist info is not available for art crop
if (useArtCrop && paperCard.getArtist().isEmpty()) if (useArtCrop && paperCard.getArtist().isEmpty())
return; return;
String imagePath = ImageUtil.getImageRelativePath(paperCard, "", true, false);
final boolean hasSetLookup = ImageKeys.hasSetLookup(imagePath); String imagePath = ImageUtil.getImageRelativePath(name, setCode, collectorNumber, useArtCrop);
if (imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX)) {
face = "back"; destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, imagePath);
} else if (imageKey.endsWith(ImageKeys.SPECFACE_W)) { if (destFile.exists()) {
face = "white"; paperCard.hasImage(true);
} else if (imageKey.endsWith(ImageKeys.SPECFACE_U)) {
face = "blue";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_B)) {
face = "black";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_R)) {
face = "red";
} else if (imageKey.endsWith(ImageKeys.SPECFACE_G)) {
face = "green";
} }
String filename = "";
switch (face) {
case "back":
filename = paperCard.getCardAltImageKey();
break;
case "white":
filename = paperCard.getCardWSpecImageKey();
break;
case "blue":
filename = paperCard.getCardUSpecImageKey();
break;
case "black":
filename = paperCard.getCardBSpecImageKey();
break;
case "red":
filename = paperCard.getCardRSpecImageKey();
break;
case "green":
filename = paperCard.getCardGSpecImageKey();
break;
default:
filename = paperCard.getCardImageKey();
break;
}
if (useArtCrop) {
filename = TextUtil.fastReplace(filename, ".full", ".artcrop");
}
boolean updateLink = false;
if ("back".equals(face)) {// seems getimage relative path don't process variants for back faces.
try {
filename = TextUtil.fastReplace(filename, "1.full", imageKey.substring(imageKey.lastIndexOf('|') + 1, imageKey.indexOf('$')) + ".full");
updateLink = true;
} catch (Exception e) {
filename = paperCard.getCardAltImageKey();
updateLink = false;
}
}
destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
//skip ftp if using art crop //skip ftp if using art crop
/*
if (!useArtCrop) { if (!useArtCrop) {
//move priority of ftp image here //move priority of ftp image here
StringBuilder setDownload = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD); StringBuilder setDownload = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD);
if (!hasSetLookup) { if (!hasSetLookup) {
if (!updateLink) { setDownload.append(ImageUtil.getDownloadUrl(paperCard, face));
setDownload.append(ImageUtil.getDownloadUrl(paperCard, face));
} else {
String url = ImageUtil.getDownloadUrl(paperCard, face);
setDownload.append(TextUtil.fastReplace(url, "1.full", imageKey.substring(imageKey.lastIndexOf('|') + 1, imageKey.indexOf('$')) + ".full"));
}
downloadUrls.add(setDownload.toString()); downloadUrls.add(setDownload.toString());
} else { } else {
List<PaperCard> clones = StaticData.instance().getCommonCards().getAllCards(paperCard.getName()); List<PaperCard> clones = StaticData.instance().getCommonCards().getAllCards(paperCard.getName());
@@ -222,10 +186,10 @@ public abstract class ImageFetcher {
} }
} }
} }
final String cardCollectorNumber = paperCard.getCollectorNumber(); //*/
if (!cardCollectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) { if (!collectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
// This function adds to downloadUrls for us // This function adds to downloadUrls for us
this.getScryfallDownloadURL(paperCard, face, useArtCrop, hasSetLookup, filename, downloadUrls); this.getScryfallDownloadURL(collectorNumber, edition, face, useArtCrop, downloadUrls);
} }
} else if (ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD).equals(imageKey)) { } else if (ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD).equals(imageKey)) {
// extra logic for hidden card to not clog the other logic // extra logic for hidden card to not clog the other logic
@@ -315,13 +279,6 @@ public abstract class ImageFetcher {
} }
if (destFile.exists()) { if (destFile.exists()) {
// TODO: Figure out why this codepath gets reached.
// Ideally, fetchImage() wouldn't be called if we already have the image.
if (prefix.equals(ImageKeys.CARD_PREFIX)) {
PaperCard paperCard = ImageUtil.getPaperCardFromImageKey(imageKey);
if (paperCard != null)
paperCard.hasImage(true);
}
return; return;
} }