diff --git a/forge-core/src/main/java/forge/token/TokenDb.java b/forge-core/src/main/java/forge/token/TokenDb.java index 9aa3ea1bd5b..44257015654 100644 --- a/forge-core/src/main/java/forge/token/TokenDb.java +++ b/forge-core/src/main/java/forge/token/TokenDb.java @@ -1,6 +1,7 @@ package forge.token; import com.google.common.collect.HashMultimap; +import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; @@ -41,7 +42,6 @@ public class TokenDb implements ITokenDatabase { public boolean containsRule(String rule) { return this.rulesByName.containsKey(rule); - } public void preloadTokens() { @@ -101,21 +101,33 @@ public class TokenDb implements ITokenDatabase { @Override public PaperToken getToken(String tokenName, String edition) { + return getToken(tokenName, edition, -1); + } + + @Override + public PaperToken getToken(String tokenName, String edition, int artIndex) { CardEdition realEdition = editions.getEditionByCodeOrThrow(edition); String fullName = String.format("%s_%s", tokenName, realEdition.getCode().toLowerCase()); - // token exist in Set, return one at random + // Token exists in edition, return token at artIndex or a random one. if (loadTokenFromSet(realEdition, tokenName)) { - return Aggregates.random(allTokenByName.get(fullName)); + Collection collection = allTokenByName.get(fullName); + + if (artIndex < 1 || artIndex > collection.size()) { + return Aggregates.random(collection); + } + + return Iterables.get(collection, artIndex - 1); } PaperToken fallback = this.fallbackToken(tokenName); if (fallback != null) { return fallback; } - if (!extraTokensByName.containsKey(fullName)) { + CardRules cr = rulesByName.get(tokenName); + if (!extraTokensByName.containsKey(fullName) && cr != null) { try { - PaperToken pt = new PaperToken(rulesByName.get(tokenName), realEdition, tokenName, "", IPaperCard.NO_ARTIST_NAME); + PaperToken pt = new PaperToken(cr, realEdition, tokenName, "", IPaperCard.NO_ARTIST_NAME); extraTokensByName.put(fullName, pt); return pt; } catch(Exception e) { @@ -126,11 +138,6 @@ public class TokenDb implements ITokenDatabase { return extraTokensByName.get(fullName); } - @Override - public PaperToken getToken(String tokenName, String edition, int artIndex) { - return null; - } - @Override public PaperToken getTokenFromEditions(String tokenName, CardDb.CardArtPreference fromSet) { return null; diff --git a/forge-core/src/main/java/forge/util/ImageUtil.java b/forge-core/src/main/java/forge/util/ImageUtil.java index b7a065be721..6f759553c05 100644 --- a/forge-core/src/main/java/forge/util/ImageUtil.java +++ b/forge-core/src/main/java/forge/util/ImageUtil.java @@ -7,6 +7,8 @@ import forge.card.CardRules; import forge.card.CardSplitType; import forge.item.IPaperCard; import forge.item.PaperCard; +import forge.item.PaperToken; +import forge.token.TokenDb; import org.apache.commons.lang3.StringUtils; import java.net.URLEncoder; @@ -45,6 +47,43 @@ public class ImageUtil { // return cp regardless if it's null return cp; } + + public static PaperToken getPaperTokenFromImageKey(final String imageKey) { + String key; + if (imageKey == null || + !imageKey.startsWith(ImageKeys.TOKEN_PREFIX)) { + return null; + } + + key = imageKey.substring(ImageKeys.TOKEN_PREFIX.length()); + + if (key.isEmpty()) { + return null; + } + + TokenDb db = StaticData.instance().getAllTokens(); + if (db == null) { + return null; + } + + String[] split = key.split("\\|"); + if (!db.containsRule(split[0])) { + return null; + } + + PaperToken pt = switch (split.length) { + case 1 -> db.getToken(split[0]); + case 2, 3 -> db.getToken(split[0], split[1]); + default -> db.getToken(split[0], split[1], Integer.parseInt(split[3])); + }; + + if (pt == null) { + System.err.println("Can't find PaperToken from key: " + key); + } + + return pt; + } + public static String transformKey(String imageKey) { String key; String edition= imageKey.substring(0, imageKey.indexOf("/")); diff --git a/forge-gui-desktop/src/main/java/forge/ImageCache.java b/forge-gui-desktop/src/main/java/forge/ImageCache.java index 8c46d438d22..491661487a5 100644 --- a/forge-gui-desktop/src/main/java/forge/ImageCache.java +++ b/forge-gui-desktop/src/main/java/forge/ImageCache.java @@ -224,7 +224,7 @@ public class ImageCache { && ipc != null && !ipc.getArtist().isEmpty(); String originalKey = imageKey; if (useArtCrop) { - if (ipc != null && ipc.getRules().getSplitType() == CardSplitType.Flip) { + if (ipc.getRules().getSplitType() == CardSplitType.Flip) { // Art crop will always use front face as image key for flip cards imageKey = ipc.getCardImageKey(); } diff --git a/forge-gui-mobile/src/forge/assets/ImageCache.java b/forge-gui-mobile/src/forge/assets/ImageCache.java index 2fd2fb7b550..adbf6436e14 100644 --- a/forge-gui-mobile/src/forge/assets/ImageCache.java +++ b/forge-gui-mobile/src/forge/assets/ImageCache.java @@ -32,6 +32,7 @@ import com.google.common.collect.Queues; import com.google.common.collect.Sets; import forge.deck.DeckProxy; import forge.gui.GuiBase; +import forge.item.PaperToken; import forge.util.FileUtil; import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; @@ -250,14 +251,18 @@ public class ImageCache { PaperCard card = ImageUtil.getPaperCardFromImageKey(imageKey); if (card != null) imageKey = altState ? card.getCardAltImageKey() : card.getCardImageKey(); - if (StringUtils.isBlank(imageKey)) { - if (useDefaultIfNotFound) - return getDefaultImage(); - else - return null; - } + } else if (imageKey.startsWith(ImageKeys.TOKEN_PREFIX)) { + PaperToken token = ImageUtil.getPaperTokenFromImageKey(imageKey); + if (token != null) + imageKey = token.getCardImageKey(); } + if (StringUtils.isBlank(imageKey)) { + if (useDefaultIfNotFound) + return getDefaultImage(); + else + return null; + } Texture image; File imageFile = ImageKeys.getImageFile(imageKey);