Merge branch 'master' into refactor_promo_sets

This commit is contained in:
Oleg Agafonov 2020-08-07 02:48:40 +02:00 committed by GitHub
commit 9e6a348cb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4098 changed files with 115584 additions and 60811 deletions

View file

@ -154,6 +154,7 @@ public class CardPanelRenderImpl extends CardPanel {
sb.append(this.view.getToughness());
sb.append(this.view.getLoyalty());
sb.append(this.view.getColor().toString());
sb.append(this.view.getType());
sb.append(this.view.getExpansionSetCode());
for (CardType type : this.view.getCardTypes()) {
sb.append((char) type.ordinal());
@ -227,7 +228,7 @@ public class CardPanelRenderImpl extends CardPanel {
private BufferedImage faceArtImage;
// Factory to generate card appropriate views
private CardRendererFactory cardRendererFactory = new CardRendererFactory();
private final CardRendererFactory cardRendererFactory = new CardRendererFactory();
// The rendered card image, with or without the art image loaded yet
// = null while invalid

View file

@ -140,13 +140,30 @@ public abstract class CardRenderer {
break;
}
// workaround to use real split card names
String realCardName = cardView.getDisplayName();
if (cardView.isSplitCard()) {
for (String partRule : cardView.getLeftSplitRules()) {
if (partRule.equals(rule)) {
realCardName = cardView.getLeftSplitName();
break;
}
}
for (String partRule : cardView.getRightSplitRules()) {
if (partRule.equals(rule)) {
realCardName = cardView.getRightSplitName();
break;
}
}
}
// Kill reminder text
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_RENDERING_REMINDER_TEXT, "false").equals("false")) {
rule = CardRendererUtils.killReminderText(rule).trim();
}
if (!rule.isEmpty()) {
TextboxRule tbRule = TextboxRuleParser.parse(cardView, rule);
TextboxRule tbRule = TextboxRuleParser.parse(cardView, rule, realCardName);
if (tbRule.type == TextboxRuleType.SIMPLE_KEYWORD) {
keywords.add(tbRule);
} else if (tbRule.text.isEmpty()) {

View file

@ -1,256 +1,256 @@
package org.mage.card.arcane;
import mage.MageInt;
import mage.view.CardView;
import mage.view.PermanentView;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author stravant@gmail.com, JayDi85
* <p>
* Various static utilities for use in the card renderer
*/
public final class CardRendererUtils {
// text colors for PT (mtgo and image render modes)
private static final Color CARD_TEXT_COLOR_GOOD_LIGHT = new Color(182, 235, 168);
private static final Color CARD_TEXT_COLOR_GOOD_DARK = new Color(52, 135, 88);
private static final Color CARD_TEXT_COLOR_BAD_LIGHT = new Color(234, 153, 153);
private static final Color CARD_TEXT_COLOR_BAD_DARK = new Color(200, 33, 33);
/**
* Convert an abstract image, whose underlying implementation may or may not
* be a BufferedImage into a BufferedImage by creating one and coping the
* contents if it is not, and simply up-casting if it is.
*
* @param img The image to convert
* @return The converted image
*/
public static BufferedImage toBufferedImage(Image img) {
// Null? No conversion to do
if (img == null) {
return null;
}
// Already a buffered image?
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
public static Color abitbrighter(Color c) {
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
int alpha = c.getAlpha();
int plus_r = (255 - r) / 2;
int plus_g = (255 - g) / 2;
int plus_b = (255 - b) / 2;
return new Color(r + plus_r,
g + plus_g,
b + plus_b,
alpha);
}
public static Color abitdarker(Color c) {
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
int alpha = c.getAlpha();
int plus_r = Math.min(255 - r, r) / 2;
int plus_g = Math.min(255 - g, g) / 2;
int plus_b = Math.min(255 - b, b) / 2;
return new Color(r - plus_r,
g - plus_g,
b - plus_b,
alpha);
}
// Draw a rounded box with a 2-pixel border
// Used on various card parts.
public static void drawRoundedBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Paint fill) {
g.setColor(new Color(0, 0, 0, 150));
g.drawOval(x - 1, y - 1, bevel * 2, h);
g.setPaint(border);
g.drawOval(x, y, bevel * 2 - 1, h - 1);
g.drawOval(x + w - bevel * 2, y, bevel * 2 - 1, h - 1);
g.drawOval(x + 1, y + 1, bevel * 2 - 3, h - 3);
g.drawOval(x + 1 + w - bevel * 2, y + 1, bevel * 2 - 3, h - 3);
g.drawRect(x + bevel, y, w - 2 * bevel, h - 1);
g.drawRect(x + 1 + bevel, y + 1, w - 2 * bevel - 2, h - 3);
g.setPaint(fill);
g.fillOval(x + 2, y + 2, bevel * 2 - 4, h - 4);
g.fillOval(x + 2 + w - bevel * 2, y + 2, bevel * 2 - 4, h - 4);
g.fillRect(x + bevel, y + 2, w - 2 * bevel, h - 4);
g.setPaint(fill);
g.setColor(abitbrighter(g.getColor()));
g.drawLine(x + 1 + bevel, y + 1, x + 1 + bevel + w - 2 * bevel - 2, y + 1);
g.setPaint(fill);
g.setColor(abitdarker(g.getColor()));
g.drawLine(x + 1 + bevel, y + h - 2, x + 1 + bevel + w - 2 * bevel - 2, y + h - 2);
}
public static void drawZendikarLandBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Paint fill) {
g.setColor(new Color(0, 0, 0, 150));
g.drawOval(x - 1, y, bevel * 2, h);
g.setPaint(border);
g.drawOval(x, y, bevel * 2 - 1, h - 1);
g.drawOval(x + w - bevel * 2, y, bevel * 2 - 1, h - 1);
g.drawOval(x + 1, y + 1, bevel * 2 - 3, h - 3);
g.drawOval(x + 1 + w - bevel * 2, y + 1, bevel * 2 - 3, h - 3);
// The big circle in the middle.. (diameter=2+1/4 of height) - 3/4 above line, 1/2 below 0.75 + .5 + 1= 2.25 = 9/4
g.drawOval(x + w / 2 - h - h / 8, y - 3 * h / 4, 9 * h / 4, 9 * h / 4);
g.drawRect(x + bevel, y, w - 2 * bevel, h - 1);
g.drawRect(x + 1 + bevel, y + 1, w - 2 * bevel - 2, h - 3);
g.setPaint(fill);
g.setColor(abitbrighter(g.getColor()));
g.drawLine(x + 1 + bevel, y + 1, x + 1 + bevel + w - 2 * bevel - 2, y + 1);
g.setPaint(fill);
g.setColor(abitdarker(g.getColor()));
g.drawLine(x + 1 + bevel, y + h - 2, x + 1 + bevel + w - 2 * bevel - 2, y + h - 2);
g.fillOval(x + 2, y + 2, bevel * 2 - 4, h - 4);
g.fillOval(x + 2 + w - bevel * 2, y + 2, bevel * 2 - 4, h - 4);
g.fillRect(x + bevel, y + 2, w - 2 * bevel, h - 4);
g.fillOval(x + w / 2 - h - h / 8, y - 3 * h / 4, 9 * h / 4, 9 * h / 4);
}
// Get the width of a mana cost rendered with ManaSymbols.draw
public static int getManaCostWidth(String manaCost, int symbolSize) {
int width = 0;
manaCost = manaCost.replace("\\", "");
StringTokenizer tok = new StringTokenizer(manaCost, " ");
while (tok.hasMoreTokens()) {
tok.nextToken();
width += symbolSize;
}
return width;
}
// Abbreviate a piece of rules text, making substitutions to decrease its
// length. Also abbreviate reminder text.
private static final Pattern abbreviationPattern;
private static final Map<String, String> abbreviations = new HashMap<>();
private static final Pattern killReminderTextPattern;
static {
// Available abbreviations
abbreviations.put("enters the battlefield", "ETB");
abbreviations.put("less than", "<");
abbreviations.put("greater than", ">");
// Compile into regex
String patternString = "(";
Iterator<String> it = abbreviations.keySet().iterator();
while (it.hasNext()) {
patternString += it.next();
if (it.hasNext()) {
patternString += "|";
}
}
patternString += ")";
abbreviationPattern = Pattern.compile(patternString);
// Reminder text killing
killReminderTextPattern = Pattern.compile("\\([^\\)]*\\)");
}
public static String abbreviateRule(String rule) {
StringBuffer build = new StringBuffer();
Matcher match = abbreviationPattern.matcher(rule);
while (match.find()) {
match.appendReplacement(build, abbreviations.get(match.group(1)));
}
match.appendTail(build);
return build.toString();
}
public static String killReminderText(String rule) {
return killReminderTextPattern.matcher(rule).replaceAll("")
.replaceAll("<i>", "")
.replaceAll("</i>", "");
}
public static Color copyColor(Color color) {
if (color != null) {
return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
} else {
return null;
}
}
public static String getCardLifeWithDamage(CardView cardView) {
// life with damage
String originLife = cardView.getToughness();
if (cardView instanceof PermanentView) {
int damage = ((PermanentView) cardView).getDamage();
int life;
try {
life = Integer.parseInt(originLife);
originLife = String.valueOf(Math.max(0, life - damage));
} catch (NumberFormatException e) {
//
}
}
return originLife;
}
public static boolean isCardWithDamage(CardView cardView) {
boolean haveDamage = false;
if (cardView instanceof PermanentView) {
haveDamage = ((PermanentView) cardView).getDamage() > 0;
}
return haveDamage;
}
public static Color getCardTextColor(MageInt value, boolean drawAsDamaged, Color defaultColor, boolean textLight) {
if (drawAsDamaged) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
}
// boost colorizing
if (value != null) {
int current = value.getValue();
int origin = value.getBaseValue();
if (origin != 0) {
if (current < origin) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
} else if (current > origin) {
return textLight ? CARD_TEXT_COLOR_GOOD_LIGHT : CARD_TEXT_COLOR_GOOD_DARK;
} else {
return defaultColor;
}
}
}
return defaultColor;
}
}
package org.mage.card.arcane;
import mage.MageInt;
import mage.view.CardView;
import mage.view.PermanentView;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author stravant@gmail.com, JayDi85
* <p>
* Various static utilities for use in the card renderer
*/
public final class CardRendererUtils {
// text colors for PT (mtgo and image render modes)
private static final Color CARD_TEXT_COLOR_GOOD_LIGHT = new Color(182, 235, 168);
private static final Color CARD_TEXT_COLOR_GOOD_DARK = new Color(52, 135, 88);
private static final Color CARD_TEXT_COLOR_BAD_LIGHT = new Color(234, 153, 153);
private static final Color CARD_TEXT_COLOR_BAD_DARK = new Color(200, 33, 33);
/**
* Convert an abstract image, whose underlying implementation may or may not
* be a BufferedImage into a BufferedImage by creating one and coping the
* contents if it is not, and simply up-casting if it is.
*
* @param img The image to convert
* @return The converted image
*/
public static BufferedImage toBufferedImage(Image img) {
// Null? No conversion to do
if (img == null) {
return null;
}
// Already a buffered image?
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
public static Color abitbrighter(Color c) {
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
int alpha = c.getAlpha();
int plus_r = (255 - r) / 2;
int plus_g = (255 - g) / 2;
int plus_b = (255 - b) / 2;
return new Color(r + plus_r,
g + plus_g,
b + plus_b,
alpha);
}
public static Color abitdarker(Color c) {
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
int alpha = c.getAlpha();
int plus_r = Math.min(255 - r, r) / 2;
int plus_g = Math.min(255 - g, g) / 2;
int plus_b = Math.min(255 - b, b) / 2;
return new Color(r - plus_r,
g - plus_g,
b - plus_b,
alpha);
}
// Draw a rounded box with a 2-pixel border
// Used on various card parts.
public static void drawRoundedBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Paint fill) {
g.setColor(new Color(0, 0, 0, 150));
g.drawOval(x - 1, y - 1, bevel * 2, h);
g.setPaint(border);
g.drawOval(x, y, bevel * 2 - 1, h - 1);
g.drawOval(x + w - bevel * 2, y, bevel * 2 - 1, h - 1);
g.drawOval(x + 1, y + 1, bevel * 2 - 3, h - 3);
g.drawOval(x + 1 + w - bevel * 2, y + 1, bevel * 2 - 3, h - 3);
g.drawRect(x + bevel, y, w - 2 * bevel, h - 1);
g.drawRect(x + 1 + bevel, y + 1, w - 2 * bevel - 2, h - 3);
g.setPaint(fill);
g.fillOval(x + 2, y + 2, bevel * 2 - 4, h - 4);
g.fillOval(x + 2 + w - bevel * 2, y + 2, bevel * 2 - 4, h - 4);
g.fillRect(x + bevel, y + 2, w - 2 * bevel, h - 4);
g.setPaint(fill);
g.setColor(abitbrighter(g.getColor()));
g.drawLine(x + 1 + bevel, y + 1, x + 1 + bevel + w - 2 * bevel - 2, y + 1);
g.setPaint(fill);
g.setColor(abitdarker(g.getColor()));
g.drawLine(x + 1 + bevel, y + h - 2, x + 1 + bevel + w - 2 * bevel - 2, y + h - 2);
}
public static void drawZendikarLandBox(Graphics2D g, int x, int y, int w, int h, int bevel, Paint border, Paint fill) {
g.setColor(new Color(0, 0, 0, 150));
g.drawOval(x - 1, y, bevel * 2, h);
g.setPaint(border);
g.drawOval(x, y, bevel * 2 - 1, h - 1);
g.drawOval(x + w - bevel * 2, y, bevel * 2 - 1, h - 1);
g.drawOval(x + 1, y + 1, bevel * 2 - 3, h - 3);
g.drawOval(x + 1 + w - bevel * 2, y + 1, bevel * 2 - 3, h - 3);
// The big circle in the middle.. (diameter=2+1/4 of height) - 3/4 above line, 1/2 below 0.75 + .5 + 1= 2.25 = 9/4
g.drawOval(x + w / 2 - h - h / 8, y - 3 * h / 4, 9 * h / 4, 9 * h / 4);
g.drawRect(x + bevel, y, w - 2 * bevel, h - 1);
g.drawRect(x + 1 + bevel, y + 1, w - 2 * bevel - 2, h - 3);
g.setPaint(fill);
g.setColor(abitbrighter(g.getColor()));
g.drawLine(x + 1 + bevel, y + 1, x + 1 + bevel + w - 2 * bevel - 2, y + 1);
g.setPaint(fill);
g.setColor(abitdarker(g.getColor()));
g.drawLine(x + 1 + bevel, y + h - 2, x + 1 + bevel + w - 2 * bevel - 2, y + h - 2);
g.fillOval(x + 2, y + 2, bevel * 2 - 4, h - 4);
g.fillOval(x + 2 + w - bevel * 2, y + 2, bevel * 2 - 4, h - 4);
g.fillRect(x + bevel, y + 2, w - 2 * bevel, h - 4);
g.fillOval(x + w / 2 - h - h / 8, y - 3 * h / 4, 9 * h / 4, 9 * h / 4);
}
// Get the width of a mana cost rendered with ManaSymbols.draw
public static int getManaCostWidth(String manaCost, int symbolSize) {
int width = 0;
manaCost = manaCost.replace("\\", "");
StringTokenizer tok = new StringTokenizer(manaCost, " ");
while (tok.hasMoreTokens()) {
tok.nextToken();
width += symbolSize;
}
return width;
}
// Abbreviate a piece of rules text, making substitutions to decrease its
// length. Also abbreviate reminder text.
private static final Pattern abbreviationPattern;
private static final Map<String, String> abbreviations = new HashMap<>();
private static final Pattern killReminderTextPattern;
static {
// Available abbreviations
abbreviations.put("enters the battlefield", "ETB");
abbreviations.put("less than", "<");
abbreviations.put("greater than", ">");
// Compile into regex
String patternString = "(";
Iterator<String> it = abbreviations.keySet().iterator();
while (it.hasNext()) {
patternString += it.next();
if (it.hasNext()) {
patternString += "|";
}
}
patternString += ")";
abbreviationPattern = Pattern.compile(patternString);
// Reminder text killing
killReminderTextPattern = Pattern.compile("\\([^\\)]*\\)");
}
public static String abbreviateRule(String rule) {
StringBuffer build = new StringBuffer();
Matcher match = abbreviationPattern.matcher(rule);
while (match.find()) {
match.appendReplacement(build, abbreviations.get(match.group(1)));
}
match.appendTail(build);
return build.toString();
}
public static String killReminderText(String rule) {
return killReminderTextPattern.matcher(rule).replaceAll("")
.replaceAll("<i>", "")
.replaceAll("</i>", "");
}
public static Color copyColor(Color color) {
if (color != null) {
return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
} else {
return null;
}
}
public static String getCardLifeWithDamage(CardView cardView) {
// life with damage
String originLife = cardView.getToughness();
if (cardView instanceof PermanentView) {
int damage = ((PermanentView) cardView).getDamage();
int life;
try {
life = Integer.parseInt(originLife);
originLife = String.valueOf(Math.max(0, life - damage));
} catch (NumberFormatException e) {
//
}
}
return originLife;
}
public static boolean isCardWithDamage(CardView cardView) {
boolean haveDamage = false;
if (cardView instanceof PermanentView) {
haveDamage = ((PermanentView) cardView).getDamage() > 0;
}
return haveDamage;
}
public static Color getCardTextColor(MageInt value, boolean drawAsDamaged, Color defaultColor, boolean textLight) {
if (drawAsDamaged) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
}
// boost colorizing
if (value != null) {
int current = value.getValue();
int origin = value.getBaseValue();
if (origin != 0) {
if (current < origin) {
return textLight ? CARD_TEXT_COLOR_BAD_LIGHT : CARD_TEXT_COLOR_BAD_DARK;
} else if (current > origin) {
return textLight ? CARD_TEXT_COLOR_GOOD_LIGHT : CARD_TEXT_COLOR_GOOD_DARK;
} else {
return defaultColor;
}
}
}
return defaultColor;
}
}

