mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Refactor Foil Effect for Mobile
Should fix rendering for Full, Crop and Art renders
This commit is contained in:
@@ -264,12 +264,14 @@ public abstract class GameState {
|
||||
}
|
||||
|
||||
if (c.hasMergedCard()) {
|
||||
String suffix = c.getTopMergedCard().hasPaperFoil() ? "+" : "";
|
||||
// we have to go by the current top card name here
|
||||
newText.append(c.getTopMergedCard().getPaperCard().getName()).append("|Set:")
|
||||
newText.append(c.getTopMergedCard().getPaperCard().getName()).append(suffix).append("|Set:")
|
||||
.append(c.getTopMergedCard().getPaperCard().getEdition()).append("|Art:")
|
||||
.append(c.getTopMergedCard().getPaperCard().getArtIndex());
|
||||
} else {
|
||||
newText.append(c.getPaperCard().getName()).append("|Set:").append(c.getPaperCard().getEdition())
|
||||
String suffix = c.hasPaperFoil() ? "+" : "";
|
||||
newText.append(c.getPaperCard().getName()).append(suffix).append("|Set:").append(c.getPaperCard().getEdition())
|
||||
.append("|Art:").append(c.getPaperCard().getArtIndex());
|
||||
}
|
||||
}
|
||||
@@ -326,8 +328,9 @@ public abstract class GameState {
|
||||
} else if (c.getCurrentStateName().equals(CardStateName.Meld)) {
|
||||
newText.append("|Meld");
|
||||
if (c.getMeldedWith() != null) {
|
||||
String suffix = c.getMeldedWith().hasPaperFoil() ? "+" : "";
|
||||
newText.append(":");
|
||||
newText.append(c.getMeldedWith().getName());
|
||||
newText.append(c.getMeldedWith().getName()).append(suffix);
|
||||
}
|
||||
} else if (c.getCurrentStateName().equals(CardStateName.Modal)) {
|
||||
newText.append("|Modal");
|
||||
|
||||
@@ -410,8 +410,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
view.updateSickness(this);
|
||||
view.updateClassLevel(this);
|
||||
view.updateDraftAction(this);
|
||||
if (paperCard != null)
|
||||
if (paperCard != null) {
|
||||
setMarkedColors(paperCard.getMarkedColors());
|
||||
setPaperFoil(paperCard.isFoil());
|
||||
}
|
||||
}
|
||||
|
||||
public int getHiddenId() {
|
||||
@@ -2246,6 +2248,14 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
public boolean hasChosenColor(String s) {
|
||||
return chosenColors != null && chosenColors.contains(s);
|
||||
}
|
||||
|
||||
public final boolean hasPaperFoil() {
|
||||
return view.hasPaperFoil();
|
||||
}
|
||||
public final void setPaperFoil(final boolean v) {
|
||||
view.updatePaperFoil(v);
|
||||
}
|
||||
|
||||
public final ColorSet getMarkedColors() {
|
||||
if (markedColor == null) {
|
||||
return ColorSet.getNullColor();
|
||||
|
||||
@@ -429,6 +429,12 @@ public class CardView extends GameEntityView {
|
||||
void updateChosenColors(Card c) {
|
||||
set(TrackableProperty.ChosenColors, c.getChosenColors());
|
||||
}
|
||||
public boolean hasPaperFoil() {
|
||||
return get(TrackableProperty.PaperFoil);
|
||||
}
|
||||
void updatePaperFoil(boolean v) {
|
||||
set(TrackableProperty.PaperFoil, v);
|
||||
}
|
||||
public ColorSet getMarkedColors() {
|
||||
return get(TrackableProperty.MarkedColors);
|
||||
}
|
||||
@@ -1520,8 +1526,8 @@ public class CardView extends GameEntityView {
|
||||
public boolean hasPrintedPT() {
|
||||
return get(TrackableProperty.HasPrintedPT);
|
||||
}
|
||||
void updateHasPrintedPT(boolean val) {
|
||||
set(TrackableProperty.HasPrintedPT, val);
|
||||
void updateHasPrintedPT(boolean v) {
|
||||
set(TrackableProperty.HasPrintedPT, v);
|
||||
}
|
||||
|
||||
public String getSetCode() {
|
||||
|
||||
@@ -37,6 +37,7 @@ public enum TrackableProperty {
|
||||
Secondary(TrackableTypes.BooleanType),
|
||||
DoubleFaced(TrackableTypes.BooleanType),
|
||||
FacedownImageKey(TrackableTypes.StringType),
|
||||
PaperFoil(TrackableTypes.BooleanType),
|
||||
|
||||
//TODO?
|
||||
Cloner(TrackableTypes.StringType),
|
||||
@@ -137,7 +138,7 @@ public enum TrackableProperty {
|
||||
AttractionLights(TrackableTypes.IntegerSetType),
|
||||
ChangedColorWords(TrackableTypes.StringMapType),
|
||||
HasChangedColors(TrackableTypes.BooleanType),
|
||||
HasPrintedPT(TrackableTypes.BooleanType, FreezeMode.IgnoresFreeze),
|
||||
HasPrintedPT(TrackableTypes.BooleanType),
|
||||
ChangedTypes(TrackableTypes.StringMapType),
|
||||
|
||||
//check produce mana for BG
|
||||
|
||||
@@ -78,6 +78,7 @@ public class Forge implements ApplicationListener {
|
||||
public static KeyInputAdapter keyInputAdapter;
|
||||
private static boolean exited, initialized;
|
||||
public boolean needsUpdate = false;
|
||||
public static boolean switchClassic = false;
|
||||
public static boolean advStartup = false;
|
||||
public static boolean safeToClose = true;
|
||||
public static boolean magnify = false;
|
||||
@@ -91,6 +92,7 @@ public class Forge implements ApplicationListener {
|
||||
public static String extrawide = "default";
|
||||
public static float heigtModifier = 0.0f;
|
||||
public static float deltaTime = 0f;
|
||||
public static float hueFragTime = 0f;
|
||||
private static boolean isloadingaMatch = false;
|
||||
public static boolean autoAIDeckSelection = false;
|
||||
public static boolean showFPS = false;
|
||||
@@ -370,8 +372,8 @@ public class Forge implements ApplicationListener {
|
||||
Config.instance().loadResources();
|
||||
SpellSmithScene.instance().loadEditions();
|
||||
GameHUD.getInstance().stopAudio();
|
||||
MusicPlaylist.invalidateMusicPlaylist();
|
||||
if (startScene) {
|
||||
MusicPlaylist.invalidateMusicPlaylist();
|
||||
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS);
|
||||
switchScene(StartScene.instance());
|
||||
}
|
||||
@@ -728,6 +730,7 @@ public class Forge implements ApplicationListener {
|
||||
}
|
||||
}
|
||||
deltaTime = 0f;
|
||||
hueFragTime = 0f;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -768,6 +771,9 @@ public class Forge implements ApplicationListener {
|
||||
}
|
||||
|
||||
public static void switchToClassic() {
|
||||
if (switchClassic)
|
||||
return;
|
||||
switchClassic = true;
|
||||
setTransitionScreen(new TransitionScreen(() -> {
|
||||
ImageCache.getInstance().disposeTextures();
|
||||
isMobileAdventureMode = false;
|
||||
@@ -778,7 +784,8 @@ public class Forge implements ApplicationListener {
|
||||
clearTransitionScreen();
|
||||
openHomeDefault();
|
||||
exited = false;
|
||||
}, Forge.takeScreenshot(), false, false));
|
||||
switchClassic = false;
|
||||
}, takeScreenshot(), false, false));
|
||||
}
|
||||
|
||||
public static void switchToAdventure() {
|
||||
@@ -870,6 +877,9 @@ public class Forge implements ApplicationListener {
|
||||
deltaTime += Gdx.graphics.getDeltaTime();
|
||||
if (deltaTime > 22.5f)
|
||||
deltaTime = 0f;
|
||||
hueFragTime += Gdx.graphics.getDeltaTime();
|
||||
if (hueFragTime > 6.29f)
|
||||
hueFragTime = 0f;
|
||||
|
||||
FContainer screen = currentScreen;
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ public class Graphics {
|
||||
private final ShaderProgram shaderChromaticAbberation = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragChromaticAbberation);
|
||||
private final ShaderProgram shaderHueShift = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragHueShift);
|
||||
private final ShaderProgram shaderRoundedRect = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragRoundedRect);
|
||||
private final ShaderProgram shaderRoundedRect2 = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragRoundedRect2);
|
||||
private final ShaderProgram shaderNoiseFade = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragNoiseFade);
|
||||
private final ShaderProgram shaderPortal = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragPortal);
|
||||
private final ShaderProgram shaderPixelateSimple = new ShaderProgram(Shaders.vertPixelateShader, Shaders.fragPixelateSimple);
|
||||
@@ -106,13 +107,28 @@ public class Graphics {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
batch.dispose();
|
||||
shapeRenderer.dispose();
|
||||
shaderOutline.dispose();
|
||||
shaderGrayscale.dispose();
|
||||
shaderUnderwater.dispose();
|
||||
shaderWarp.dispose();
|
||||
if (dummyTexture != null) dummyTexture.dispose();
|
||||
try {
|
||||
batch.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
shapeRenderer.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
shaderOutline.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
shaderGrayscale.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
shaderUnderwater.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
shaderWarp.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
try {
|
||||
if (dummyTexture != null)
|
||||
dummyTexture.dispose();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
public Batch getBatch() {
|
||||
@@ -918,13 +934,40 @@ public class Graphics {
|
||||
batch.begin();
|
||||
}
|
||||
|
||||
public void drawCardRoundRect(Texture image, TextureRegion damage_overlay, float x, float y, float w, float h, boolean drawGray, boolean damaged) {
|
||||
public void drawFoil(float x, float y, float w, float h, float radius) {
|
||||
drawFoil(x, y, w, h, radius, false);
|
||||
}
|
||||
|
||||
public void drawFoil(float x, float y, float w, float h, float radius, boolean rotate) {
|
||||
Texture image = Forge.getAssets().getHolofoil();
|
||||
if (image == null)
|
||||
return;
|
||||
batch.end();
|
||||
shaderRoundedRect2.bind();
|
||||
shaderRoundedRect2.setUniformf("u_resolution", image.getWidth(), image.getHeight());
|
||||
shaderRoundedRect2.setUniformf("edge_radius", (float)(image.getHeight() / image.getWidth()) * radius);
|
||||
shaderRoundedRect2.setUniformf("u_time", Forge.hueFragTime);
|
||||
batch.setShader(shaderRoundedRect2);
|
||||
batch.begin();
|
||||
//draw
|
||||
if (rotate)
|
||||
drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, 0, 0, image.getWidth(), image.getHeight(), 90);
|
||||
else
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
}
|
||||
|
||||
public void drawCardRoundRect(Texture image, TextureRegion damage_overlay, float x, float y, float w, float h, boolean drawGray, boolean damaged, boolean foilEffect) {
|
||||
if (image == null)
|
||||
return;
|
||||
float radius = ImageCache.getInstance().getRadius(image);
|
||||
batch.end();
|
||||
shaderRoundedRect.bind();
|
||||
shaderRoundedRect.setUniformf("u_resolution", image.getWidth(), image.getHeight());
|
||||
shaderRoundedRect.setUniformf("edge_radius", (float)(image.getHeight() / image.getWidth()) * ImageCache.getInstance().getRadius(image));
|
||||
shaderRoundedRect.setUniformf("edge_radius", (float)(image.getHeight() / image.getWidth()) * radius);
|
||||
shaderRoundedRect.setUniformf("u_gray", drawGray ? 0.8f : 0f);
|
||||
batch.setShader(shaderRoundedRect);
|
||||
batch.begin();
|
||||
@@ -934,22 +977,31 @@ public class Graphics {
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
batch.begin();
|
||||
if (foilEffect && !drawGray) {
|
||||
drawFoil(x, y, w, h, radius);
|
||||
}
|
||||
if (damage_overlay != null && damaged)
|
||||
batch.draw(damage_overlay, adjustX(x), adjustY(y, h), w, h);
|
||||
}
|
||||
|
||||
public void drawCardRoundRect(Texture image, float x, float y, float w, float h, float originX, float originY, float rotation) {
|
||||
drawCardRoundRect(image, x, y, w, h, originX, originY, rotation, 1f, false);
|
||||
}
|
||||
|
||||
public void drawCardRoundRect(Texture image, float x, float y, float w, float h, float originX, float originY, float rotation, float modR, boolean drawFoil) {
|
||||
if (image == null)
|
||||
return;
|
||||
batch.end();
|
||||
shaderRoundedRect.bind();
|
||||
shaderRoundedRect.setUniformf("u_resolution", image.getWidth(), image.getHeight());
|
||||
shaderRoundedRect.setUniformf("edge_radius", (float)(image.getHeight() / image.getWidth()) * ImageCache.getInstance().getRadius(image));
|
||||
shaderRoundedRect.setUniformf("edge_radius", (float)(image.getHeight() / image.getWidth()) * (ImageCache.getInstance().getRadius(image) * modR));
|
||||
shaderRoundedRect.setUniformf("u_gray", 0f);
|
||||
batch.setShader(shaderRoundedRect);
|
||||
batch.begin();
|
||||
//draw
|
||||
drawRotatedImage(image, x, y, w, h, originX, originY, 0, 0, image.getWidth(), image.getHeight(), rotation);
|
||||
if (drawFoil)
|
||||
drawFoil(x, y, w, h, modR, true);
|
||||
//reset
|
||||
batch.end();
|
||||
batch.setShader(null);
|
||||
@@ -1273,13 +1325,25 @@ public class Graphics {
|
||||
}
|
||||
|
||||
public void drawImage(Texture image, float x, float y, float w, float h) {
|
||||
drawImage(image, x, y, w, h, false);
|
||||
}
|
||||
|
||||
public void drawImage(Texture image, float x, float y, float w, float h, boolean drawFoil) {
|
||||
if (image != null)
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
if (drawFoil)
|
||||
drawFoil(x, y, w, h, 0f);
|
||||
}
|
||||
|
||||
public void drawImage(TextureRegion image, float x, float y, float w, float h) {
|
||||
drawImage(image, x, y, w, h, false);
|
||||
}
|
||||
|
||||
public void drawImage(TextureRegion image, float x, float y, float w, float h, boolean drawFoil) {
|
||||
if (image != null)
|
||||
batch.draw(image, adjustX(x), adjustY(y, h), w, h);
|
||||
if (drawFoil)
|
||||
drawFoil(x, y, w, h, 0f);
|
||||
}
|
||||
|
||||
public void drawImage(TextureRegion image, TextureRegion glowImageReference, float x, float y, float w, float h, Color glowColor, boolean selected) {
|
||||
@@ -1509,7 +1573,7 @@ public class Graphics {
|
||||
}
|
||||
|
||||
public Color borderLining(String c) {
|
||||
if (c == null || c == "")
|
||||
if (c == null || "".equals(c))
|
||||
return Color.valueOf("#fffffd");
|
||||
int c_r = Integer.parseInt(c.substring(0, 2), 16);
|
||||
int c_g = Integer.parseInt(c.substring(2, 4), 16);
|
||||
|
||||
@@ -154,7 +154,7 @@ public class GuiMobile implements IGuiBase {
|
||||
} else if (paperCard != null) {
|
||||
Texture cardImage = ImageCache.getInstance().getImage(paperCard.getCardImageKey(), false);
|
||||
if (cardImage != null)
|
||||
g.drawCardRoundRect(cardImage, null, (background.getWidth() - cardImageWidth) / 2, (background.getHeight() - cardImageHeight) / 3.8f, cardImageWidth, cardImageHeight, false, false);
|
||||
g.drawCardRoundRect(cardImage, null, (background.getWidth() - cardImageWidth) / 2, (background.getHeight() - cardImageHeight) / 3.8f, cardImageWidth, cardImageHeight, false, false, paperCard.isFoil());
|
||||
}
|
||||
|
||||
Gdx.graphics.requestRendering(); //ensure image appears right away
|
||||
|
||||
@@ -181,6 +181,66 @@ public class Shaders {
|
||||
" }\n" +
|
||||
" gl_FragColor = col*alpha;\n" +
|
||||
"}";
|
||||
public static final String fragRoundedRect2 = "#ifdef GL_ES\n" +
|
||||
"#define LOWP lowp\n" +
|
||||
"precision mediump float;\n" +
|
||||
"#else\n" +
|
||||
"#define LOWP \n" +
|
||||
"#endif\n" +
|
||||
"varying vec2 v_texCoords;\n" +
|
||||
"uniform sampler2D u_texture;\n" +
|
||||
"uniform vec2 u_resolution;\n" +
|
||||
"uniform float edge_radius;\n" +
|
||||
"uniform float u_time;\n" +
|
||||
"LOWP vec4 color = vec4(1.0,1.0,1.0,1.0);\n" +
|
||||
"float gradientIntensity = 0.5;\n" +
|
||||
"const float contrast = 1.5 ;\n" +
|
||||
"vec3 barronSpline(vec3 x, float shape) {\n" +
|
||||
" const float turning = 0.5;\n" +
|
||||
" vec3 d = turning - x;\n" +
|
||||
" return mix(\n" +
|
||||
" ((1. - turning) * (x - 1.)) / (1. - (x + shape * d)) + 1.,\n" +
|
||||
" (turning * x) / (1.0e-20 + (x + shape * d)),\n" +
|
||||
" step(0.0, d));\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"vec3 hs(vec3 c, float s) {\n" +
|
||||
" vec3 m=vec3(cos(s),s=sin(s)*.5774,-s);\n" +
|
||||
" return c*mat3(m+=(1.-m.x)/3.,m.zxy,m.yzx);\n" +
|
||||
"}\n" +
|
||||
"vec3 applyHue(vec3 rgb, float hue)\n" +
|
||||
"{\n" +
|
||||
" //rgb = ((rgb + 0.5f) * 1f) - 0.5f;\n" +
|
||||
" //rgb = barronSpline(rgb, contrast);\n" +
|
||||
" vec3 k = vec3(0.5774);\n" +
|
||||
" float c = cos(hue);\n" +
|
||||
" //Rodrigues' rotation formula\n" +
|
||||
" return rgb * c + cross(k, rgb) * sin(hue) + k * dot(k, rgb) * (1.0 - c);\n" +
|
||||
"}\n"+
|
||||
"void main() {\n" +
|
||||
" vec2 uv = v_texCoords;\n" +
|
||||
" vec2 uv_base_center = uv * 2.0 - 1.0;\n" +
|
||||
"\n" +
|
||||
" vec2 half_resolution = u_resolution.xy * 0.5;\n" +
|
||||
" vec2 abs_rounded_center = half_resolution.xy - edge_radius;\n" +
|
||||
" vec2 abs_pixel_coord = vec2( abs(uv_base_center.x * half_resolution.x), abs(uv_base_center.y * half_resolution.y) );\n" +
|
||||
"\n" +
|
||||
" float alpha = 1.0;\n" +
|
||||
" LOWP vec4 orig = color * texture2D(u_texture, uv);\n" +
|
||||
" vec3 col = orig.rgb;\n" +
|
||||
" vec4 col2 = vec4(applyHue(col, u_time), 1.);\n" +
|
||||
" //multiply the original texture alpha to render only opaque shifted colors \n" +
|
||||
" col2.a *= orig.a;\n" +
|
||||
" uv.y = -1.0 - uv.y;" +
|
||||
" uv.x += sin(uv.y*12.0+u_time)/4.0;" +
|
||||
" if (abs_pixel_coord.x > abs_rounded_center.x && abs_pixel_coord.y > abs_rounded_center.y) {\n" +
|
||||
" float r = length(abs_pixel_coord - abs_rounded_center);\n" +
|
||||
" alpha = smoothstep(edge_radius, edge_radius - gradientIntensity, r);\n" +
|
||||
" \n" +
|
||||
" }\n" +
|
||||
" //alpha here is the rounded edges to be removed \n" +
|
||||
" gl_FragColor = col2*alpha;\n" +
|
||||
"}";
|
||||
public static final String fragHueShift = "#ifdef GL_ES\n" +
|
||||
"#define LOWP lowp\n" +
|
||||
"precision mediump float;\n" +
|
||||
|
||||
@@ -30,6 +30,8 @@ import forge.localinstance.skin.FSkinProp;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static forge.assets.FSkin.getDefaultSkinFile;
|
||||
|
||||
public class Assets implements Disposable {
|
||||
private MemoryTrackingAssetManager manager;
|
||||
private HashMap<Integer, FSkinFont> fonts;
|
||||
@@ -51,6 +53,7 @@ public class Assets implements Disposable {
|
||||
private TextureParameter textureParameter;
|
||||
private ObjectMap<String, Font> textrafonts;
|
||||
private int cFB = 0, cFBVal = 0, cTM = 0, cTMVal = 0, cSF = 0, cSFVal = 0, cCF = 0, cCFVal = 0;
|
||||
private Texture holofoil;
|
||||
|
||||
public Assets() {
|
||||
String titleFilename = Forge.isLandscapeMode() ? "title_bg_lq.png" : "title_bg_lq_portrait.png";
|
||||
@@ -354,6 +357,12 @@ public class Assets implements Disposable {
|
||||
return dummy;
|
||||
}
|
||||
|
||||
public Texture getHolofoil() {
|
||||
if (holofoil == null) {
|
||||
holofoil = getTexture(getDefaultSkinFile("holofoil.png"));
|
||||
}
|
||||
return holofoil;
|
||||
}
|
||||
public Font getTextraFont(BitmapFont bitmapFont, TextureAtlas item_atlas, TextureAtlas pixelmana_atlas) {
|
||||
if (textrafonts == null)
|
||||
textrafonts = new ObjectMap<>();
|
||||
|
||||
@@ -180,6 +180,7 @@ public class FSkin {
|
||||
Forge.getAssets().loadTexture(getDefaultSkinFile("overlay_alpha.png"));
|
||||
Forge.getAssets().loadTexture(getDefaultSkinFile("spiral.png"));
|
||||
Forge.getAssets().loadTexture(getDefaultSkinFile("splatter.png"));
|
||||
Forge.getAssets().loadTexture(getDefaultSkinFile("holofoil.png"));
|
||||
|
||||
if (splashScreen != null) {
|
||||
final FileHandle f = getSkinFile("bg_splash.png");
|
||||
|
||||
@@ -50,7 +50,7 @@ public class CardImage implements FImage {
|
||||
} else {
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false);
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false, false);
|
||||
else {
|
||||
float radius = (h - w) / 8;
|
||||
g.drawborderImage(ImageCache.getInstance().borderColor(image), x, y, w, h);
|
||||
|
||||
@@ -10,8 +10,7 @@ import java.util.List;
|
||||
import forge.ImageKeys;
|
||||
import forge.assets.*;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.ImageUtil;
|
||||
import forge.util.TextBounds;
|
||||
import forge.util.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
@@ -35,8 +34,6 @@ import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.FScreen;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Utils;
|
||||
|
||||
public class CardImageRenderer {
|
||||
private static final float BASE_IMAGE_WIDTH = 360;
|
||||
@@ -791,6 +788,9 @@ public class CardImageRenderer {
|
||||
}
|
||||
}
|
||||
public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard) {
|
||||
drawZoom(g, card, gameView, altState, x, y, w, h, dispW, dispH, isCurrentCard, 1f);
|
||||
}
|
||||
public static void drawZoom(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h, float dispW, float dispH, boolean isCurrentCard, float modR) {
|
||||
boolean canshow = MatchController.instance.mayView(card);
|
||||
String key = card.getState(altState).getImageKey();
|
||||
Texture image = new CachedCardImageRenderer(key).getImage();
|
||||
@@ -814,33 +814,31 @@ public class CardImageRenderer {
|
||||
float new_h = h * wh_Adj;
|
||||
float new_x = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispW - new_w) / 2 : x;
|
||||
float new_y = ForgeConstants.isGdxPortLandscape && isCurrentCard ? (dispH - new_h) / 2 : y;
|
||||
float new_xRotate = (dispW - new_h) / 2;
|
||||
float new_yRotate = (dispH - new_w) / 2;
|
||||
boolean rotateSplit = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS);
|
||||
boolean rotatePlane = FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON);
|
||||
float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f;
|
||||
float minusxy = isModernFrame(card) ? 0.0f : 0.13f * radius;
|
||||
if (card.getCurrentState().getSetCode().equals("LEA") || card.getCurrentState().getSetCode().equals("LEB")) {
|
||||
croppedArea = 0.975f;
|
||||
minusxy = 0.135f * radius;
|
||||
}
|
||||
if (rotatePlane && (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane() || (card.getCurrentState().isBattle() && !altState) || (card.getAlternateState() != null && card.getAlternateState().isBattle() && altState))) {
|
||||
if (canshow && CardRendererUtils.needsRotation(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON, card, altState)) {
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
|
||||
else {
|
||||
g.drawRotatedImage(FSkin.getBorders().get(0), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), new_x + radius / 2 - minusxy, new_y + radius / 2 - minusxy, new_w * croppedArea, new_h * croppedArea, (new_x + radius / 2 - minusxy) + (new_w * croppedArea) / 2, (new_y + radius / 2 - minusxy) + (new_h * croppedArea) / 2, -90);
|
||||
if (CardRendererUtils.drawFoil(card))
|
||||
g.drawFoil(new_x, new_y, new_w, new_h, modR, true);
|
||||
}
|
||||
} else if (Forge.enableUIMask.equals("Crop")) {
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
|
||||
} else
|
||||
g.drawRotatedImage(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, -90);
|
||||
} else if (rotateSplit && isCurrentCard && card.isSplitCard() && canshow && !card.isFaceDown()) {
|
||||
} else if (canshow && CardRendererUtils.needsRotation(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS, card, altState)) {
|
||||
boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath");
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
|
||||
g.drawCardRoundRect(image, new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90, modR, CardRendererUtils.drawFoil(card));
|
||||
else {
|
||||
g.drawRotatedImage(FSkin.getBorders().get(ImageCache.getInstance().getFSkinBorders(card)), new_x, new_y, new_w, new_h, new_x + new_w / 2, new_y + new_h / 2, isAftermath ? 90 : -90);
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), new_x + radius / 2 - minusxy, new_y + radius / 2 - minusxy, new_w * croppedArea, new_h * croppedArea, (new_x + radius / 2 - minusxy) + (new_w * croppedArea) / 2, (new_y + radius / 2 - minusxy) + (new_h * croppedArea) / 2, isAftermath ? 90 : -90);
|
||||
@@ -852,7 +850,7 @@ public class CardImageRenderer {
|
||||
} else {
|
||||
if (card.isFaceDown() && ZoneType.Exile.equals(card.getZone())) {
|
||||
if (card.isForeTold() || altState) {
|
||||
if (card.isSplitCard() && rotateSplit && isCurrentCard) {
|
||||
if (CardRendererUtils.needsRotation(ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS, card, altState) && isCurrentCard) {
|
||||
boolean isAftermath = card.getText().contains("Aftermath") || card.getAlternateState().getOracleText().contains("Aftermath");
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
@@ -868,7 +866,7 @@ public class CardImageRenderer {
|
||||
} else {
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false);
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false, CardRendererUtils.drawFoil(card));
|
||||
else {
|
||||
g.drawImage(ImageCache.getInstance().getBorderImage(image.toString()), ImageCache.getInstance().borderColor(image), x, y, w, h);
|
||||
g.drawImage(ImageCache.getInstance().croppedBorderImage(image), x + radius / 2.4f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea);
|
||||
@@ -885,7 +883,7 @@ public class CardImageRenderer {
|
||||
}
|
||||
} else if (Forge.enableUIMask.equals("Full") && canshow) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false);
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false, CardRendererUtils.drawFoil(card));
|
||||
else {
|
||||
g.drawImage(ImageCache.getInstance().getBorderImage(image.toString()), ImageCache.getInstance().borderColor(image), x, y, w, h);
|
||||
g.drawImage(ImageCache.getInstance().croppedBorderImage(image), x + radius / 2.4f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea);
|
||||
@@ -900,7 +898,8 @@ public class CardImageRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
CardRenderer.drawFoilEffect(g, card, x, y, w, h, isCurrentCard && canshow && image != ImageCache.getInstance().getDefaultImage());
|
||||
if (canshow && !Forge.enableUIMask.equals("Full") && CardRendererUtils.drawFoil(card))
|
||||
g.drawFoil(x, y, w, h, 0f, CardRendererUtils.needsRotation(card, altState));
|
||||
}
|
||||
|
||||
public static void drawDetails(Graphics g, CardView card, GameView gameView, boolean altState, float x, float y, float w, float h) {
|
||||
|
||||
@@ -53,7 +53,6 @@ import forge.gui.card.CardDetailUtil.DetailColors;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.localinstance.properties.ForgeConstants.CounterDisplayType;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.localinstance.properties.ForgePreferences.FPref;
|
||||
import forge.localinstance.skin.FSkinProp;
|
||||
import forge.model.FModel;
|
||||
@@ -605,28 +604,29 @@ public class CardRenderer {
|
||||
croppedArea = 0.975f;
|
||||
minusxy = 0.135f * radius;
|
||||
}
|
||||
if (pc.isFoil()) { //draw foil effect if needed
|
||||
if (card.getCurrentState().getFoilIndex() == 0) { //if foil finish not yet established, assign a random one
|
||||
card.getCurrentState().setFoilIndexOverride(-1);
|
||||
}
|
||||
}
|
||||
if (image != null) {
|
||||
if (image == ImageCache.getInstance().getDefaultImage() || Forge.enableUIMask.equals("Art")) {
|
||||
CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos, true, true);
|
||||
} else {
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false);
|
||||
g.drawCardRoundRect(image, null, x, y, w, h, false, false, CardRendererUtils.drawFoil(card));
|
||||
else {
|
||||
//tint the border
|
||||
g.drawImage(ImageCache.getInstance().getBorderImage(image.toString()), ImageCache.getInstance().borderColor(image), x, y, w, h);
|
||||
g.drawImage(ImageCache.getInstance().croppedBorderImage(image), x + radius / 2.4f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea);
|
||||
if (CardRendererUtils.drawFoil(card))
|
||||
g.drawFoil(x, y, w, h, radius);
|
||||
}
|
||||
} else if (Forge.enableUIMask.equals("Crop")) {
|
||||
g.drawImage(ImageCache.getInstance().croppedBorderImage(image), x, y, w, h);
|
||||
g.drawImage(ImageCache.getInstance().croppedBorderImage(image), x, y, w, h, CardRendererUtils.drawFoil(card));
|
||||
} else
|
||||
g.drawImage(image, x, y, w, h);
|
||||
}
|
||||
if (pc.isFoil()) { //draw foil effect if needed
|
||||
if (card.getCurrentState().getFoilIndex() == 0) { //if foil finish not yet established, assign a random one
|
||||
card.getCurrentState().setFoilIndexOverride(-1);
|
||||
}
|
||||
drawFoilEffect(g, card, x, y, w, h, false);
|
||||
g.drawImage(image, x, y, w, h, CardRendererUtils.drawFoil(card));
|
||||
}
|
||||
} else {
|
||||
//if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically
|
||||
@@ -652,59 +652,56 @@ public class CardRenderer {
|
||||
minusxy = 0.135f * radius;
|
||||
}
|
||||
if (image != null) {
|
||||
float cardR = ImageCache.getInstance().getRadius(image);
|
||||
if (image == ImageCache.getInstance().getDefaultImage() || Forge.enableUIMask.equals("Art")) {
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList, !showCardIdOverlay(card));
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList, !CardRendererUtils.showCardIdOverlay(card));
|
||||
} else if (showsleeves) {
|
||||
if (!card.isForeTold())
|
||||
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
else
|
||||
g.drawCardImage(image, crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(image, crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
} else {
|
||||
if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON)
|
||||
&& (card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane() || (card.getCurrentState().isBattle() && !showAltState) || (card.getAlternateState() != null && card.getAlternateState().isBattle() && showAltState)) && rotate) {
|
||||
if (rotate) {
|
||||
float rotation = CardRendererUtils.hasAftermath(card) ? 90 : -90;
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, x, y, w, h, x + w / 2, y + h / 2, -90);
|
||||
g.drawCardRoundRect(image, x, y, w, h, x + w / 2, y + h / 2, rotation);
|
||||
else {
|
||||
g.drawRotatedImage(FSkin.getBorders().get(0), x, y, w, h, x + w / 2, y + h / 2, -90);
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), x + radius / 2.3f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea, (x + radius / 2.3f - minusxy) + (w * croppedArea) / 2, (y + radius / 2 - minusxy) + (h * croppedArea) / 2, -90);
|
||||
g.drawRotatedImage(FSkin.getBorders().get(0), x, y, w, h, x + w / 2, y + h / 2, rotation);
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), x + radius / 2.3f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea, (x + radius / 2.3f - minusxy) + (w * croppedArea) / 2, (y + radius / 2 - minusxy) + (h * croppedArea) / 2, rotation);
|
||||
}
|
||||
|
||||
} else if (Forge.enableUIMask.equals("Crop")) {
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), x, y, w, h, x + w / 2, y + h / 2, -90);
|
||||
g.drawRotatedImage(ImageCache.getInstance().croppedBorderImage(image), x, y, w, h, x + w / 2, y + h / 2, rotation);
|
||||
} else
|
||||
g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, -90);
|
||||
g.drawRotatedImage(image, x, y, w, h, x + w / 2, y + h / 2, rotation);
|
||||
} else {
|
||||
if (Forge.enableUIMask.equals("Full") && canshow) {
|
||||
if (ImageCache.getInstance().isFullBorder(image))
|
||||
g.drawCardRoundRect(image, crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardRoundRect(image, crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify), CardRendererUtils.drawFoil(card));
|
||||
else {
|
||||
//boolean t = (card.getCurrentState().getOriginalColors() != card.getCurrentState().getColors()) || card.getCurrentState().hasChangeColors();
|
||||
g.drawBorderImage(ImageCache.getInstance().getBorderImage(image.toString(), canshow), ImageCache.getInstance().borderColor(image), ImageCache.getInstance().getTint(card, image), x, y, w, h, false); //tint check for changed colors
|
||||
g.drawCardImage(ImageCache.getInstance().croppedBorderImage(image), crack_overlay, x + radius / 2.4f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(ImageCache.getInstance().croppedBorderImage(image), crack_overlay, x + radius / 2.4f - minusxy, y + radius / 2 - minusxy, w * croppedArea, h * croppedArea, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
}
|
||||
} else if (Forge.enableUIMask.equals("Crop") && canshow) {
|
||||
g.drawCardImage(ImageCache.getInstance().croppedBorderImage(image), crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(ImageCache.getInstance().croppedBorderImage(image), crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
} else {
|
||||
if (canshow)
|
||||
g.drawCardImage(image, crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(image, crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
else // draw card back sleeves
|
||||
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, drawGray(card), magnify ? false : card.getDamage() > 0);
|
||||
g.drawCardImage(sleeves, crack_overlay, x, y, w, h, CardRendererUtils.drawGray(card), CardRendererUtils.drawCracks(card, magnify));
|
||||
}
|
||||
}
|
||||
}
|
||||
drawFoilEffect(g, card, x, y, w, h, false);
|
||||
if (canshow && CardRendererUtils.drawFoil(card))
|
||||
g.drawFoil(x, y, w, h, Forge.enableUIMask.equals("Full") ? cardR : 0f, !Forge.enableUIMask.equals("Art") && rotate);
|
||||
} else {
|
||||
//if card has invalid or no texture due to sudden changes in ImageCache, draw CardImageRenderer instead and wait for it to refresh automatically
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList, !showCardIdOverlay(card));
|
||||
CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList, !CardRendererUtils.showCardIdOverlay(card));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean drawGray(CardView c) {
|
||||
if (c == null)
|
||||
return false;
|
||||
return c.wasDestroyed() || c.isPhasedOut();
|
||||
}
|
||||
|
||||
public static void drawCardWithOverlays(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos) {
|
||||
drawCardWithOverlays(g, card, x, y, w, h, pos, false, false, false);
|
||||
}
|
||||
@@ -757,7 +754,7 @@ public class CardRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
if (canShow && showCardIdOverlay(card)) {
|
||||
if (canShow && CardRendererUtils.showCardIdOverlay(card)) {
|
||||
FSkinFont idFont = FSkinFont.forHeight(h * 0.11f);
|
||||
float idHeight = idFont.getCapHeight();
|
||||
g.drawOutlinedText(String.valueOf(card.getId()), idFont, Color.WHITE, Color.BLACK, x + padding, y + h - idHeight - padding, w, h, false, Align.left, false);
|
||||
@@ -805,7 +802,7 @@ public class CardRenderer {
|
||||
CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize);
|
||||
}
|
||||
|
||||
if (onTop && showCardPowerOverlay(card) && (canShow || card.isFaceDown())) { //make sure card p/t box appears on top
|
||||
if (onTop && CardRendererUtils.showCardPowerOverlay(card) && (canShow || card.isFaceDown())) { //make sure card p/t box appears on top
|
||||
//only needed if on top since otherwise P/T will be hidden
|
||||
drawPtBox(g, card, details, color, x, y, w, h);
|
||||
}
|
||||
@@ -822,8 +819,8 @@ public class CardRenderer {
|
||||
g.setAlphaComposite(0.6f);
|
||||
}
|
||||
if (ZoneType.Battlefield.equals(card.getZone()) && onTop) {
|
||||
drawAbilityIcons(g, card, cx, cy, cw, ch, cx + ((cw * 2) / 2.3f), cy, cw / 5.5f, cw / 5.7f, showAbilityIcons(card));
|
||||
} else if (canShow && !ZoneType.Battlefield.equals(card.getZone()) && showAbilityIcons(card)) {
|
||||
drawAbilityIcons(g, card, cx, cy, cw, ch, cx + ((cw * 2) / 2.3f), cy, cw / 5.5f, cw / 5.7f, CardRendererUtils.showAbilityIcons(card));
|
||||
} else if (canShow && !ZoneType.Battlefield.equals(card.getZone()) && CardRendererUtils.showAbilityIcons(card)) {
|
||||
//draw indicator for flash or can be cast at instant speed, enabled if show ability icons is enabled
|
||||
String keywordKey = card.getCurrentState().getKeywordKey();
|
||||
String abilityText = card.getCurrentState().getAbilityText();
|
||||
@@ -836,7 +833,7 @@ public class CardRenderer {
|
||||
}
|
||||
//draw name and mana cost overlays if card is small or default card image being used
|
||||
if (h <= NAME_COST_THRESHOLD && canShow) {
|
||||
if (showCardNameOverlay(card)) {
|
||||
if (CardRendererUtils.showCardNameOverlay(card)) {
|
||||
float multiplier;
|
||||
switch (Forge.extrawide) {
|
||||
case "default":
|
||||
@@ -854,7 +851,7 @@ public class CardRenderer {
|
||||
}
|
||||
g.drawOutlinedText(CardTranslation.getTranslatedName(details.getName()), FSkinFont.forHeight(h * multiplier), Color.WHITE, Color.BLACK, cx + padding - 1f, cy + padding, cw - 2 * padding, ch * 0.4f, true, Align.left, false, true);
|
||||
}
|
||||
if (showCardManaCostOverlay(card)) {
|
||||
if (CardRendererUtils.showCardManaCostOverlay(card)) {
|
||||
float manaSymbolSize = w / 4.5f;
|
||||
if (card.isSplitCard() && card.hasAlternateState() && !card.isFaceDown() && card.getZone() != ZoneType.Stack && card.getZone() != ZoneType.Battlefield) {
|
||||
if (isChoiceList) {
|
||||
@@ -1442,67 +1439,6 @@ public class CardRenderer {
|
||||
CardFaceSymbols.drawManaCost(g, cost, x + (w - manaCostWidth) / 2, y + (h - manaSymbolSize) / 2, manaSymbolSize);
|
||||
}
|
||||
|
||||
public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h, boolean inZoomer) {
|
||||
if (card.getCurrentState().isBattle())
|
||||
return;
|
||||
if (card.getAlternateState() != null && card.getCurrentState().isBattle())
|
||||
return;
|
||||
//todo add support for battle, better to move the render inside the draw method for card in the future or a general foil effect shader..
|
||||
float new_x = x;
|
||||
float new_y = y;
|
||||
float new_w = w;
|
||||
float new_h = h;
|
||||
float radius = (h - w) / 8;
|
||||
float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f;
|
||||
float minusxy = isModernFrame(card) ? 0.0f : 0.13f * radius;
|
||||
if (card.getCurrentState().getSetCode().equals("LEA") || card.getCurrentState().getSetCode().equals("LEB")) {
|
||||
croppedArea = 0.975f;
|
||||
minusxy = 0.135f * radius;
|
||||
}
|
||||
if (Forge.enableUIMask.equals("Full")) {
|
||||
new_x += radius / 2.4f - minusxy;
|
||||
new_y += radius / 2 - minusxy;
|
||||
new_w = w * croppedArea;
|
||||
new_h = h * croppedArea;
|
||||
}
|
||||
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && MatchController.instance.mayView(card)) {
|
||||
boolean rotateSplit = isPreferenceEnabled(FPref.UI_ROTATE_SPLIT_CARDS) && card.isSplitCard() && inZoomer;
|
||||
int foil = card.getCurrentState().getFoilIndex();
|
||||
if (foil > 0) {
|
||||
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), new_x, new_y, new_w, new_h, rotateSplit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPreferenceEnabled(FPref preferenceName) {
|
||||
return FModel.getPreferences().getPrefBoolean(preferenceName);
|
||||
}
|
||||
|
||||
private static boolean isShowingOverlays(CardView card) {
|
||||
return isPreferenceEnabled(FPref.UI_SHOW_CARD_OVERLAYS) && card != null;
|
||||
}
|
||||
|
||||
private static boolean showCardNameOverlay(CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_NAME);
|
||||
}
|
||||
|
||||
private static boolean showCardPowerOverlay(CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_POWER);
|
||||
}
|
||||
|
||||
private static boolean showCardManaCostOverlay(CardView card) {
|
||||
return isShowingOverlays(card) &&
|
||||
isPreferenceEnabled(FPref.UI_OVERLAY_CARD_MANA_COST);
|
||||
}
|
||||
|
||||
public static boolean showAbilityIcons(CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_ABILITY_ICONS);
|
||||
}
|
||||
|
||||
private static boolean showCardIdOverlay(CardView card) {
|
||||
return card.getId() > 0 && isShowingOverlays(card) && isPreferenceEnabled(FPref.UI_OVERLAY_CARD_ID);
|
||||
}
|
||||
|
||||
//TODO Make FSkinFont accept more than one kind of font and merge this with it
|
||||
private static void generateFontForCounters(final int fontSize) {
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import forge.gui.interfaces.IGuiGame;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.screens.match.views.VReveal;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.util.CardRendererUtils;
|
||||
import forge.util.Utils;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -404,36 +405,43 @@ public class MatchScreen extends FScreen {
|
||||
if (object instanceof FCardPanel cardPanel) {
|
||||
try {
|
||||
if (cardPanel.isHovered()) {
|
||||
VPlayerPanel vPlayerPanel = getPlayerPanel(cardPanel.getCard().getController());
|
||||
CardView cardView = cardPanel.getCard();
|
||||
VPlayerPanel vPlayerPanel = getPlayerPanel(cardView.getController());
|
||||
if (vPlayerPanel == null)
|
||||
vPlayerPanel = getPlayerPanel(cardPanel.getCard().getOwner());
|
||||
vPlayerPanel = getPlayerPanel(cardView.getOwner());
|
||||
if (vPlayerPanel != null) {
|
||||
float cardW = getHeight() * 0.45f;
|
||||
boolean rotate = CardRendererUtils.needsRotation(cardView) && !Forge.magnifyShowDetails;
|
||||
boolean inBattlefield = ZoneType.Battlefield.equals(cardView.getZone());
|
||||
float mul = 0.45f;
|
||||
float div = inBattlefield ? cardPanel.isTapped() ? 2.7f : 2.4f : 1.6f;
|
||||
float adjX = rotate ? cardPanel.getWidth() / div : 0f;
|
||||
float adjY = rotate ? cardPanel.getHeight() / 2.2f : 0f;
|
||||
float cardW = getHeight() * mul;
|
||||
float cardH = FCardPanel.ASPECT_RATIO * cardW;
|
||||
float cardX = !ZoneType.Battlefield.equals(cardPanel.getCard().getZone())
|
||||
? cardPanel.screenPos.x - cardW : cardPanel.screenPos.x + (cardPanel.isTapped()
|
||||
? cardPanel.getWidth() : cardPanel.getWidth() / 1.4f);
|
||||
float cardX = !inBattlefield ? cardPanel.screenPos.x - (cardW + adjX)
|
||||
: cardPanel.screenPos.x + (cardPanel.isTapped() ? cardPanel.getWidth()
|
||||
: cardPanel.getWidth() / 1.4f) + adjX;
|
||||
if (vPlayerPanel.getSelectedTab() != null && vPlayerPanel.getSelectedTab().isVisible()
|
||||
&& cardX > vPlayerPanel.getSelectedTab().getDisplayArea().getLeft()) {
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
cardX = cardPanel.screenPos.x - (cardW + adjX);
|
||||
}
|
||||
if ((cardX + cardW) > scroller.getWidth() + scroller.getLeft())
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
if ((cardX + cardW + adjX) > scroller.getWidth() + scroller.getLeft())
|
||||
cardX = cardPanel.screenPos.x - (cardW + adjX);
|
||||
if (vPlayerPanel.getCommandZone() != null
|
||||
&& vPlayerPanel.getCommandZone().isVisible() && cardX > vPlayerPanel.getCommandZone().screenPos.x)
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
float cardY = (cardPanel.screenPos.y - cardH) + cardPanel.getHeight();
|
||||
cardX = cardPanel.screenPos.x - (cardW + adjX);
|
||||
float cardY = (cardPanel.screenPos.y - (cardH - adjY)) + cardPanel.getHeight();
|
||||
if (vPlayerPanel.getPlayer() == bottomPlayerPanel.getPlayer()) {
|
||||
cardY = bottomPlayerPrompt.screenPos.y - cardH;
|
||||
cardY = bottomPlayerPrompt.screenPos.y - (cardH - adjY);
|
||||
} else if (cardY < vPlayerPanel.getField().screenPos.y && vPlayerPanel.getPlayer() != bottomPlayerPanel.getPlayer()) {
|
||||
cardY = vPlayerPanel.getField().screenPos.y;
|
||||
if ((cardY + cardH) > bottomPlayerPrompt.screenPos.y)
|
||||
cardY = bottomPlayerPrompt.screenPos.y - cardH;
|
||||
cardY = vPlayerPanel.getField().screenPos.y - adjY;
|
||||
if ((cardY + (cardH - adjY)) > bottomPlayerPrompt.screenPos.y)
|
||||
cardY = bottomPlayerPrompt.screenPos.y - (cardH - adjY);
|
||||
}
|
||||
if (Forge.magnifyShowDetails)
|
||||
CardImageRenderer.drawDetails(g, cardPanel.getCard(), MatchController.instance.getGameView(), false, cardX, cardY, cardW, cardH);
|
||||
CardImageRenderer.drawDetails(g, cardView, MatchController.instance.getGameView(), false, cardX, cardY, cardW, cardH);
|
||||
else
|
||||
CardRenderer.drawCard(g, cardPanel.getCard(), cardX, cardY, cardW, cardH, CardRenderer.CardStackPosition.Top, false, false, false, true);
|
||||
CardRenderer.drawCard(g, cardView, cardX, cardY, cardW, cardH, CardRenderer.CardStackPosition.Top, rotate, false, false, true);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -888,11 +896,11 @@ public class MatchScreen extends FScreen {
|
||||
g.drawRipple(image, x, y, w, h, 1 - percentage);
|
||||
if ("Day".equalsIgnoreCase(dt)) {
|
||||
g.setAlphaComposite(percentage);
|
||||
g.drawNightDay(image, x, y, w, h, 100f, true, 1 - percentage);
|
||||
g.drawNightDay(image, x, y, w, h, 100f, true, 0/*1 - percentage*/); // disable extra ripples
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
} else if ("Night".equalsIgnoreCase(dt)) {
|
||||
g.setAlphaComposite(percentage);
|
||||
g.drawNightDay(image, x, y, w, h, -100f, true, 1 - percentage);
|
||||
g.drawNightDay(image, x, y, w, h, -100f, true, 0/*1 - percentage*/); // disable extra ripples
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -41,6 +41,7 @@ import forge.localinstance.skin.IHasSkinProp;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.screens.match.views.VAvatar;
|
||||
import forge.screens.match.views.VStack;
|
||||
import forge.util.CardRendererUtils;
|
||||
import forge.util.TextUtil;
|
||||
import forge.util.Utils;
|
||||
|
||||
@@ -440,33 +441,6 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
|
||||
}
|
||||
}
|
||||
|
||||
//simple check for cardview needed on some special renderer for cards
|
||||
private boolean showAlternate(CardView cardView, String value) {
|
||||
if (cardView == null)
|
||||
return false;
|
||||
if (cardView.isFaceDown())
|
||||
return false;
|
||||
boolean showAlt = false;
|
||||
if (cardView.hasAlternateState()) {
|
||||
if (cardView.hasBackSide())
|
||||
showAlt = value.contains(cardView.getBackSideName()) || cardView.getAlternateState().getAbilityText().contains(value);
|
||||
else if (cardView.hasSecondaryState())
|
||||
showAlt = value.equals(cardView.getAlternateState().getAbilityText());
|
||||
else if (cardView.isSplitCard()) {
|
||||
//special case if aftermath cards can be cast from graveyard like yawgmoths will, you will have choices
|
||||
if (cardView.getAlternateState().getOracleText().contains("Aftermath"))
|
||||
showAlt = cardView.getAlternateState().getOracleText().contains(value);
|
||||
else {
|
||||
if (cardView.isRoom()) // special case for room cards
|
||||
showAlt = cardView.getAlternateState().getName().equalsIgnoreCase(value);
|
||||
else
|
||||
showAlt = value.equals(cardView.getAlternateState().getAbilityText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return showAlt;
|
||||
}
|
||||
|
||||
//special renderer for cards
|
||||
protected class PaperCardItemRenderer extends ItemRenderer {
|
||||
@Override
|
||||
@@ -575,7 +549,7 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
|
||||
}
|
||||
}
|
||||
CardView cv = ((IHasCardView) value).getCardView();
|
||||
CardZoom.show(cv, showAlternate(cv, value.toString()));
|
||||
CardZoom.show(cv, CardRendererUtils.canShowAlternate(cv, value.toString()));
|
||||
} catch (Exception ignored) {
|
||||
//fixme: java.lang.ClassCastException for cards like Subtlety which should be cancelable instead...
|
||||
}
|
||||
@@ -595,7 +569,7 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
|
||||
}
|
||||
}
|
||||
CardView cv = ((IHasCardView) value).getCardView();
|
||||
CardZoom.show(cv, showAlternate(cv, value.toString()));
|
||||
CardZoom.show(cv, CardRendererUtils.canShowAlternate(cv, value.toString()));
|
||||
} catch (Exception ignored) {
|
||||
//fixme: java.lang.ClassCastException for cards like Subtlety which should be cancelable instead...
|
||||
}
|
||||
@@ -612,7 +586,7 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
|
||||
if (morph != null) {
|
||||
g.drawImage(morph, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT);
|
||||
} else if (cv != null) {
|
||||
boolean showAlternate = showAlternate(cv, value.toString());
|
||||
boolean showAlternate = CardRendererUtils.canShowAlternate(cv, value.toString());
|
||||
if (!cv.isFaceDown())
|
||||
CardRenderer.drawCardWithOverlays(g, cv, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top, false, showAlternate, true);
|
||||
else
|
||||
@@ -620,7 +594,7 @@ public class FChoiceList<T> extends FList<T> implements ActivateHandler {
|
||||
}
|
||||
} else {
|
||||
if (cv != null) {
|
||||
boolean showAlternate = showAlternate(cv, value.toString());
|
||||
boolean showAlternate = CardRendererUtils.canShowAlternate(cv, value.toString());
|
||||
if (!cv.isFaceDown())
|
||||
CardRenderer.drawCardWithOverlays(g, cv, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top, false, showAlternate, true);
|
||||
else
|
||||
|
||||
119
forge-gui-mobile/src/forge/util/CardRendererUtils.java
Normal file
119
forge-gui-mobile/src/forge/util/CardRendererUtils.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package forge.util;
|
||||
|
||||
import forge.Forge;
|
||||
import forge.game.card.CardView;
|
||||
import forge.localinstance.properties.ForgePreferences;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.match.MatchController;
|
||||
|
||||
public class CardRendererUtils {
|
||||
public static boolean needsRotation(final CardView card) {
|
||||
return needsRotation(card.isSplitCard() ? ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS
|
||||
: ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON, card, canShowAlternate(card, card.getName()));
|
||||
}
|
||||
public static boolean needsRotation(final CardView card, final boolean altState) {
|
||||
return needsRotation(card.isSplitCard() ? ForgePreferences.FPref.UI_ROTATE_SPLIT_CARDS
|
||||
: ForgePreferences.FPref.UI_ROTATE_PLANE_OR_PHENOMENON, card, altState);
|
||||
}
|
||||
public static boolean needsRotation(final ForgePreferences.FPref fPref, final CardView card, boolean altState) {
|
||||
if (isPreferenceEnabled(fPref)) {
|
||||
if (Forge.enableUIMask.equals("Art"))
|
||||
return false;
|
||||
switch (fPref) {
|
||||
case UI_ROTATE_SPLIT_CARDS -> {
|
||||
return card.isSplitCard() && MatchController.instance.mayView(card) && !card.isFaceDown();
|
||||
}
|
||||
case UI_ROTATE_PLANE_OR_PHENOMENON -> {
|
||||
return card.getCurrentState().isPhenomenon() || card.getCurrentState().isPlane()
|
||||
|| (card.getCurrentState().isBattle() && !altState)
|
||||
|| (card.getAlternateState() != null && card.getAlternateState().isBattle() && altState);
|
||||
}
|
||||
default -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static boolean canShowAlternate(final CardView card, final String reference) {
|
||||
if (card == null)
|
||||
return false;
|
||||
if (card.isFaceDown())
|
||||
return false;
|
||||
boolean showAlt = false;
|
||||
if (card.hasAlternateState()) {
|
||||
if (card.hasBackSide())
|
||||
showAlt = reference.contains(card.getBackSideName()) || card.getAlternateState().getAbilityText().contains(reference);
|
||||
else if (card.hasSecondaryState())
|
||||
showAlt = reference.equals(card.getAlternateState().getAbilityText());
|
||||
else if (card.isSplitCard()) {
|
||||
//special case if aftermath cards can be cast from graveyard like yawgmoths will, you will have choices
|
||||
if (card.getAlternateState().getOracleText().contains("Aftermath"))
|
||||
showAlt = card.getAlternateState().getOracleText().contains(reference);
|
||||
else {
|
||||
if (card.isRoom()) // special case for room cards
|
||||
showAlt = card.getAlternateState().getName().equalsIgnoreCase(reference);
|
||||
else
|
||||
showAlt = reference.equals(card.getAlternateState().getAbilityText());
|
||||
}
|
||||
}
|
||||
}
|
||||
return showAlt;
|
||||
}
|
||||
public static boolean hasAftermath(final CardView card) {
|
||||
if (card.hasAlternateState())
|
||||
return card.getAlternateState().hasAftermath();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isPreferenceEnabled(final ForgePreferences.FPref preferenceName) {
|
||||
return FModel.getPreferences().getPrefBoolean(preferenceName);
|
||||
}
|
||||
|
||||
public static boolean isShowingOverlays(final CardView card) {
|
||||
return isPreferenceEnabled(ForgePreferences.FPref.UI_SHOW_CARD_OVERLAYS) && card != null;
|
||||
}
|
||||
|
||||
public static boolean showCardNameOverlay(final CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_CARD_NAME);
|
||||
}
|
||||
|
||||
public static boolean showCardPowerOverlay(final CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_CARD_POWER);
|
||||
}
|
||||
|
||||
public static boolean showCardManaCostOverlay(final CardView card) {
|
||||
return isShowingOverlays(card) &&
|
||||
isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_CARD_MANA_COST);
|
||||
}
|
||||
|
||||
public static boolean showAbilityIcons(final CardView card) {
|
||||
return isShowingOverlays(card) && isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_ABILITY_ICONS);
|
||||
}
|
||||
|
||||
public static boolean showCardIdOverlay(final CardView card) {
|
||||
return card.getId() > 0 && isShowingOverlays(card) && isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_CARD_ID);
|
||||
}
|
||||
|
||||
public static boolean drawGray(final CardView card) {
|
||||
if (card == null)
|
||||
return false;
|
||||
return card.wasDestroyed() || card.isPhasedOut();
|
||||
}
|
||||
public static boolean drawFoil(final CardView card) {
|
||||
if (card == null)
|
||||
return false;
|
||||
if (isPreferenceEnabled(ForgePreferences.FPref.UI_OVERLAY_FOIL_EFFECT))
|
||||
return card.hasPaperFoil(); // TODO the Card BG should be the texture instead of the Foil Overlay
|
||||
return false;
|
||||
}
|
||||
public static boolean drawCracks(final CardView card, final boolean isMagnify) {
|
||||
if (card == null)
|
||||
return false;
|
||||
if (isMagnify)
|
||||
return false;
|
||||
return card.getDamage() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
forge-gui/res/skins/default/holofoil.png
Normal file
BIN
forge-gui/res/skins/default/holofoil.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Reference in New Issue
Block a user