View file

@ -1,17 +1,17 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.card.arcane;
import java.util.List;
/**
* @author stravant@gmail.com
*/
public class TextboxKeywordRule extends TextboxRule {
public TextboxKeywordRule(String text, List<AttributeRegion> regions) {
super(text, regions, TextboxRuleType.SIMPLE_KEYWORD);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.card.arcane;
import java.util.List;
/**
* @author stravant@gmail.com
*/
public class TextboxKeywordRule extends TextboxRule {
public TextboxKeywordRule(String text, List<AttributeRegion> regions) {
super(text, regions, TextboxRuleType.SIMPLE_KEYWORD);
}
}

View file

@ -7,6 +7,7 @@ package org.mage.card.arcane;
import java.awt.Font;
import java.awt.Image;
import java.awt.Paint;
import java.awt.font.GraphicAttribute;
import java.awt.font.ImageGraphicAttribute;
import java.awt.font.TextAttribute;
@ -47,6 +48,25 @@ public class TextboxRule {
}
}
public static class ColorRegion implements AttributeRegion {
ColorRegion(int start, int end, Paint color) {
this.start = start;
this.end = end;
this.color = color;
}
private final int start;
private final int end;
private final Paint color;
@Override
public void applyToAttributedString(AttributedString str, Font normal, Font italic) {
if (end > start + 1) {
str.addAttribute(TextAttribute.FOREGROUND, color, start, end);
}
}
}
// A special symbol embedded at some point in a string
public static class EmbeddedSymbol implements AttributeRegion {

View file

@ -8,6 +8,7 @@ import java.awt.*;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -22,15 +23,16 @@ public final class TextboxRuleParser {
private static final Pattern LevelAbilityPattern = Pattern.compile("Level (\\d+)-?(\\d*)(\\+?)");
private static final Pattern LoyaltyAbilityPattern = Pattern.compile("^(\\+|\\-)(\\d+|X): ");
private static final Pattern SimpleKeywordPattern = Pattern.compile("^(\\w+( \\w+)?)\\s*(\\([^\\)]*\\))?\\s*$");
private static final Pattern FontColorValuePattern = Pattern.compile("color\\s*=\\s*[\"'](\\w+)[\"']");
// Parse a given rule (given as a string) into a TextboxRule, replacing
// symbol annotations, italics, etc, parsing out information such as
// if the ability is a loyalty ability, and returning an TextboxRule
// representing that information, which can be used to render the rule in
// the textbox of a card.
public static TextboxRule parse(CardView source, String rule) {
public static TextboxRule parse(CardView source, String rule, String cardNameToUse) {
// List of regions to apply
java.util.List<TextboxRule.AttributeRegion> regions = new ArrayList<>();
List<TextboxRule.AttributeRegion> regions = new ArrayList<>();
// Leveler / loyalty / basic
boolean isLeveler = false;
@ -102,10 +104,9 @@ public final class TextboxRuleParser {
String contents = rule.substring(index + 1, closeIndex);
if (contents.equals("this") || contents.equals("source")) {
// Replace {this} with the card's name
String cardName = source.getName();
build.append(cardName);
build.append(cardNameToUse);
index += contents.length() + 2;
outputIndex += cardName.length();
outputIndex += cardNameToUse.length();
} else {
Image symbol = ManaSymbols.getSizedManaSymbol(contents.replace("/", ""), 10);
if (symbol != null) {
@ -199,6 +200,11 @@ public final class TextboxRuleParser {
}
}
break;
case "/font":
// Font it is an additional info of a card
// lets make it blue like it is in tooltip
regions.add(new TextboxRule.ColorRegion(openingIndex, outputIndex, Color.BLUE));
break;
default:
// Unknown
build.append('<').append(tag).append('>');

View file

@ -1,28 +1,28 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.card.arcane;
/**
* @author stravant@gmail.com
*/
public enum TextboxRuleType {
/* Normal abilities, just rendered as lines of text with embedded symbols
* replaced to the relevant images. */
NORMAL,
/* Keyword ability. To be displayed in the comma separated list at the
* very top of the rules box */
SIMPLE_KEYWORD,
/* Loyalty abilities on planeswalkers */
LOYALTY,
/* Basic mana ability */
BASIC_MANA,
/* Levelup creature - static ability at a given level */
LEVEL
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.card.arcane;
/**
* @author stravant@gmail.com
*/
public enum TextboxRuleType {
/* Normal abilities, just rendered as lines of text with embedded symbols
* replaced to the relevant images. */
NORMAL,
/* Keyword ability. To be displayed in the comma separated list at the
* very top of the rules box */
SIMPLE_KEYWORD,
/* Loyalty abilities on planeswalkers */
LOYALTY,
/* Basic mana ability */
BASIC_MANA,
/* Levelup creature - static ability at a given level */
LEVEL
}

View file

@ -2,6 +2,7 @@ package org.mage.plugins.card.dl.sources;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author JayDi85
@ -25,7 +26,10 @@ public class CardImageUrls {
this.baseUrl = baseUrl;
if (alternativeUrl != null && !alternativeUrl.isEmpty()) {
if (alternativeUrl != null
&& alternativeUrl != null
&& !alternativeUrl.isEmpty()
&& !Objects.equals(baseUrl, alternativeUrl)) {
this.alternativeUrls.add(alternativeUrl);
}
}

View file

@ -24,7 +24,7 @@ public enum GrabbagImageSource implements CardImageSource {
@Override
public String getSourceName() {
return "";
return "Grabbag";
}
@Override
@ -75,7 +75,6 @@ public enum GrabbagImageSource implements CardImageSource {
return;
}
singleLinks = new HashMap<>();
singleLinks.put("SWS/AAT-1", "CqmDY8V.jpg");
singleLinks.put("SWS/Acklay of the Arena", "ESVRm6F.jpg");
singleLinks.put("SWS/Acquire Target", "FOskB4q.jpg");
@ -468,7 +467,7 @@ public enum GrabbagImageSource implements CardImageSource {
if (card.getSet().equals("MTG")) {
return "http://static.starcitygames.com/sales/cardscans/";
} else if (card.getSet().equals("SWS")) {
return "http://i.imgur.com/";
return "https://i.imgur.com/";
} else {
return "http://magiccards.info/scans/en/";
}

View file

@ -114,6 +114,15 @@ public enum ScryfallImageSource implements CardImageSource {
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
// workaround to use cards without english images (some promos or special cards)
// bug: https://github.com/magefree/mage/issues/6829
// example: Mysterious Egg from IKO https://api.scryfall.com/cards/iko/385/?format=image
if (Objects.equals(baseUrl, alternativeUrl)) {
// without loc code scryfall must return first available image
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
+ card.getCollectorId() + "/?format=image";
}
}
return new CardImageUrls(baseUrl, alternativeUrl);

View file

@ -473,6 +473,141 @@ public class ScryfallImageSupportCards {
// TODO: DuelsOfThePlaneswalkersPromos
add("DPAP");
add("GRC");
//
add("ARC");
add("M11");
add("V10");
add("DDF");
add("SOM");
// add("TD0"); // Commander Theme Decks
add("PD2");
add("ME4");
add("MBS");
add("DDG");
add("NPH");
add("CMD");
add("M12");
add("V11");
add("DDH");
add("ISD");
add("PD3");
add("DKA");
add("DDI");
add("AVR");
add("PC2");
add("M13");
add("V12");
add("DDJ");
add("RTR");
add("CM1");
// add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia
add("GTC");
add("DDK");
add("DGM");
add("MMA");
add("M14");
add("V13");
add("DDL");
add("THS");
add("C13");
add("BNG");
add("DDM");
add("JOU");
// add("MD1"); // Modern Event Deck
add("CNS");
add("VMA");
add("M15");
add("V14");
add("DDN");
add("KTK");
add("C14");
// add("DD3"); // Duel Decks Anthology
add("FRF");
add("DDO");
add("DTK");
add("TPR");
add("MM2");
add("ORI");
add("V15");
add("DDP");
add("BFZ");
add("EXP");
add("C15");
// add("PZ1"); // Legendary Cube
add("OGW");
add("DDQ");
add("W16");
add("SOI");
add("EMA");
add("EMN");
add("V16");
add("CN2");
add("DDR");
add("KLD");
add("MPS");
// add("PZ2");
add("C16");
add("PCA");
add("AER");
add("MM3");
add("DDS");
add("W17");
add("AKH");
add("CMA");
add("E01");
add("HOU");
add("C17");
add("XLN");
add("DDT");
add("IMA");
add("E02");
add("V17");
add("UST");
add("DDU");
add("RIX");
add("WMCQ");
add("PPRO");
add("A25");
add("DOM");
add("BBD");
add("C18");
add("CM2");
add("M19");
add("GS1");
add("GRN");
add("GK1");
add("GNT");
add("UMA");
add("PUMA");
add("RNA");
add("MEDM");
add("GK2");
add("MH1");
add("WAR");
add("M20");
add("C19");
add("ELD");
add("THB");
add("IKO");
add("C20");
add("MB1");
add("FMB1");
//
add("EURO");
add("GPX");
add("ATH");
add("GRC");
add("ANA");
add("G18");
add("PM20");
add("PS19");
add("SS1");
add("SS2");
add("PPP1");
add("PF19");
add("MPS-AKH");
add("M21");
add("JMP");
}
};

View file

@ -94,16 +94,33 @@ public class ScryfallImageSupportTokens {
put("HOU/Insect", "https://api.scryfall.com/cards/thou/12/en?format=image");
put("HOU/Snake", "https://api.scryfall.com/cards/thou/11/en?format=image");
//AKH
//AKH - tokens
put("AKH/Beast", "https://api.scryfall.com/cards/takh/21/en?format=image");
put("AKH/Cat", "https://api.scryfall.com/cards/takh/16/en?format=image");
put("AKH/Drake", "https://api.scryfall.com/cards/takh/18/en?format=image");
put("AKH/Emblem Gideon", "https://api.scryfall.com/cards/takh/25/en?format=image");
put("AKH/Hippo", "https://api.scryfall.com/cards/takh/22/en?format=image");
put("AKH/Insect", "https://api.scryfall.com/cards/takh/19/en?format=image");
put("AKH/Snake", "https://api.scryfall.com/cards/takh/23/en?format=image");
put("AKH/Warrior", "https://api.scryfall.com/cards/takh/17/en?format=image");
put("AKH/Wurm", "https://api.scryfall.com/cards/takh/24/en?format=image");
put("AKH/Zombie", "https://api.scryfall.com/cards/takh/20/en?format=image");
//AKH - embalm ability (token from card)
put("AKH/Angel of Sanctions", "https://api.scryfall.com/cards/takh/1/en?format=image");
put("AKH/Anointer Priest", "https://api.scryfall.com/cards/takh/2/en?format=image");
put("AKH/Aven Initiate", "https://api.scryfall.com/cards/takh/3/en?format=image");
put("AKH/Aven Wind Guide", "https://api.scryfall.com/cards/takh/4/en?format=image");
put("AKH/Glyph Keeper", "https://api.scryfall.com/cards/takh/5/en?format=image");
put("AKH/Heart-Piercer Manticore", "https://api.scryfall.com/cards/takh/6/en?format=image");
put("AKH/Honored Hydra", "https://api.scryfall.com/cards/takh/7/en?format=image");
put("AKH/Labyrinth Guardian", "https://api.scryfall.com/cards/takh/8/en?format=image");
put("AKH/Oketra's Attendant", "https://api.scryfall.com/cards/takh/9/en?format=image");
put("AKH/Sacred Cat", "https://api.scryfall.com/cards/takh/10/en?format=image");
put("AKH/Tah-Crop Skirmisher", "https://api.scryfall.com/cards/takh/11/en?format=image");
put("AKH/Temmet, Vizier of Naktamun", "https://api.scryfall.com/cards/takh/12/en?format=image");
put("AKH/Trueheart Duelist", "https://api.scryfall.com/cards/takh/13/en?format=image");
put("AKH/Unwavering Initiate", "https://api.scryfall.com/cards/takh/14/en?format=image");
put("AKH/Vizier of Many Faces", "https://api.scryfall.com/cards/takh/15/en?format=image");
//AER
put("AER/Etherium Cell", "https://api.scryfall.com/cards/taer/3/en?format=image");
@ -350,6 +367,88 @@ public class ScryfallImageSupportTokens {
put("THB/Wolf", "https://api.scryfall.com/cards/tthb/11/en?format=image");
put("THB/Zombie", "https://api.scryfall.com/cards/tthb/7/en?format=image");
// IKO
put("IKO/Emblem Narset Of The Ancient Way", "https://api.scryfall.com/cards/tiko/12/en?format=image");
put("IKO/Beast", "https://api.scryfall.com/cards/tiko/10/en?format=image");
put("IKO/Cat Bird", "https://api.scryfall.com/cards/tiko/2/en?format=image");
put("IKO/Cat", "https://api.scryfall.com/cards/tiko/1/en?format=image");
put("IKO/Dinosaur Beast", "https://api.scryfall.com/cards/tiko/11/en?format=image");
put("IKO/Dinosaur", "https://api.scryfall.com/cards/tiko/8/en?format=image");
put("IKO/Feather", "https://api.scryfall.com/cards/tiko/9/en?format=image");
put("IKO/Human Soldier/1", "https://api.scryfall.com/cards/tiko/3/en?format=image");
put("IKO/Human Soldier/2", "https://api.scryfall.com/cards/tiko/4/en?format=image");
put("IKO/Human Soldier/3", "https://api.scryfall.com/cards/tiko/5/en?format=image");
put("IKO/Kraken", "https://api.scryfall.com/cards/tiko/6/en?format=image");
put("IKO/Shark", "https://api.scryfall.com/cards/tiko/7/en?format=image");
// PCA (planes)
put("PCA/Eldrazi", "https://api.scryfall.com/cards/tpca/1/en?format=image");
put("PCA/Plane - Academy at Tolaria West", "https://api.scryfall.com/cards/opca/9/en?format=image");
put("PCA/Plane - Agyrem", "https://api.scryfall.com/cards/opca/11/en?format=image");
put("PCA/Plane - Akoum", "https://api.scryfall.com/cards/opca/12/en?format=image");
put("PCA/Plane - Astral Arena", "https://api.scryfall.com/cards/opca/14/en?format=image");
put("PCA/Plane - Bant", "https://api.scryfall.com/cards/opca/15/en?format=image");
put("PCA/Plane - Edge of Malacol", "https://api.scryfall.com/cards/opca/20/en?format=image");
put("PCA/Plane - Feeding Grounds", "https://api.scryfall.com/cards/opca/23/en?format=image");
put("PCA/Plane - Fields of Summer", "https://api.scryfall.com/cards/opca/24/en?format=image");
put("PCA/Plane - Hedron Fields of Agadeem", "https://api.scryfall.com/cards/opca/35/en?format=image");
put("PCA/Plane - Lethe Lake", "https://api.scryfall.com/cards/opca/47/en?format=image");
put("PCA/Plane - Naya", "https://api.scryfall.com/cards/opca/55/en?format=image");
put("PCA/Plane - Panopticon", "https://api.scryfall.com/cards/opca/62/en?format=image");
put("PCA/Plane - Tazeem", "https://api.scryfall.com/cards/opca/78/en?format=image");
put("PCA/Plane - The Dark Barony", "https://api.scryfall.com/cards/opca/19/en?format=image");
put("PCA/Plane - The Eon Fog", "https://api.scryfall.com/cards/opca/22/en?format=image");
put("PCA/Plane - The Great Forest", "https://api.scryfall.com/cards/opca/32/en?format=image");
put("PCA/Plane - The Zephyr Maze", "https://api.scryfall.com/cards/opca/86/en?format=image");
put("PCA/Plane - Truga Jungle", "https://api.scryfall.com/cards/opca/81/en?format=image");
put("PCA/Plane - Trail of the Mage-Rings", "https://api.scryfall.com/cards/opca/80/en?format=image");
put("PCA/Plane - Turri Island", "https://api.scryfall.com/cards/opca/82/en?format=image");
put("PCA/Plane - Undercity Reaches", "https://api.scryfall.com/cards/opca/83/en?format=image");
// C20
put("C20/Angel", "https://api.scryfall.com/cards/tc20/1/en?format=image");
put("C20/Beast", "https://api.scryfall.com/cards/tc20/11/en?format=image");
put("C20/Bird Illusion", "https://api.scryfall.com/cards/tc20/7/en?format=image");
put("C20/Bird", "https://api.scryfall.com/cards/tc20/2/en?format=image");
put("C20/Dinosaur Cat", "https://api.scryfall.com/cards/tc20/16/en?format=image");
put("C20/Drake", "https://api.scryfall.com/cards/tc20/8/en?format=image");
put("C20/Elemental/1", "https://api.scryfall.com/cards/tc20/10/en?format=image"); // 3/1
put("C20/Elemental/2", "https://api.scryfall.com/cards/tc20/3/en?format=image"); // 4/4
put("C20/Goblin Warrior", "https://api.scryfall.com/cards/tc20/17/en?format=image");
put("C20/Human", "https://api.scryfall.com/cards/tc20/4/en?format=image");
put("C20/Hydra", "https://api.scryfall.com/cards/tc20/12/en?format=image");
put("C20/Insect/1", "https://api.scryfall.com/cards/tc20/13/en?format=image"); // deathtouch
put("C20/Insect/2", "https://api.scryfall.com/cards/tc20/18/en?format=image"); // haste
put("C20/Saproling", "https://api.scryfall.com/cards/tc20/14/en?format=image");
put("C20/Snake", "https://api.scryfall.com/cards/tc20/15/en?format=image");
put("C20/Soldier", "https://api.scryfall.com/cards/tc20/5/en?format=image");
put("C20/Spirit", "https://api.scryfall.com/cards/tc20/6/en?format=image");
put("C20/Treasure", "https://api.scryfall.com/cards/tc20/19/en?format=image");
put("C20/Zombie", "https://api.scryfall.com/cards/tc20/9/en?format=image");
// M21
put("M21/Angel", "https://api.scryfall.com/cards/tm21/1/en?format=image");
put("M21/Emblem Basri Ket", "https://api.scryfall.com/cards/tm21/16/en?format=image");
put("M21/Beast", "https://api.scryfall.com/cards/tm21/10/en?format=image");
put("M21/Bird", "https://api.scryfall.com/cards/tm21/2/en?format=image");
put("M21/Cat/1", "https://api.scryfall.com/cards/tm21/20/en?format=image"); // 1/1
put("M21/Cat/2", "https://api.scryfall.com/cards/tm21/11/en?format=image"); // 2/2
put("M21/Construct", "https://api.scryfall.com/cards/tm21/14/en?format=image");
put("M21/Demon", "https://api.scryfall.com/cards/tm21/6/en?format=image");
put("M21/Dog", "https://api.scryfall.com/cards/tm21/19/en?format=image");
put("M21/Emblem Garruk, Unleashed", "https://api.scryfall.com/cards/tm21/17/en?format=image");
put("M21/Goblin Wizard", "https://api.scryfall.com/cards/tm21/8/en?format=image");
put("M21/Griffin", "https://api.scryfall.com/cards/tm21/3/en?format=image");
put("M21/Knight", "https://api.scryfall.com/cards/tm21/4/en?format=image");
put("M21/Emblem Liliana, Waker of the Dead", "https://api.scryfall.com/cards/tm21/18/en?format=image");
put("M21/Pirate", "https://api.scryfall.com/cards/tm21/9/en?format=image");
put("M21/Saproling", "https://api.scryfall.com/cards/tm21/12/en?format=image");
put("M21/Soldier", "https://api.scryfall.com/cards/tm21/5/en?format=image");
put("M21/Treasure", "https://api.scryfall.com/cards/tm21/15/en?format=image");
put("M21/Weird", "https://api.scryfall.com/cards/tm21/13/en?format=image");
put("M21/Zombie", "https://api.scryfall.com/cards/tm21/7/en?format=image");
// generate supported sets
supportedSets.clear();
for (String cardName : this.keySet()) {

View file

@ -47,7 +47,7 @@ public final class ImageCache {
private static final SoftValuesLoadingCache<String, BufferedImage> FACE_IMAGE_CACHE;
/**
* Common pattern for keys. Format: "<cardname>#<setname>#<collectorID>"
* Common pattern for keys. See ImageCache.getKey for structure info
*/
private static final Pattern KEY_PATTERN = Pattern.compile("(.*)#(.*)#(.*)#(.*)#(.*)#(.*)");
@ -84,13 +84,21 @@ public final class ImageCache {
boolean cardback = false;
String path;
if (collectorId.isEmpty() || "0".equals(collectorId)) {
if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability
info.setToken(true);
path = CardImageUtils.generateTokenImagePath(info);
if (path == null) {
cardback = true;
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
// try token image from card
CardDownloadData newInfo = new CardDownloadData(info);
newInfo.setToken(false);
path = CardImageUtils.buildImagePathToCard(newInfo);
TFile tokenFile = getTFile(path);
if (tokenFile == null || !tokenFile.exists()) {
// token empty token image
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
}
}
} else {
path = CardImageUtils.buildImagePathToCard(info);
@ -245,12 +253,20 @@ public final class ImageCache {
CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor);
String path;
if (collectorId.isEmpty() || "0".equals(collectorId)) {
if (collectorId.isEmpty() || "0".equals(collectorId) || !tokenDescriptor.isEmpty()) { // tokenDescriptor for embalm ability
info.setToken(true);
path = CardImageUtils.generateFullTokenImagePath(info);
path = CardImageUtils.generateTokenImagePath(info);
if (path == null) {
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
// try token image from card
CardDownloadData newInfo = new CardDownloadData(info);
newInfo.setToken(false);
path = CardImageUtils.buildImagePathToCard(newInfo);
TFile tokenFile = getTFile(path);
if (tokenFile == null || !tokenFile.exists()) {
// token empty token image
// TODO: replace empty token by other default card, not cardback
path = CardImageUtils.buildImagePathToDefault(DirectLinksForDownload.cardbackFilename);
}
}
} else {
path = CardImageUtils.buildImagePathToCard(info);
@ -428,11 +444,14 @@ public final class ImageCache {
* Returns the map key for a card, without any suffixes for the image size.
*/
private static String getKey(CardView card, String name, String suffix) {
return name + '#' + card.getExpansionSetCode() + '#' + card.getType() + '#' + card.getCardNumber() + '#'
+ (card.getTokenSetCode() == null ? "" : card.getTokenSetCode())
return name
+ '#' + card.getExpansionSetCode()
+ '#' + card.getType()
+ '#' + card.getCardNumber()
+ '#' + (card.getTokenSetCode() == null ? "" : card.getTokenSetCode())
+ suffix
+ (card.getUsesVariousArt() ? "#usesVariousArt" : "")
+ (card.getTokenDescriptor() != null ? '#' + card.getTokenDescriptor() : "#");
+ '#' + (card.getTokenDescriptor() != null ? card.getTokenDescriptor() : "");
}
/**

View file

@ -14,6 +14,8 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.imageio.ImageIO;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.gui.BufferedImageBuilder;
import org.mage.plugins.card.utils.ImageManager;
import org.mage.plugins.card.utils.Transparency;
@ -31,7 +33,9 @@ public enum ImageManagerImpl implements ImageManager {
"Main2", "Cleanup", "Next_Turn"};
phasesImages = new HashMap<>();
for (String name : phases) {
Image image = getImageFromResource("/phases/phase_" + name.toLowerCase(Locale.ENGLISH) + ".png", new Rectangle(36, 36));
Image image = getImageFromResource(
PreferencesDialog.getCurrentTheme().getPhasePath("phase_" + name.toLowerCase(Locale.ENGLISH) + ".png"),
new Rectangle(36, 36));
phasesImages.put(name, image);
}
}
@ -263,7 +267,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getConcedeButtonImage() {
if (imageConcedeButton == null) {
imageConcedeButton = getBufferedImageFromResource("/buttons/concede.png");
imageConcedeButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("concede.png"));
}
return imageConcedeButton;
}
@ -271,7 +276,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSwitchHandsButtonImage() {
if (imageSwitchHandsButton == null) {
imageSwitchHandsButton = getBufferedImageFromResource("/buttons/switch_hands.png");
imageSwitchHandsButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("switch_hands.png"));
}
return imageSwitchHandsButton;
}
@ -279,7 +285,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getStopWatchButtonImage() {
if (imageStopWatchingButton == null) {
imageStopWatchingButton = getBufferedImageFromResource("/buttons/stop_watching.png");
imageStopWatchingButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("stop_watching.png"));
}
return imageStopWatchingButton;
}
@ -287,7 +294,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getCancelSkipButtonImage() {
if (imageCancelSkipButton == null) {
imageCancelSkipButton = getBufferedImageFromResource("/buttons/cancel_skip.png");
imageCancelSkipButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("cancel_skip.png"));
}
return imageCancelSkipButton;
}
@ -295,7 +303,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipNextTurnButtonImage() {
if (imageSkipNextTurnButton == null) {
imageSkipNextTurnButton = getBufferedImageFromResource("/buttons/skip_turn.png");
imageSkipNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_turn.png"));
}
return imageSkipNextTurnButton;
}
@ -303,7 +312,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipEndTurnButtonImage() {
if (imageSkipToEndTurnButton == null) {
imageSkipToEndTurnButton = getBufferedImageFromResource("/buttons/skip_to_end.png");
imageSkipToEndTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_end.png"));
}
return imageSkipToEndTurnButton;
}
@ -311,7 +321,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipMainButtonImage() {
if (imageSkipToMainButton == null) {
imageSkipToMainButton = getBufferedImageFromResource("/buttons/skip_to_main.png");
imageSkipToMainButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_main.png"));
}
return imageSkipToMainButton;
}
@ -319,7 +330,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipStackButtonImage() {
if (imageSkipStackButton == null) {
imageSkipStackButton = getBufferedImageFromResource("/buttons/skip_stack.png");
imageSkipStackButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_stack.png"));
}
return imageSkipStackButton;
}
@ -327,7 +339,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipEndStepBeforeYourTurnButtonImage() {
if (imageSkipUntilEndStepBeforeYourTurnButton == null) {
imageSkipUntilEndStepBeforeYourTurnButton = getBufferedImageFromResource("/buttons/skip_to_previous_end.png");
imageSkipUntilEndStepBeforeYourTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_to_previous_end.png"));
}
return imageSkipUntilEndStepBeforeYourTurnButton;
}
@ -335,7 +348,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getSkipYourNextTurnButtonImage() {
if (imageSkipYourNextTurnButton == null) {
imageSkipYourNextTurnButton = getBufferedImageFromResource("/buttons/skip_all.png");
imageSkipYourNextTurnButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("skip_all.png"));
}
return imageSkipYourNextTurnButton;
}
@ -343,7 +357,8 @@ public enum ImageManagerImpl implements ImageManager {
@Override
public Image getToggleRecordMacroButtonImage() {
if (imageToggleRecordMacroButton == null) {
imageToggleRecordMacroButton = getBufferedImageFromResource("/buttons/toggle_macro.png");
imageToggleRecordMacroButton = getBufferedImageFromResource(
PreferencesDialog.getCurrentTheme().getButtonPath("toggle_macro.png"));
}
return imageToggleRecordMacroButton;
}

View file

@ -12,7 +12,6 @@ import mage.components.ImagePanel;
import mage.components.ImagePanelStyle;
import mage.interfaces.plugin.ThemePlugin;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import net.xeoh.plugins.base.annotations.events.Init;
import net.xeoh.plugins.base.annotations.events.PluginLoaded;
import net.xeoh.plugins.base.annotations.meta.Author;
import org.apache.log4j.Logger;
@ -27,10 +26,6 @@ public class ThemePluginImpl implements ThemePlugin {
private final List flist = new List();
private final String BackgroundDir = "backgrounds" + File.separator;
@Init
public void init() {
}
@PluginLoaded
public void newPlugin(ThemePlugin plugin) {
log.info(plugin.toString() + " has been loaded.");
@ -104,10 +99,11 @@ public class ThemePluginImpl implements ThemePlugin {
}
}
// Sets background for in-battle
// loadbuffer_default - Only apply theme background if no custom user background set
private BufferedImage loadbuffer_default() throws IOException {
String filename = "/dragon.png";
BufferedImage res;
InputStream is = this.getClass().getResourceAsStream(filename);
InputStream is = this.getClass().getResourceAsStream(PreferencesDialog.getCurrentTheme().getBattleBackgroundPath());
res = ImageIO.read(is);
return res;
}
@ -150,43 +146,44 @@ public class ThemePluginImpl implements ThemePlugin {
return bgPanel;
}
// Sets background for logged in user for tables/deck editor/card viewer/etc
private synchronized ImagePanel createImagePanelInstance() {
if (background == null) {
String filename = "/background.png";
try {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
} else {
String path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE, "");
if (path != null && !path.isEmpty()) {
try {
File f = new File(path);
if (f != null) {
background = ImageIO.read(f);
}
} catch (Exception e) {
background = null;
try {
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE_DEFAULT, "true").equals("true")) {
InputStream is = this.getClass().getResourceAsStream(PreferencesDialog.getCurrentTheme().getBackgroundPath());
if (is == null) {
throw new FileNotFoundException("Couldn't find " + PreferencesDialog.getCurrentTheme().getBackgroundPath() + " in resources.");
}
background = ImageIO.read(is);
} else {
String path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_BACKGROUND_IMAGE, "");
if (path != null && !path.isEmpty()) {
try {
File f = new File(path);
if (f != null) {
background = ImageIO.read(f);
}
} catch (Exception e) {
background = null;
}
}
if (background == null) {
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
}
if (background == null) {
String filename = "/background/background.png";
InputStream is = this.getClass().getResourceAsStream(filename);
if (is == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
background = ImageIO.read(is);
if (background == null) {
throw new FileNotFoundException("Couldn't find " + filename + " in resources.");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return null;
}
}
return new ImagePanel(background, ImagePanelStyle.SCALED);
}