diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 0d59026e743..6ffb3ac087b 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import forge.game.spellability.SpellAbility; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Predicate; @@ -821,7 +822,7 @@ public class CardView extends GameEntityView { updateZoneText(c); updateDamage(c); - if (getBackup() == null && !c.isFaceDown() && c.hasBackSide()) { + if (getBackup() == null && !c.isFaceDown() && (c.hasBackSide()||c.isFlipCard())) { set(TrackableProperty.PaperCardBackup, c.getPaperCard()); } @@ -1300,6 +1301,37 @@ public class CardView extends GameEntityView { public boolean hasLandwalk() { return get(TrackableProperty.HasLandwalk); } + public boolean hasHasAftermath() { + return get(TrackableProperty.HasAftermath); + } + + public boolean origProduceAnyMana() { + return get(TrackableProperty.OrigProduceAnyMana); + } + public boolean origProduceManaR() { + return get(TrackableProperty.OrigProduceManaR); + } + public boolean origProduceManaG() { + return get(TrackableProperty.OrigProduceManaG); + } + public boolean origProduceManaB() { + return get(TrackableProperty.OrigProduceManaB); + } + public boolean origProduceManaU() { + return get(TrackableProperty.OrigProduceManaU); + } + public boolean origProduceManaW() { + return get(TrackableProperty.OrigProduceManaW); + } + public boolean origProduceManaC() { + return get(TrackableProperty.OrigProduceManaC); + } + public int origCanProduceColoredMana() { + return get(TrackableProperty.CountOrigProduceColoredMana); + } + public int countBasicLandTypes() { + return get(TrackableProperty.CountBasicLandTypes); + } public String getAbilityText() { return get(TrackableProperty.AbilityText); @@ -1333,6 +1365,7 @@ public class CardView extends GameEntityView { set(TrackableProperty.HasInfect, c.hasKeyword(Keyword.INFECT, state)); set(TrackableProperty.HasStorm, c.hasKeyword(Keyword.STORM, state)); set(TrackableProperty.HasLandwalk, c.hasKeyword(Keyword.LANDWALK, state)); + set(TrackableProperty.HasAftermath, c.hasKeyword(Keyword.AFTERMATH, state)); updateAbilityText(c, state); //set protectionKey for Icons set(TrackableProperty.ProtectionKey, c.getProtectionKey()); @@ -1340,6 +1373,84 @@ public class CardView extends GameEntityView { set(TrackableProperty.HexproofKey, c.getHexproofKey()); //keywordkey set(TrackableProperty.KeywordKey, c.getKeywordKey()); + //update Trackable Mana Color for BG Colors + updateManaColorBG(state); + } + void updateManaColorBG(CardState state) { + boolean anyMana = false; + boolean rMana = false; + boolean gMana = false; + boolean bMana = false; + boolean uMana = false; + boolean wMana = false; + boolean cMana = false; + int count = 0; + int basicLandTypes = 0; + if (!state.getManaAbilities().isEmpty()) { + for (SpellAbility sa : state.getManaAbilities()) { + if (sa == null || sa.getManaPart() == null) + continue; + if (sa.getManaPart().isAnyMana()) { + anyMana = true; + } + switch (sa.getManaPart().getOrigProduced()) { + case "R": + if (!rMana) { + count += 1; + rMana = true; + } + break; + case "G": + if (!gMana) { + count += 1; + gMana = true; + } + break; + case "B": + if (!bMana) { + count += 1; + bMana = true; + } + break; + case "U": + if (!uMana) { + count += 1; + uMana = true; + } + break; + case "W": + if (!wMana) { + count += 1; + wMana = true; + } + break; + case "C": + if (!cMana) { + cMana = true; + } + break; + } + } + } + if (isForest()) + basicLandTypes += 1; + if (isMountain()) + basicLandTypes += 1; + if (isSwamp()) + basicLandTypes += 1; + if (isPlains()) + basicLandTypes += 1; + if (isIsland()) + basicLandTypes += 1; + set(TrackableProperty.CountBasicLandTypes, basicLandTypes); + set(TrackableProperty.OrigProduceManaR, rMana); + set(TrackableProperty.OrigProduceManaG, gMana); + set(TrackableProperty.OrigProduceManaB, bMana); + set(TrackableProperty.OrigProduceManaU, uMana); + set(TrackableProperty.OrigProduceManaW, wMana); + set(TrackableProperty.OrigProduceManaC, cMana); + set(TrackableProperty.CountOrigProduceColoredMana, count); + set(TrackableProperty.OrigProduceAnyMana, anyMana); } public boolean isBasicLand() { @@ -1375,6 +1486,12 @@ public class CardView extends GameEntityView { public boolean isIsland() { return getType().hasSubtype("Island"); } + public boolean isVehicle() { + return getType().hasSubtype("Vehicle"); + } + public boolean isArtifact() { + return getType().isArtifact(); + } } //special methods for updating card and player properties as needed and returning the new collection diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index e378e900ab9..09783eba9eb 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -111,6 +111,18 @@ public enum TrackableProperty { HasChangedColors(TrackableTypes.BooleanType), ChangedTypes(TrackableTypes.StringMapType), + //check produce mana for BG + OrigProduceManaR(TrackableTypes.BooleanType), + OrigProduceManaG(TrackableTypes.BooleanType), + OrigProduceManaB(TrackableTypes.BooleanType), + OrigProduceManaU(TrackableTypes.BooleanType), + OrigProduceManaW(TrackableTypes.BooleanType), + OrigProduceManaC(TrackableTypes.BooleanType), + OrigProduceAnyMana(TrackableTypes.BooleanType), + CountOrigProduceColoredMana(TrackableTypes.IntegerType), + //number of basic landtypes + CountBasicLandTypes(TrackableTypes.IntegerType), + KeywordKey(TrackableTypes.StringType), HasDeathtouch(TrackableTypes.BooleanType), HasDevoid(TrackableTypes.BooleanType), @@ -132,6 +144,7 @@ public enum TrackableProperty { HasTrample(TrackableTypes.BooleanType), HasVigilance(TrackableTypes.BooleanType), HasLandwalk(TrackableTypes.BooleanType), + HasAftermath(TrackableTypes.BooleanType), //protectionkey ProtectionKey(TrackableTypes.StringType), //hexproofkey diff --git a/forge-gui-mobile/src/forge/Graphics.java b/forge-gui-mobile/src/forge/Graphics.java index baae7551b1b..5b5b61019da 100644 --- a/forge-gui-mobile/src/forge/Graphics.java +++ b/forge-gui-mobile/src/forge/Graphics.java @@ -472,6 +472,12 @@ public class Graphics { batch.begin(); } + public void drawRectLines(float thickness, Color color, float x, float y, float w, float h) { + drawLine(thickness, color, x, y, x+w, y); + drawLine(thickness, color, x+thickness/2f, y+thickness/2f, x+thickness/2f, y+h-thickness/2f); + drawLine(thickness, color, x, y+h, x+w, y+h); + drawLine(thickness, color, x+w-thickness/2f, y+thickness/2f, x+w-thickness/2f, y+h-thickness/2f); + } public void fillRect(FSkinColor skinColor, float x, float y, float w, float h) { fillRect(skinColor.getColor(), x, y, w, h); @@ -850,6 +856,18 @@ public class Graphics { //use nifty trick with multiple text renders to draw outlined text public void drawOutlinedText(String text, FSkinFont skinFont, Color textColor, Color outlineColor, float x, float y, float w, float h, boolean wrap, int horzAlignment, boolean centerVertically) { + drawOutlinedText(text, skinFont, textColor, outlineColor, x, y, w, h, wrap, horzAlignment, centerVertically, false); + } + public void drawOutlinedText(String text, FSkinFont skinFont, Color textColor, Color outlineColor, float x, float y, float w, float h, boolean wrap, int horzAlignment, boolean centerVertically, boolean shadow) { + if (shadow) { + float oldAlpha = alphaComposite; + alphaComposite = 0.4f; + drawText(text, skinFont, outlineColor, x - 1.5f, y + 1.5f, w, h, wrap, horzAlignment, centerVertically); + drawText(text, skinFont, outlineColor, x + 1.5f, y + 1.5f, w, h, wrap, horzAlignment, centerVertically); + drawText(text, skinFont, outlineColor, x + 1.5f, y - 1.5f, w, h, wrap, horzAlignment, centerVertically); + drawText(text, skinFont, outlineColor, x - 1.5f, y - 1.5f, w, h, wrap, horzAlignment, centerVertically); + alphaComposite = oldAlpha; + } drawText(text, skinFont, outlineColor, x - 1, y, w, h, wrap, horzAlignment, centerVertically); drawText(text, skinFont, outlineColor, x, y - 1, w, h, wrap, horzAlignment, centerVertically); drawText(text, skinFont, outlineColor, x - 1, y - 1, w, h, wrap, horzAlignment, centerVertically); diff --git a/forge-gui-mobile/src/forge/assets/FBufferedImage.java b/forge-gui-mobile/src/forge/assets/FBufferedImage.java index dfc152ce99e..eaebff0e25b 100644 --- a/forge-gui-mobile/src/forge/assets/FBufferedImage.java +++ b/forge-gui-mobile/src/forge/assets/FBufferedImage.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.math.Matrix4; @@ -44,8 +45,30 @@ public abstract class FBufferedImage extends FImageComplex { return 0; } + @Override + public TextureRegion getTextureRegion() { + return new TextureRegion(checkFrameBuffer().getColorBufferTexture()); + } + @Override public Texture getTexture() { + return checkFrameBuffer().getColorBufferTexture(); + } + + public void clear() { + final FrameBuffer fb = frameBuffer; + if (fb != null) { + frameBuffer = null; + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override + public void run() { + fb.dispose(); //must be disposed on EDT thread + } + }); + } + } + + public FrameBuffer checkFrameBuffer() { if (frameBuffer == null) { Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST); //prevent buffered image being clipped @@ -69,20 +92,7 @@ public abstract class FBufferedImage extends FImageComplex { Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST); } - return frameBuffer.getColorBufferTexture(); - } - - public void clear() { - final FrameBuffer fb = frameBuffer; - if (fb != null) { - frameBuffer = null; - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - fb.dispose(); //must be disposed on EDT thread - } - }); - } + return frameBuffer; } protected abstract void draw(Graphics g, float w, float h); diff --git a/forge-gui-mobile/src/forge/assets/FDelayLoadImage.java b/forge-gui-mobile/src/forge/assets/FDelayLoadImage.java index 36d87245f4f..10a339f59ba 100644 --- a/forge-gui-mobile/src/forge/assets/FDelayLoadImage.java +++ b/forge-gui-mobile/src/forge/assets/FDelayLoadImage.java @@ -3,6 +3,7 @@ package forge.assets; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import forge.Graphics; //Special wrapper for a texture to be loaded later when it's needed @@ -32,6 +33,14 @@ public class FDelayLoadImage extends FImageComplex { return texture; } + @Override + public TextureRegion getTextureRegion() { + if (texture == null) { + texture = new Texture(Gdx.files.absolute(filename)); + } + return new TextureRegion(texture); + } + @Override public int getRegionX() { return 0; diff --git a/forge-gui-mobile/src/forge/assets/FImageComplex.java b/forge-gui-mobile/src/forge/assets/FImageComplex.java index 06d557424a5..c726f243093 100644 --- a/forge-gui-mobile/src/forge/assets/FImageComplex.java +++ b/forge-gui-mobile/src/forge/assets/FImageComplex.java @@ -1,9 +1,11 @@ package forge.assets; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; public abstract class FImageComplex implements FImage { public abstract Texture getTexture(); + public abstract TextureRegion getTextureRegion(); public abstract int getRegionX(); public abstract int getRegionY(); } diff --git a/forge-gui-mobile/src/forge/assets/FRotatedImage.java b/forge-gui-mobile/src/forge/assets/FRotatedImage.java index b0a8bdc3764..1022aaebd52 100644 --- a/forge-gui-mobile/src/forge/assets/FRotatedImage.java +++ b/forge-gui-mobile/src/forge/assets/FRotatedImage.java @@ -2,6 +2,7 @@ package forge.assets; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import forge.Graphics; public class FRotatedImage extends FImageComplex { @@ -33,6 +34,11 @@ public class FRotatedImage extends FImageComplex { return texture; } + @Override + public TextureRegion getTextureRegion() { + return new TextureRegion(texture); + } + @Override public int getRegionX() { return srcX; diff --git a/forge-gui-mobile/src/forge/assets/FSkin.java b/forge-gui-mobile/src/forge/assets/FSkin.java index eb70ab5e237..2cadcf0a9b9 100644 --- a/forge-gui-mobile/src/forge/assets/FSkin.java +++ b/forge-gui-mobile/src/forge/assets/FSkin.java @@ -217,9 +217,12 @@ public class FSkin { final FileHandle f11 = getSkinFile(ForgeConstants.SPRITE_BUTTONS_FILE); final FileHandle f12 = getSkinFile(ForgeConstants.SPRITE_START_FILE); final FileHandle f13 = getDefaultSkinFile(ForgeConstants.SPRITE_DECKBOX_FILE); + + /*TODO Themeable final FileHandle f14 = getDefaultSkinFile(ForgeConstants.SPRITE_SETLOGO_FILE); final FileHandle f15 = getSkinFile(ForgeConstants.SPRITE_SETLOGO_FILE); final FileHandle f16 = getDefaultSkinFile(ForgeConstants.SPRITE_WATERMARK_FILE); + */ try { textures.put(f1.path(), new Texture(f1)); diff --git a/forge-gui-mobile/src/forge/assets/FSkinImage.java b/forge-gui-mobile/src/forge/assets/FSkinImage.java index af1258cd27b..e70cbd8bf5f 100644 --- a/forge-gui-mobile/src/forge/assets/FSkinImage.java +++ b/forge-gui-mobile/src/forge/assets/FSkinImage.java @@ -115,6 +115,28 @@ public enum FSkinImage implements FImage { WATERMARK_W (FSkinProp.IMG_WATERMARK_W, SourceFile.WATERMARKS), WATERMARK_C (FSkinProp.IMG_WATERMARK_C, SourceFile.WATERMARKS), + //CardBG + CARDBG_A (FSkinProp.IMG_CARDBG_A, SourceFile.CARDBG), + CARDBG_B (FSkinProp.IMG_CARDBG_B, SourceFile.CARDBG), + CARDBG_BG (FSkinProp.IMG_CARDBG_BG, SourceFile.CARDBG), + CARDBG_BR (FSkinProp.IMG_CARDBG_BR, SourceFile.CARDBG), + CARDBG_C (FSkinProp.IMG_CARDBG_C, SourceFile.CARDBG), + CARDBG_G (FSkinProp.IMG_CARDBG_G, SourceFile.CARDBG), + CARDBG_L (FSkinProp.IMG_CARDBG_L, SourceFile.CARDBG), + CARDBG_M (FSkinProp.IMG_CARDBG_M, SourceFile.CARDBG), + CARDBG_R (FSkinProp.IMG_CARDBG_R, SourceFile.CARDBG), + CARDBG_RG (FSkinProp.IMG_CARDBG_RG, SourceFile.CARDBG), + CARDBG_U (FSkinProp.IMG_CARDBG_U, SourceFile.CARDBG), + CARDBG_UB (FSkinProp.IMG_CARDBG_UB, SourceFile.CARDBG), + CARDBG_UG (FSkinProp.IMG_CARDBG_UG, SourceFile.CARDBG), + CARDBG_UR (FSkinProp.IMG_CARDBG_UR, SourceFile.CARDBG), + CARDBG_V (FSkinProp.IMG_CARDBG_V, SourceFile.CARDBG), + CARDBG_W (FSkinProp.IMG_CARDBG_W, SourceFile.CARDBG), + CARDBG_WB (FSkinProp.IMG_CARDBG_WB, SourceFile.CARDBG), + CARDBG_WG (FSkinProp.IMG_CARDBG_WG, SourceFile.CARDBG), + CARDBG_WR (FSkinProp.IMG_CARDBG_WR, SourceFile.CARDBG), + CARDBG_WU (FSkinProp.IMG_CARDBG_WU, SourceFile.CARDBG), + //Gameplay TAP (FSkinProp.IMG_TAP, SourceFile.MANAICONS), UNTAP (FSkinProp.IMG_UNTAP, SourceFile.MANAICONS), @@ -439,6 +461,7 @@ public enum FSkinImage implements FImage { MANAICONS(ForgeConstants.SPRITE_MANAICONS_FILE), SETLOGOS(ForgeConstants.SPRITE_SETLOGO_FILE), WATERMARKS(ForgeConstants.SPRITE_WATERMARK_FILE), + CARDBG(ForgeConstants.SPRITE_CARDBG_FILE), PLANAR_CONQUEST(ForgeConstants.SPRITE_PLANAR_CONQUEST_FILE); private final String filename; diff --git a/forge-gui-mobile/src/forge/assets/FTextureImage.java b/forge-gui-mobile/src/forge/assets/FTextureImage.java index a1316961b11..292d97c083e 100644 --- a/forge-gui-mobile/src/forge/assets/FTextureImage.java +++ b/forge-gui-mobile/src/forge/assets/FTextureImage.java @@ -2,6 +2,7 @@ package forge.assets; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import forge.Graphics; public class FTextureImage extends FImageComplex { @@ -26,6 +27,11 @@ public class FTextureImage extends FImageComplex { return texture; } + @Override + public TextureRegion getTextureRegion() { + return new TextureRegion(texture); + } + @Override public int getRegionX() { return 0; diff --git a/forge-gui-mobile/src/forge/assets/FTextureRegionImage.java b/forge-gui-mobile/src/forge/assets/FTextureRegionImage.java index 1f5ed033593..dcd6c914b1b 100644 --- a/forge-gui-mobile/src/forge/assets/FTextureRegionImage.java +++ b/forge-gui-mobile/src/forge/assets/FTextureRegionImage.java @@ -27,6 +27,11 @@ public class FTextureRegionImage extends FImageComplex { return textureRegion.getTexture(); } + @Override + public TextureRegion getTextureRegion() { + return textureRegion; + } + @Override public int getRegionX() { return textureRegion.getRegionX(); diff --git a/forge-gui-mobile/src/forge/card/CardAvatarImage.java b/forge-gui-mobile/src/forge/card/CardAvatarImage.java index 6609ca06c35..953937da8a3 100644 --- a/forge-gui-mobile/src/forge/card/CardAvatarImage.java +++ b/forge-gui-mobile/src/forge/card/CardAvatarImage.java @@ -32,7 +32,7 @@ public class CardAvatarImage implements FImage { @Override public void draw(Graphics g, float x, float y, float w, float h) { //force to get the avatar since the the cardartcache & loadingcache is always cleared on screen change or the battle bar will display black - image = CardRenderer.getCardArt(imageKey, false, false, false); + image = CardRenderer.getCardArt(imageKey, false, false, false, false, false, false, false, false); if (image == null) { return; //can't draw anything if can't be loaded yet } diff --git a/forge-gui-mobile/src/forge/card/CardImage.java b/forge-gui-mobile/src/forge/card/CardImage.java index 6d2e7be323e..aa7f338cd8e 100644 --- a/forge-gui-mobile/src/forge/card/CardImage.java +++ b/forge-gui-mobile/src/forge/card/CardImage.java @@ -38,14 +38,14 @@ public class CardImage implements FImage { image = ImageCache.getImage(card); if (image == null) { if (!Forge.enableUIMask.equals("Off")) //render this if mask is still loading - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top); + CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top, Forge.enableUIMask.equals("Art")); return; //can't draw anything if can't be loaded yet } } - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top); + if (image == ImageCache.defaultImage || Forge.enableUIMask.equals("Art")) { + CardImageRenderer.drawCardImage(g, CardView.getCardForUi(card), false, x, y, w, h, CardStackPosition.Top, true); } else { if (Forge.enableUIMask.equals("Full")) { diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index ac665e22964..5c25b33d81b 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -6,6 +6,9 @@ import static forge.card.CardRenderer.isModernFrame; import java.util.ArrayList; import java.util.List; +import forge.ImageKeys; +import forge.assets.*; +import forge.util.ImageUtil; import org.apache.commons.lang3.StringUtils; import com.badlogic.gdx.graphics.Color; @@ -15,15 +18,6 @@ import com.google.common.collect.ImmutableList; import forge.Forge; import forge.Graphics; -import forge.assets.FBufferedImage; -import forge.assets.FImage; -import forge.assets.FSkin; -import forge.assets.FSkinColor; -import forge.assets.FSkinFont; -import forge.assets.FSkinImage; -import forge.assets.FSkinTexture; -import forge.assets.ImageCache; -import forge.assets.TextRenderer; import forge.card.CardRenderer.CardStackPosition; import forge.card.mana.ManaCost; import forge.game.GameView; @@ -48,6 +42,10 @@ public class CardImageRenderer { private static float prevImageWidth, prevImageHeight; private static final float BLACK_BORDER_THICKNESS_RATIO = 0.021f; + private static Color fromDetailColor(DetailColors detailColor) { + return FSkinColor.fromRGB(detailColor.r, detailColor.g, detailColor.b); + } + public static void forceStaticFieldUpdate() { //force static fields to be updated the next time a card image is rendered prevImageWidth = 0; @@ -78,13 +76,17 @@ public class CardImageRenderer { public static void drawFaceDownCard(CardView card, Graphics g, float x, float y, float w, float h) { //try to draw the card sleeves first - if (FSkin.getSleeves().get(card.getOwner()) != null) - g.drawImage(FSkin.getSleeves().get(card.getOwner()), x, y, w, h); + FImage sleeves = MatchController.getPlayerSleeve(card.getOwner()); + if (sleeves != null) + g.drawImage(sleeves, x, y, w, h); else - drawArt(g, x, y, w, h); + drawArt(null, g, x, y, w, h, false, true); } - public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos) { + public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos, boolean useCardBGTexture) { + drawCardImage(g, card, altState, x, y, w, h, pos, useCardBGTexture, false, false); + } + public static void drawCardImage(Graphics g, CardView card, boolean altState, float x, float y, float w, float h, CardStackPosition pos, boolean useCardBGTexture, boolean noText, boolean isChoiceList) { updateStaticFields(w, h); float blackBorderThickness = w * BLACK_BORDER_THICKNESS_RATIO; @@ -94,8 +96,16 @@ public class CardImageRenderer { w -= 2 * blackBorderThickness; h -= 2 * blackBorderThickness; - final CardStateView state = card.getState(altState); + CardStateView state = altState ? card.getAlternateState() : isChoiceList && card.isSplitCard() ? card.getLeftSplitState() : card.getCurrentState(); + final boolean isFaceDown = card.isFaceDown(); final boolean canShow = MatchController.instance.mayView(card); + //override + if (isFaceDown && altState && card.isSplitCard()) + state = card.getLeftSplitState(); + boolean isSaga = state.getType().hasSubtype("Saga"); + boolean isClass = state.getType().hasSubtype("Class"); + boolean isDungeon = state.getType().isDungeon(); + boolean drawDungeon = isDungeon && CardRenderer.getCardArt(card) != null; if (!canShow) { drawFaceDownCard(card, g, x, y, w, h); @@ -104,14 +114,12 @@ public class CardImageRenderer { //determine colors for borders final List borderColors; - final boolean isFaceDown = card.isFaceDown(); if (isFaceDown) { - borderColors = ImmutableList.of(DetailColors.FACE_DOWN); - } - else { + borderColors = !altState ? ImmutableList.of(DetailColors.FACE_DOWN) : !useCardBGTexture ? ImmutableList.of(DetailColors.FACE_DOWN) : CardDetailUtil.getBorderColors(state, canShow); + } else { borderColors = CardDetailUtil.getBorderColors(state, canShow); } - Color[] colors = fillColorBackground(g, borderColors, x, y, w, h); + Color[] colors = useCardBGTexture ? drawCardBackgroundTexture(state, g, borderColors, x, y, w, h) : fillColorBackground(g, borderColors, x, y, w, h); float artInset = blackBorderThickness * 0.5f; float outerBorderThickness = 2 * blackBorderThickness - artInset; @@ -122,7 +130,7 @@ public class CardImageRenderer { //draw header containing name and mana cost Color[] headerColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.NAME_BOX_TINT); - drawHeader(g, card, state, headerColors, x, y, w, headerHeight); + drawHeader(g, card, state, headerColors, x, y, w, headerHeight, isFaceDown && !altState); if (pos == CardStackPosition.BehindVert) { return; } //remaining rendering not needed if card is behind another card in a vertical stack boolean onTop = (pos == CardStackPosition.Top); @@ -156,53 +164,95 @@ public class CardImageRenderer { //draw art box with Forge icon if (artHeight > 0) { - drawArt(g, x + artInset, y, artWidth, artHeight); + if (isSaga) + drawArt(card, g, x + artInset+(artWidth/2), y, artWidth/2, artHeight+textBoxHeight, altState, isFaceDown); + else if (isClass) + drawArt(card, g, x + artInset, y, artWidth/2, artHeight+textBoxHeight, altState, isFaceDown); + else if (isDungeon) { + if (drawDungeon) { + drawArt(card, g, x + artInset, y, artWidth, artHeight+textBoxHeight, altState, isFaceDown); + y += textBoxHeight; + } + } + else + drawArt(card, g, x + artInset, y, artWidth, artHeight, altState, isFaceDown); y += artHeight; } - //draw type line - drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight); - y += typeBoxHeight; + if (isSaga) { + //draw text box + Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); + drawTextBox(g, card, state, textBoxColors, x + artInset, y-artHeight, (w - 2 * artInset)/2, textBoxHeight+artHeight, onTop, useCardBGTexture, noText); + y += textBoxHeight; - //draw text box - Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); - drawTextBox(g, card, state, textBoxColors, x + artInset, y, w - 2 * artInset, textBoxHeight, onTop); - y += textBoxHeight; + //draw type line + drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight, noText); + y += typeBoxHeight; + } else if (isClass) { + //draw text box + Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); + drawTextBox(g, card, state, textBoxColors, x + artInset+(artWidth/2), y-artHeight, (w - 2 * artInset)/2, textBoxHeight+artHeight, onTop, useCardBGTexture, noText); + y += textBoxHeight; + + //draw type line + drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight, noText); + y += typeBoxHeight; + } else if (isDungeon) { + if (!drawDungeon) { + //draw textbox + Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); + drawTextBox(g, card, state, textBoxColors, x + artInset, y-artHeight, (w - 2 * artInset), textBoxHeight+artHeight, onTop, useCardBGTexture, noText); + y += textBoxHeight; + } + drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight, noText); + y += typeBoxHeight; + } else { + //draw type line + drawTypeLine(g, card, state, canShow, headerColors, x, y, w, typeBoxHeight, noText); + y += typeBoxHeight; + + //draw text box + Color[] textBoxColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.TEXT_BOX_TINT); + drawTextBox(g, card, state, textBoxColors, x + artInset, y, w - 2 * artInset, textBoxHeight, onTop, useCardBGTexture, noText); + y += textBoxHeight; + } //draw P/T box if (onTop && ptBoxHeight > 0) { //only needed if on top since otherwise P/T will be hidden Color[] ptColors = FSkinColor.tintColors(Color.WHITE, colors, CardRenderer.PT_BOX_TINT); - drawPtBox(g, card, state, ptColors, x, y - 2 * artInset, w, ptBoxHeight); + drawPtBox(g, card, state, ptColors, x, y - 2 * artInset, w, ptBoxHeight, noText); } } - private static void drawHeader(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h) { + private static void drawHeader(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h, boolean noText) { fillColorBackground(g, colors, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); float padding = h / 8; - - //draw mana cost for card float manaCostWidth = 0; - ManaCost mainManaCost = state.getManaCost(); - if (card.isSplitCard() && card.getAlternateState() != null) { - //handle rendering both parts of split card - mainManaCost = card.getLeftSplitState().getManaCost(); - ManaCost otherManaCost = card.getAlternateState().getManaCost(); - manaCostWidth = CardFaceSymbols.getWidth(otherManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, otherManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); - //draw "//" between two parts of mana cost - manaCostWidth += NAME_FONT.getBounds("//").width + HEADER_PADDING; - g.drawText("//", NAME_FONT, Color.BLACK, x + w - manaCostWidth, y, w, h, false, Align.left, true); + if (!noText) { + //draw mana cost for card + ManaCost mainManaCost = state.getManaCost(); + if (card.isSplitCard() && card.getAlternateState() != null) { + //handle rendering both parts of split card + mainManaCost = card.getLeftSplitState().getManaCost(); + ManaCost otherManaCost = card.getRightSplitState().getManaCost(); + manaCostWidth = CardFaceSymbols.getWidth(otherManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; + CardFaceSymbols.drawManaCost(g, otherManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); + //draw "//" between two parts of mana cost + manaCostWidth += NAME_FONT.getBounds("//").width + HEADER_PADDING; + g.drawText("//", NAME_FONT, Color.BLACK, x + w - manaCostWidth, y, w, h, false, Align.left, true); + } + manaCostWidth += CardFaceSymbols.getWidth(mainManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; + CardFaceSymbols.drawManaCost(g, mainManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); } - manaCostWidth += CardFaceSymbols.getWidth(mainManaCost, MANA_SYMBOL_SIZE) + HEADER_PADDING; - CardFaceSymbols.drawManaCost(g, mainManaCost, x + w - manaCostWidth, y + (h - MANA_SYMBOL_SIZE) / 2, MANA_SYMBOL_SIZE); //draw name for card x += padding; w -= 2 * padding; - g.drawText(CardTranslation.getTranslatedName(state.getName()), NAME_FONT, Color.BLACK, x, y, w - manaCostWidth - padding, h, false, Align.left, true); + if (!noText) + g.drawText(CardTranslation.getTranslatedName(state.getName()), NAME_FONT, Color.BLACK, x, y, w - manaCostWidth - padding, h, false, Align.left, true); } public static final FBufferedImage forgeArt; @@ -221,12 +271,95 @@ public class CardImageRenderer { }; } - private static void drawArt(Graphics g, float x, float y, float w, float h) { - g.drawImage(forgeArt, x, y, w, h); + private static void drawArt(CardView cv, Graphics g, float x, float y, float w, float h, boolean altState, boolean isFaceDown) { + if (cv == null) { + if (isFaceDown) { + Texture cardBack = ImageCache.getImage(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD), false); + if (cardBack != null) { + g.drawImage(cardBack, x, y, w, h); + return; + } + } + //fallback + g.drawImage(forgeArt, x, y, w, h); + g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); + return; + } + if (Forge.enableUIMask.equals("Art")) { + FImageComplex cardArt = CardRenderer.getCardArt(cv); + FImageComplex altArt = cardArt; + boolean isHidden = (cv.getCurrentState().getImageKey().equals(ImageKeys.getTokenKey(ImageKeys.HIDDEN_CARD)) + || cv.getCurrentState().getImageKey().equals(ImageKeys.getTokenKey(ImageKeys.FORETELL_IMAGE))); + if (cardArt != null) { + if (isHidden && !altState) { + g.drawImage(forgeArt, x, y, w, h); + } else if (cv.getCurrentState().getImageKey().equals(ImageKeys.getTokenKey(ImageKeys.MANIFEST_IMAGE)) && !altState) { + altArt = CardRenderer.getAlternateCardArt(ImageKeys.getTokenKey(ImageKeys.MANIFEST_IMAGE), false); + g.drawImage(altArt, x, y, w, h); + } else if (cv.getCurrentState().getImageKey().equals(ImageKeys.getTokenKey(ImageKeys.MORPH_IMAGE)) && !altState) { + altArt = CardRenderer.getAlternateCardArt(ImageKeys.getTokenKey(ImageKeys.MORPH_IMAGE), false); + g.drawImage(altArt, x, y, w, h); + } else { + if (cv.hasAlternateState()) { + if (altState) { + if (cv.getAlternateState().isPlaneswalker()) + altArt = CardRenderer.getAlternateCardArt(cv.getAlternateState().getImageKey(), cv.getAlternateState().isPlaneswalker()); + else { + altArt = CardRenderer.getCardArt(cv.getAlternateState().getImageKey(), cv.isSplitCard(), cv.getAlternateState().isPlane() || cv.getAlternateState().isPhenomenon(), cv.getText().contains("Aftermath"), + cv.getAlternateState().getType().hasSubtype("Saga"), cv.getAlternateState().getType().hasSubtype("Class"), cv.getAlternateState().getType().isDungeon(), cv.isFlipCard(), cv.getAlternateState().isPlaneswalker()); + } + } + } + if (cv.isSplitCard()) { + drawSplitCard(cv, altArt, g, x, y, w, h, altState, isFaceDown); + } else if (cv.isFlipCard()) { + drawFlipCard(isFaceDown ? altArt : cardArt, g, x, y, w, h, altState); + } else { + g.drawImage(altArt, x, y, w, h); + } + } + } else { + g.drawImage(forgeArt, x, y, w, h); + } + } else { + g.drawImage(forgeArt, x, y, w, h); + } g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); } - - private static void drawTypeLine(Graphics g, CardView card, CardStateView state, boolean canShow, Color[] colors, float x, float y, float w, float h) { + private static void drawSplitCard(CardView card, FImageComplex cardArt, Graphics g, float x, float y, float w, float h, boolean altState, boolean isFaceDown) { + CardView alt = CardView.getCardForUi(ImageUtil.getPaperCardFromImageKey(card.getAlternateState().getImageKey())); + if (alt == null) + alt = card.getAlternateState().getCard(); + CardView cv = altState && isFaceDown ? alt : card; + boolean isAftermath = altState ? cv.getAlternateState().hasHasAftermath(): cv.getRightSplitState().hasHasAftermath(); + if (!isAftermath) { + CardEdition ed = FModel.getMagicDb().getEditions().get(cv.getCurrentState().getSetCode()); + boolean isOldFrame = ed != null && !ed.isModern(); + float modH = isOldFrame ? cardArt.getHeight()/12f : 0f; + float modW = !isOldFrame ? cardArt.getWidth()/12f : 0f; + float modW2 = !isOldFrame ? cardArt.getWidth()/6f : 0f; + float srcY = cardArt.getHeight() * 13f / 354f; + float srcHeight = cardArt.getHeight() * 190f / 354f; + float dh = srcHeight * (1 - cardArt.getWidth() / srcHeight / CardRenderer.CARD_ART_RATIO); + srcHeight -= dh; + srcY += dh / 2; + g.drawRotatedImage(cardArt.getTexture(), x, y, h+modH, w / 2, x + w / 2, y + w / 2, cardArt.getRegionX()+(int)modW, (int)srcY, (int)(cardArt.getWidth()-modW2), (int)srcHeight, -90); + g.drawRotatedImage(cardArt.getTexture(), x, y + w / 2, h+modH, w / 2, x + w / 2, y + w / 2, cardArt.getRegionX()+(int)modW, (int)cardArt.getHeight() - (int)(srcY + srcHeight), (int)(cardArt.getWidth()-modW2), (int)srcHeight, -90); + g.drawLine(BORDER_THICKNESS, Color.BLACK, x+w/2, y, x+w/2, y+h); + } else { + FImageComplex secondArt = CardRenderer.getAftermathSecondCardArt(cv.getCurrentState().getImageKey()); + g.drawRotatedImage(cardArt.getTexture(), x, y, w, h / 2, x + w, y + h / 2, cardArt.getRegionX(), cardArt.getRegionY(), (int)cardArt.getWidth(), (int)cardArt.getHeight() /2, 0); + g.drawRotatedImage(secondArt.getTexture(), x - h / 2 , y + h / 2, h /2, w, x, y + h / 2, secondArt.getRegionX(), secondArt.getRegionY(), (int)secondArt.getWidth(), (int)secondArt.getHeight(), 90); + g.drawLine(BORDER_THICKNESS, Color.BLACK, x, y+h/2, x+w, y+h/2); + } + } + private static void drawFlipCard(FImageComplex cardArt, Graphics g, float x, float y, float w, float h, boolean altState) { + if (altState) + g.drawRotatedImage(cardArt.getTextureRegion(), x, y, w, h, x + w / 2, y + h / 2, 180); + else + g.drawImage(cardArt, x, y, w, h); + } + private static void drawTypeLine(Graphics g, CardView card, CardStateView state, boolean canShow, Color[] colors, float x, float y, float w, float h, boolean noText) { fillColorBackground(g, colors, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); @@ -252,6 +385,8 @@ public class CardImageRenderer { } //draw type + if (noText) + return; x += padding; g.drawText(CardDetailUtil.formatCardType(state, canShow), TYPE_FONT, Color.BLACK, x, y, w, h, false, Align.left, true); } @@ -259,7 +394,9 @@ public class CardImageRenderer { //use text renderer to handle mana symbols and reminder text private static final TextRenderer cardTextRenderer = new TextRenderer(true); - private static void drawTextBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h, boolean onTop) { + private static void drawTextBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h, boolean onTop, boolean useCardBGTexture, boolean noText) { + boolean fakeDuals = false; + //update land bg colors if (state.isLand()) { DetailColors modColors = DetailColors.WHITE; if (state.isBasicLand()) { @@ -273,49 +410,137 @@ public class CardImageRenderer { modColors = DetailColors.BLACK; else if (state.isPlains()) modColors = DetailColors.LAND; + } if (state.origCanProduceColoredMana() == 2) { + //dual colors + Color[] colorPairs = new Color[2]; + Color[] colorPairsBackup = new Color[2]; + //init Color + colorPairs[0] = fromDetailColor(DetailColors.WHITE); + colorPairs[1] = fromDetailColor(DetailColors.WHITE); + //override + if (state.origProduceAnyMana()) { + colorPairs[0] = fromDetailColor(DetailColors.MULTICOLOR); + colorPairs[1] = fromDetailColor(DetailColors.MULTICOLOR); + } else { + fakeDuals = true; + if (state.origProduceManaW() && state.origProduceManaU()) { + colorPairs[0] = fromDetailColor(DetailColors.LAND); + colorPairs[1] = fromDetailColor(DetailColors.BLUE); + } else if (state.origProduceManaW() && state.origProduceManaB()) { + colorPairs[0] = fromDetailColor(DetailColors.LAND); + colorPairs[1] = fromDetailColor(DetailColors.BLACK); + } else if (state.origProduceManaW() && state.origProduceManaR()) { + colorPairs[0] = fromDetailColor(DetailColors.LAND); + colorPairs[1] = fromDetailColor(DetailColors.RED); + } else if (state.origProduceManaW() && state.origProduceManaG()) { + colorPairs[0] = fromDetailColor(DetailColors.LAND); + colorPairs[1] = fromDetailColor(DetailColors.GREEN); + } else if (state.origProduceManaU() && state.origProduceManaB()) { + colorPairs[0] = fromDetailColor(DetailColors.BLUE); + colorPairs[1] = fromDetailColor(DetailColors.BLACK); + } else if (state.origProduceManaU() && state.origProduceManaR()) { + colorPairs[0] = fromDetailColor(DetailColors.BLUE); + colorPairs[1] = fromDetailColor(DetailColors.RED); + } else if (state.origProduceManaU() && state.origProduceManaG()) { + colorPairs[0] = fromDetailColor(DetailColors.BLUE); + colorPairs[1] = fromDetailColor(DetailColors.GREEN); + } else if (state.origProduceManaB() && state.origProduceManaR()) { + colorPairs[0] = fromDetailColor(DetailColors.BLACK); + colorPairs[1] = fromDetailColor(DetailColors.RED); + } else if (state.origProduceManaB() && state.origProduceManaG()) { + colorPairs[0] = fromDetailColor(DetailColors.BLACK); + colorPairs[1] = fromDetailColor(DetailColors.GREEN); + } else if (state.origProduceManaR() && state.origProduceManaG()) { + colorPairs[0] = fromDetailColor(DetailColors.RED); + colorPairs[1] = fromDetailColor(DetailColors.GREEN); + } + } + colorPairsBackup = colorPairs; + colorPairs = FSkinColor.tintColors(Color.WHITE, colorPairs, 0.3f); + float oldAlpha = g.getfloatAlphaComposite(); + if (!useCardBGTexture) + fillColorBackground(g, colorPairs, x, y, w, h); + else { + g.setAlphaComposite(0.95f); + fillColorBackground(g, colorPairs, x, y, w, h); + if (fakeDuals && state.countBasicLandTypes() == 2) { + float thickness = h/16f; + float mod = 2f*thickness/2f; + g.setAlphaComposite(0.2f); + drawAlphaLines(colorPairsBackup, g, x, y, w, h, thickness, mod); + } + g.setAlphaComposite(oldAlpha); + } + } else { + //override bg color + if (state.origCanProduceColoredMana() > 2 || state.origProduceAnyMana()) { + modColors = DetailColors.MULTICOLOR; + } else if (state.origCanProduceColoredMana() == 1) { + if (state.origProduceManaW()) + modColors = DetailColors.LAND; + else if (state.origProduceManaB()) + modColors = DetailColors.BLACK; + else if (state.origProduceManaG()) + modColors = DetailColors.GREEN; + else if (state.origProduceManaR()) + modColors = DetailColors.RED; + else if (state.origProduceManaU()) + modColors = DetailColors.BLUE; + } + Color bgColor = fromDetailColor(modColors); + bgColor = FSkinColor.tintColor(Color.WHITE, bgColor, CardRenderer.NAME_BOX_TINT); + float oldAlpha = g.getfloatAlphaComposite(); + if (!useCardBGTexture) + g.fillRect(bgColor, x, y, w, h); + else { + g.setAlphaComposite(0.95f); + g.fillRect(bgColor, x, y, w, h); + g.setAlphaComposite(oldAlpha); + } } - Color bgColor = FSkinColor.fromRGB(modColors.r, modColors.g, modColors.b); - bgColor = FSkinColor.tintColor(Color.WHITE, bgColor, CardRenderer.NAME_BOX_TINT); - g.fillRect(bgColor, x, y, w, h); } else { - fillColorBackground(g, colors, x, y, w, h); + float oldAlpha = g.getfloatAlphaComposite(); + if (!useCardBGTexture) + fillColorBackground(g, colors, x, y, w, h); + else { + g.setAlphaComposite(0.95f); + fillColorBackground(g, colors, x, y, w, h); + g.setAlphaComposite(oldAlpha); + } } g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); if (!onTop) { return; } //remaining rendering only needed if card on top if (state.isBasicLand()) { - //draw icons for basic lands - FSkinImage image; - switch (state.getName().replaceFirst("^Snow-Covered ", "")) { - case "Plains": - image = FSkinImage.WATERMARK_W; - break; - case "Island": - image = FSkinImage.WATERMARK_U; - break; - case "Swamp": - image = FSkinImage.WATERMARK_B; - break; - case "Mountain": - image = FSkinImage.WATERMARK_R; - break; - case "Forest": - image = FSkinImage.WATERMARK_G; - break; - default: + //draw watermark + FSkinImage image = null; + if (state.origCanProduceColoredMana() == 1 && !state.origProduceManaC()) { + if (state.isPlains()) + image = FSkinImage.WATERMARK_W; + else if (state.isIsland()) + image = FSkinImage.WATERMARK_U; + else if (state.isSwamp()) + image = FSkinImage.WATERMARK_B; + else if (state.isMountain()) + image = FSkinImage.WATERMARK_R; + else if (state.isForest()) + image = FSkinImage.WATERMARK_G; + } else if (state.origProduceManaC()) { image = FSkinImage.WATERMARK_C; - break; } - float iconSize = h * 0.75f; - g.drawImage(image, x + (w - iconSize) / 2, y + (h - iconSize) / 2, iconSize, iconSize); - } - else { + if (image != null) { + float iconSize = h * 0.75f; + g.drawImage(image, x + (w - iconSize) / 2, y + (h - iconSize) / 2, iconSize, iconSize); + } + } else { boolean needTranslation = true; if (card.isToken()) { if (card.getCloneOrigin() == null) needTranslation = false; } + if (noText) + return; final String text = !card.isSplitCard() ? card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(state.getName(), "") : null) : card.getText(state, needTranslation ? CardTranslation.getTranslationTexts(card.getLeftSplitState().getName(), card.getRightSplitState().getName()) : null ); @@ -329,8 +554,24 @@ public class CardImageRenderer { cardTextRenderer.drawText(g, text, TEXT_FONT, Color.BLACK, x, y, w, h, y, h, true, Align.left, true); } } - - private static void drawPtBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h) { + private static void drawAlphaLines(Color[] colors, Graphics g, float x, float y, float w, float h, float thickness, float mod) { + g.drawRectLines(thickness, colors[1], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 4f*thickness/2f; + g.drawRectLines(thickness, colors[0], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 6f*thickness/2f; + g.drawRectLines(thickness, colors[1], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 8f*thickness/2f; + g.drawRectLines(thickness, colors[0], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 10f*thickness/2f; + g.drawRectLines(thickness, colors[1], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 12f*thickness/2f; + g.drawRectLines(thickness, colors[0], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 14f*thickness/2f; + g.drawRectLines(thickness, colors[1], x+mod, y+mod, w-(mod*2f), h-(mod*2f)); + mod = 16f*thickness/2f; + g.drawLine(thickness, colors[1], x+mod, y+mod, x+w-mod, y+mod); + } + private static void drawPtBox(Graphics g, CardView card, CardStateView state, Color[] colors, float x, float y, float w, float h, boolean noText) { List pieces = new ArrayList<>(); if (state.isCreature()) { pieces.add(String.valueOf(state.getPower())); @@ -369,6 +610,8 @@ public class CardImageRenderer { fillColorBackground(g, colors, x, y, w, h); g.drawRect(BORDER_THICKNESS, Color.BLACK, x, y, w, h); + if (noText) + return; x += (boxWidth - totalPieceWidth) / 2; for (int i = 0; i < pieces.size(); i++) { g.drawText(pieces.get(i), PT_FONT, Color.BLACK, x, y, w, h, false, Align.left, true); @@ -399,8 +642,8 @@ public class CardImageRenderer { return; } - if (image == ImageCache.defaultImage) { //support drawing card image manually if card image not found - drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top); + if (image == ImageCache.defaultImage || Forge.enableUIMask.equals("Art")) { //support drawing card image manually if card image not found + drawCardImage(g, card, altState, x, y, w, h, CardStackPosition.Top, true); } else { float radius = (h - w)/8; float wh_Adj = ForgeConstants.isGdxPortLandscape && isCurrentCard ? 1.38f:1.0f; @@ -517,11 +760,79 @@ public class CardImageRenderer { Color[] colors = new Color[backColors.size()]; for (int i = 0; i < colors.length; i++) { DetailColors dc = backColors.get(i); - colors[i] = FSkinColor.fromRGB(dc.r, dc.g, dc.b); + colors[i] = fromDetailColor(dc); } fillColorBackground(g, colors, x, y, w, h); return colors; } + public static Color[] drawCardBackgroundTexture(CardStateView state, Graphics g, List backColors, float x, float y, float w, float h) { + boolean isHybrid = state.getManaCost().hasHybrid(); + Color[] colors = new Color[backColors.size()]; + for (int i = 0; i < colors.length; i++) { + DetailColors dc = backColors.get(i); + colors[i] = fromDetailColor(dc); + } + switch (backColors.size()) { + case 1: + if (backColors.get(0) == DetailColors.FACE_DOWN) { + g.drawImage(FSkinImage.CARDBG_C, x, y, w,h); + } else if (backColors.get(0) == DetailColors.LAND) { + g.drawImage(FSkinImage.CARDBG_L, x, y, w,h); + }else if (backColors.get(0) == DetailColors.MULTICOLOR) { + g.drawImage(FSkinImage.CARDBG_M, x, y, w,h); + } else if (backColors.get(0) == DetailColors.COLORLESS) { + if (state.isVehicle()) + g.drawImage(FSkinImage.CARDBG_V, x, y, w,h); + else if (state.isArtifact()) + g.drawImage(FSkinImage.CARDBG_A, x, y, w,h); + else + g.drawImage(FSkinImage.CARDBG_C, x, y, w,h); + } else if (backColors.get(0) == DetailColors.GREEN) { + g.drawImage(FSkinImage.CARDBG_G, x, y, w,h); + } else if (backColors.get(0) == DetailColors.RED) { + g.drawImage(FSkinImage.CARDBG_R, x, y, w,h); + } else if (backColors.get(0) == DetailColors.BLACK) { + g.drawImage(FSkinImage.CARDBG_B, x, y, w,h); + } else if (backColors.get(0) == DetailColors.BLUE) { + g.drawImage(FSkinImage.CARDBG_U, x, y, w,h); + } else if (backColors.get(0) == DetailColors.WHITE) { + g.drawImage(FSkinImage.CARDBG_W, x, y, w,h); + } + break; + case 2: + if (!isHybrid) { + g.drawImage(FSkinImage.CARDBG_M, x, y, w, h); + } else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLUE)) { + g.drawImage(FSkinImage.CARDBG_WU, x, y, w, h); + } else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.BLACK)) { + g.drawImage(FSkinImage.CARDBG_WB, x, y, w, h); + } else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.RED)) { + g.drawImage(FSkinImage.CARDBG_WR, x, y, w, h); + } else if (backColors.contains(DetailColors.WHITE) && backColors.contains(DetailColors.GREEN)) { + g.drawImage(FSkinImage.CARDBG_WG, x, y, w, h); + } else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.BLACK)) { + g.drawImage(FSkinImage.CARDBG_UB, x, y, w, h); + } else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.RED)) { + g.drawImage(FSkinImage.CARDBG_UR, x, y, w, h); + } else if (backColors.contains(DetailColors.BLUE) && backColors.contains(DetailColors.GREEN)) { + g.drawImage(FSkinImage.CARDBG_UG, x, y, w, h); + } else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.RED)) { + g.drawImage(FSkinImage.CARDBG_BR, x, y, w, h); + } else if (backColors.contains(DetailColors.BLACK) && backColors.contains(DetailColors.GREEN)) { + g.drawImage(FSkinImage.CARDBG_BG, x, y, w, h); + } else if (backColors.contains(DetailColors.RED) && backColors.contains(DetailColors.GREEN)) { + g.drawImage(FSkinImage.CARDBG_RG, x, y, w, h); + } + break; + case 3: + g.drawImage(FSkinImage.CARDBG_M, x, y, w, h); + break; + default: + g.drawImage(FSkinImage.CARDBG_C, x, y, w,h); + break; + } + return colors; + } public static void fillColorBackground(Graphics g, Color[] colors, float x, float y, float w, float h) { switch (colors.length) { case 1: diff --git a/forge-gui-mobile/src/forge/card/CardRenderer.java b/forge-gui-mobile/src/forge/card/CardRenderer.java index fcd57e85d93..992a5811e1d 100644 --- a/forge-gui-mobile/src/forge/card/CardRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardRenderer.java @@ -207,15 +207,15 @@ public class CardRenderer { public static FImageComplex getCardArt(IPaperCard pc, boolean backFace) { CardType type = pc.getRules().getType(); - return getCardArt(pc.getImageKey(backFace), pc.getRules().getSplitType() == CardSplitType.Split, type.isPlane() || type.isPhenomenon(),pc.getRules().getOracleText().contains("Aftermath")); + return getCardArt(pc.getImageKey(backFace), pc.getRules().getSplitType() == CardSplitType.Split, type.isPlane() || type.isPhenomenon(),pc.getRules().getOracleText().contains("Aftermath"), type.hasSubtype("Saga"), type.hasSubtype("Class"), type.isDungeon(), CardSplitType.Flip.equals(pc.getRules().getSplitType()), type.isPlaneswalker()); } public static FImageComplex getCardArt(CardView card) { CardTypeView type = card.getCurrentState().getType(); - return getCardArt(card.getCurrentState().getImageKey(), card.isSplitCard(), type.isPlane() || type.isPhenomenon(),card.getText().contains("Aftermath")); + return getCardArt(card.getCurrentState().getImageKey(), card.isSplitCard(), type.isPlane() || type.isPhenomenon(),card.getText().contains("Aftermath"), type.hasSubtype("Saga"), type.hasSubtype("Class"), type.isDungeon(), card.isFlipCard(), type.isPlaneswalker()); } - public static FImageComplex getCardArt(String imageKey, boolean isSplitCard, boolean isHorizontalCard, boolean isAftermathCard) { + public static FImageComplex getCardArt(String imageKey, boolean isSplitCard, boolean isHorizontalCard, boolean isAftermathCard, boolean isSaga, boolean isClass, boolean isDungeon, boolean isFlipCard, boolean isPlanesWalker) { FImageComplex cardArt = cardArtCache.get(imageKey); if (cardArt == null) { Texture image = new RendererCachedCardImage(imageKey, true).getImage(); @@ -227,12 +227,36 @@ public class CardRenderer { float x, y; float w = image.getWidth(); float h = image.getHeight(); - if (isSplitCard && !isAftermathCard) { //allow rotated image for split cards + if (isPlanesWalker) { + x = w * 0.09f; + y = h * 0.11f; + w -= 2f * x; + h -= 5.71f * y; + } else if (isFlipCard) { + x = w * 0.09f; + y = h * 0.32f; + w -= 2f * x; + h -= 2.1f * y; + } else if (isDungeon) { + x = w * 0.09f; + y = h * 0.1f; + w -= 2f * x; + h -= 2.2f * y; + } else if (isClass) { + x = w * 0.09f; + y = h * 0.11f; + w -= 1.1f * x + w / 2; + h -= 2.45f * y; + } else if (isSaga) { + x = (w * 0.1f) + (w * 0.8f / 2); + y = h * 0.11f; + w -= 1.16f * x; + h -= 2.45f * y; + } else if (isSplitCard && !isAftermathCard) { //allow rotated image for split cards x = w * 33f / 250f; y = 0; //delay adjusting y and h until drawn w *= 106f / 250f; - } - else if (isHorizontalCard) { //allow rotated image for horizontal cards + } else if (isHorizontalCard) { //allow rotated image for horizontal cards float artX = 40f, artY = 40f; float artW = 350f, artH = 156f; float srcW = 430f, srcH = 300f; @@ -241,8 +265,7 @@ public class CardRenderer { y = h * 40f / srcH; w *= artW / srcW; h *= artH / srcH; - } - else { //rotate art clockwise if its not the correct orientation + } else { //rotate art clockwise if its not the correct orientation x = w * artY / srcH; y = h * (srcW - artW - artX) / srcW; w *= artH / srcH; @@ -251,8 +274,7 @@ public class CardRenderer { cardArtCache.put(imageKey, cardArt); return cardArt; } - } - else { + } else { x = w * 0.1f; y = h * 0.11f; w -= 2 * x; @@ -262,8 +284,7 @@ public class CardRenderer { float dw = w * (ratioRatio - 1); w -= dw; x += dw / 2; - } - else { //if too tall, shrink height + } else { //if too tall, shrink height float dh = h * (1 - ratioRatio); h -= dh; y += dh / 2; @@ -290,16 +311,15 @@ public class CardRenderer { if (image != null) { if (image == ImageCache.defaultImage) { cardArt = CardImageRenderer.forgeArt; - } - else { + } else { float x, y; float w = image.getWidth(); float h = image.getHeight(); //allow rotated image for split cards - x = w * 138f / 250f; - y = h * 210f / 370f; //delay adjusting y and h until drawn - w *= 68f / 250f; - h *= 128f / 370f; + x = w * 138f / 250f; + y = h * 210f / 370f; //delay adjusting y and h until drawn + w *= 68f / 250f; + h *= 128f / 370f; cardArt = new FTextureRegionImage(new TextureRegion(image, Math.round(x), Math.round(y), Math.round(w), Math.round(h))); @@ -310,6 +330,52 @@ public class CardRenderer { return cardArt; } + public static FImageComplex getAlternateCardArt(final String imageKey, boolean isPlanesWalker) { + FImageComplex cardArt = cardArtCache.get("Alternate_"+imageKey); + if (cardArt == null) { + Texture image = new CachedCardImage(imageKey) { + @Override + public void onImageFetched() { + ImageCache.clear(); + cardArtCache.remove("Alternate_" + imageKey); + } + }.getImage(); + if (image != null) { + if (image == ImageCache.defaultImage) { + cardArt = CardImageRenderer.forgeArt; + } else { + float x, y; + float w = image.getWidth(); + float h = image.getHeight(); + if (isPlanesWalker) { + x = w * 0.09f; + y = h * 0.11f; + w -= 2f * x; + h -= 5.71f * y; + } else { + x = w * 0.1f; + y = h * 0.11f; + w -= 2 * x; + h *= CARD_ART_HEIGHT_PERCENTAGE; + float ratioRatio = w / h / CARD_ART_RATIO; + if (ratioRatio > 1) { //if too wide, shrink width + float dw = w * (ratioRatio - 1); + w -= dw; + x += dw / 2; + } else { //if too tall, shrink height + float dh = h * (1 - ratioRatio); + h -= dh; + y += dh / 2; + } + } + cardArt = new FTextureRegionImage(new TextureRegion(image, Math.round(x), Math.round(y), Math.round(w), Math.round(h))); + } + cardArtCache.put("Alternate_"+imageKey, cardArt); + } + } + return cardArt; + } + public static void drawCardListItem(Graphics g, FSkinFont font, FSkinColor foreColor, CardView card, int count, String suffix, float x, float y, float w, float h, boolean compactMode) { final CardStateView state = card.getCurrentState(); if (card.getId() > 0) { @@ -457,8 +523,8 @@ public class CardRenderer { minusxy = 0.135f*radius; } if (image != null) { - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos); + if (image == ImageCache.defaultImage || Forge.enableUIMask.equals("Art")) { + CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos, true); } else { if (Forge.enableUIMask.equals("Full")) { if (ImageCache.isBorderlessCardArt(image)) @@ -482,13 +548,13 @@ public class CardRenderer { } } 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, CardView.getCardForUi(pc), false, x, y, w, h, pos); + CardImageRenderer.drawCardImage(g, CardView.getCardForUi(pc), false, x, y, w, h, pos, Forge.enableUIMask.equals("Art")); } } public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate) { - drawCard(g, card, x, y, w, h, pos, rotate, false); + drawCard(g, card, x, y, w, h, pos, rotate, false, false); } - public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState) { + public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState, boolean isChoiceList) { boolean canshow = MatchController.instance.mayView(card); boolean showsleeves = card.isFaceDown() && card.isInZone(EnumSet.of(ZoneType.Exile)); //fix facedown card image ie gonti lord of luxury Texture image = new RendererCachedCardImage(card, false).getImage( showAltState ? card.getAlternateState().getImageKey() : card.getCurrentState().getImageKey()); @@ -501,8 +567,8 @@ public class CardRenderer { minusxy = 0.135f*radius; } if (image != null) { - if (image == ImageCache.defaultImage) { - CardImageRenderer.drawCardImage(g, card, false, x, y, w, h, pos); + if (image == ImageCache.defaultImage || Forge.enableUIMask.equals("Art")) { + CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, true, false, isChoiceList); } else if (showsleeves) { if (!card.isForeTold()) g.drawImage(sleeves, x, y, w, h); @@ -544,7 +610,7 @@ public class CardRenderer { drawFoilEffect(g, card, x, y, w, h, false); } 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, false, x, y, w, h, pos); + CardImageRenderer.drawCardImage(g, card, showAltState, x, y, w, h, pos, Forge.enableUIMask.equals("Art"), false, isChoiceList); } } @@ -557,7 +623,7 @@ public class CardRenderer { boolean unselectable = !MatchController.instance.isSelectable(card) && MatchController.instance.isSelecting(); float cx, cy, cw, ch; cx = x; cy = y; cw = w; ch = h; - drawCard(g, card, x, y, w, h, pos, false, showAltState); + drawCard(g, card, x, y, w, h, pos, false, showAltState, isChoiceList); float padding = w * PADDING_MULTIPLIER; //adjust for card border x += padding; @@ -684,7 +750,7 @@ public class CardRenderer { multiplier = 0.150f; break; } - g.drawOutlinedText(CardTranslation.getTranslatedName(details.getName()), FSkinFont.forHeight(h * multiplier), Color.WHITE, Color.BLACK, x + padding -1f, y + padding, w - 2 * padding, h * 0.4f, true, Align.left, false); + g.drawOutlinedText(CardTranslation.getTranslatedName(details.getName()), FSkinFont.forHeight(h * multiplier), Color.WHITE, Color.BLACK, x + padding -1f, y + padding, w - 2 * padding, h * 0.4f, true, Align.left, false, true); } if (showCardManaCostOverlay(card)) { float manaSymbolSize = w / 4.5f; diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index d8b9d074caa..e9c16745634 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -181,7 +181,7 @@ public class CardZoom extends FOverlay { } if (flipIconBounds != null && flipIconBounds.contains(x, y)) { if (currentCard.isFaceDown() && currentCard.getBackup() != null) { - if (currentCard.getBackup().hasBackSide()) { + if (currentCard.getBackup().hasBackSide() || currentCard.getBackup().isFlipCard()) { show(currentCard.getBackup()); return true; } diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java index a27826a6d6c..5be4429f44b 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ImageView.java @@ -16,6 +16,7 @@ import com.badlogic.gdx.utils.Align; import forge.Forge; import forge.Forge.KeyInputAdapter; import forge.Graphics; +import forge.ImageKeys; import forge.assets.FImage; import forge.assets.FImageComplex; import forge.assets.FSkin; @@ -24,17 +25,15 @@ import forge.assets.FSkinColor.Colors; import forge.assets.FSkinFont; import forge.assets.FSkinImage; import forge.assets.ImageCache; -import forge.card.CardFaceSymbols; -import forge.card.CardRenderer; +import forge.card.*; import forge.card.CardRenderer.CardStackPosition; -import forge.card.CardZoom; -import forge.card.ColorSet; import forge.deck.ArchetypeDeckGenerator; import forge.deck.CardThemedDeckGenerator; import forge.deck.CommanderDeckGenerator; import forge.deck.DeckProxy; import forge.deck.FDeckViewer; import forge.deck.io.DeckPreferences; +import forge.game.card.CardView; import forge.gamemodes.planarconquest.ConquestCommander; import forge.item.InventoryItem; import forge.item.PaperCard; @@ -54,6 +53,7 @@ import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; import forge.toolbox.FTextField; +import forge.util.ImageUtil; import forge.util.Localizer; import forge.util.TextUtil; import forge.util.Utils; @@ -1016,8 +1016,20 @@ public class ImageView extends ItemView { } else { //commander bg g.drawImage(FSkin.getDeckbox().get(0), FSkin.getDeckbox().get(0), x, y, w, h, Color.GREEN, selected); - TextureRegion tr = ImageCache.croppedBorderImage(dpImg); - g.drawImage(tr, x+(w-w*scale)/2, y+(h-h*scale)/1.5f, w*scale, h*scale); + + PaperCard paperCard = null; + String imageKey = item.getImageKey(false); + if (imageKey != null) { + if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) + paperCard = ImageUtil.getPaperCardFromImageKey(imageKey); + } + if (paperCard != null && Forge.enableUIMask.equals("Art")) { + CardImageRenderer.drawCardImage(g, CardView.getCardForUi(paperCard), false, + x + (w - w * scale) / 2, y + (h - h * scale) / 1.5f, w * scale, h * scale, CardStackPosition.Top, true, false, false); + } else { + TextureRegion tr = ImageCache.croppedBorderImage(dpImg); + g.drawImage(tr, x + (w - w * scale) / 2, y + (h - h * scale) / 1.5f, w * scale, h * scale); + } } //fake labelname shadow g.drawText(item.getName(), GROUP_HEADER_FONT, Color.BLACK, (x + PADDING)-1f, (y + PADDING*2)+1f, w - 2 * PADDING, h - 2 * PADDING, true, Align.center, false); @@ -1026,8 +1038,8 @@ public class ImageView extends ItemView { } else { if (!dp.isGeneratedDeck()){ //If deck has Commander, use it as cardArt reference - String deckImageKey = dp.getDeck().getCommanders().isEmpty() ? dp.getHighestCMCCard().getImageKey(false) : dp.getDeck().getCommanders().get(0).getImageKey(false); - FImageComplex cardArt = CardRenderer.getCardArt(deckImageKey, false, false, false); + PaperCard paperCard = dp.getDeck().getCommanders().isEmpty() ? dp.getHighestCMCCard() : dp.getDeck().getCommanders().get(0); + FImageComplex cardArt = CardRenderer.getCardArt(paperCard); //draw the deckbox if (cardArt == null){ //draw generic box if null or still loading diff --git a/forge-gui-mobile/src/forge/screens/home/HomeScreen.java b/forge-gui-mobile/src/forge/screens/home/HomeScreen.java index c65782f334f..2e8c39f913b 100644 --- a/forge-gui-mobile/src/forge/screens/home/HomeScreen.java +++ b/forge-gui-mobile/src/forge/screens/home/HomeScreen.java @@ -161,6 +161,10 @@ public class HomeScreen extends FScreen { return QuestCommander; } + public int getActiveButtonIndex() { + return activeButtonIndex; + } + public String getQuestWorld() { return QuestWorld; } diff --git a/forge-gui-mobile/src/forge/screens/home/LoadGameMenu.java b/forge-gui-mobile/src/forge/screens/home/LoadGameMenu.java index 40082ecf6a4..e248e02fdf6 100644 --- a/forge-gui-mobile/src/forge/screens/home/LoadGameMenu.java +++ b/forge-gui-mobile/src/forge/screens/home/LoadGameMenu.java @@ -105,8 +105,11 @@ public class LoadGameMenu extends FPopupMenu { protected void buildMenu() { FScreen currentScreen = Forge.getCurrentScreen(); for (LoadGameScreen lgs : LoadGameScreen.values()) { - addItem(lgs.item); - lgs.item.setSelected(currentScreen == lgs.screen); + //fixes the overlapping menu items when the user suddenly switch from load game screen index to another screen + if (HomeScreen.instance.getActiveButtonIndex() == 1) { + addItem(lgs.item); + lgs.item.setSelected(currentScreen == lgs.screen); + } } } } diff --git a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java index 477b2cd9d85..8bc21cf3f66 100644 --- a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java +++ b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java @@ -521,7 +521,7 @@ public class SettingsPage extends TabPage { lstSettings.addItem(new CustomSelectSetting(FPref.UI_ENABLE_BORDER_MASKING, localizer.getMessage("lblBorderMaskOption"), localizer.getMessage("nlBorderMaskOption"), - new String[]{"Off", "Crop", "Full"}) { + new String[]{"Off", "Crop", "Full", "Art"}) { @Override public void valueChanged(String newValue) { super.valueChanged(newValue); diff --git a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java index 47d8edfd6d4..81fddb39214 100644 --- a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java +++ b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java @@ -393,7 +393,7 @@ public class FChoiceList extends FList implements ActivateHandler { boolean showAlt = false; if(cardView.hasAlternateState()){ if(cardView.hasBackSide()) - showAlt = value.contains(cardView.getBackSideName()); + showAlt = value.contains(cardView.getBackSideName()) || cardView.getAlternateState().getAbilityText().contains(value); else if (cardView.isAdventureCard()) showAlt = value.equals(cardView.getAlternateState().getAbilityText()); else if (cardView.isSplitCard()) { @@ -520,9 +520,12 @@ public class FChoiceList extends FList implements ActivateHandler { @Override public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { //should fix NPE ie Thief of Sanity, Gonti... etc - CardView cv = ((IHasCardView)value).getCardView().isFaceDown() && ((IHasCardView)value).getCardView().isInZone(EnumSet.of(ZoneType.Exile)) ? ((IHasCardView)value).getCardView().getBackup() : ((IHasCardView)value).getCardView(); - boolean showAlternate = showAlternate(cv, value.toString()); - CardRenderer.drawCardWithOverlays(g, cv, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top, false, showAlternate, true); + CardView cv = ((IHasCardView)value).getCardView(); + if (cv != null) { + CardView render = cv.isFaceDown() && cv.isInZone(EnumSet.of(ZoneType.Exile)) ? cv.getBackup() : cv; + boolean showAlternate = showAlternate(render, value.toString()); + CardRenderer.drawCardWithOverlays(g, render, x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top, false, showAlternate, true); + } float dx = VStack.CARD_WIDTH + FList.PADDING; x += dx; diff --git a/forge-gui/res/skins/default/sprite_cardbg.png b/forge-gui/res/skins/default/sprite_cardbg.png new file mode 100644 index 00000000000..344a531202b Binary files /dev/null and b/forge-gui/res/skins/default/sprite_cardbg.png differ diff --git a/forge-gui/src/main/java/forge/deck/DeckProxy.java b/forge-gui/src/main/java/forge/deck/DeckProxy.java index 1892e7b7566..fd06cc92019 100644 --- a/forge-gui/src/main/java/forge/deck/DeckProxy.java +++ b/forge-gui/src/main/java/forge/deck/DeckProxy.java @@ -256,7 +256,8 @@ public class DeckProxy implements InventoryItem { for (final Entry pc : getDeck().getAllCardsInASinglePool()) { if (pc.getKey().getRules().getManaCost() != null) { - if (pc.getKey().getRules().getSplitType() != CardSplitType.Split) + if (pc.getKey().getRules().getType().hasSubtype("Saga") || pc.getKey().getRules().getType().hasSubtype("Class") || CardSplitType.Split.equals(pc.getKey().getRules().getSplitType())) + continue; keyCMC.put(pc.getKey(),pc.getKey().getRules().getManaCost().getCMC()); } } diff --git a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java index e1ea5dce308..9c2e3c2dde3 100644 --- a/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java +++ b/forge-gui/src/main/java/forge/localinstance/properties/ForgeConstants.java @@ -122,6 +122,7 @@ public final class ForgeConstants { public static final String SPRITE_PLANAR_CONQUEST_FILE = "sprite_planar_conquest.png"; public static final String SPRITE_SETLOGO_FILE = "sprite_setlogo.png"; public static final String SPRITE_WATERMARK_FILE = "sprite_watermark.png"; + public static final String SPRITE_CARDBG_FILE = "sprite_cardbg.png"; public static final String FONT_FILE = "font1.ttf"; public static final String SPLASH_BG_FILE = "bg_splash.png"; public static final String MATCH_BG_FILE = "bg_match.jpg"; diff --git a/forge-gui/src/main/java/forge/localinstance/skin/FSkinProp.java b/forge-gui/src/main/java/forge/localinstance/skin/FSkinProp.java index eef03fe9fcd..779eb4c2a42 100644 --- a/forge-gui/src/main/java/forge/localinstance/skin/FSkinProp.java +++ b/forge-gui/src/main/java/forge/localinstance/skin/FSkinProp.java @@ -410,6 +410,28 @@ public enum FSkinProp { IMG_WATERMARK_W (new int[] {2, 1006, 500, 500}, PropType.WATERMARKS), IMG_WATERMARK_C (new int[] {504, 1006, 500, 500}, PropType.WATERMARKS), + //FOR CARDBG + IMG_CARDBG_A (new int[] {2, 2, 339, 496}, PropType.CARDBG), + IMG_CARDBG_B (new int[] {343, 2, 339, 496}, PropType.CARDBG), + IMG_CARDBG_BG (new int[] {684, 2, 339, 496}, PropType.CARDBG), + IMG_CARDBG_BR (new int[] {1025, 2, 339, 496}, PropType.CARDBG), + IMG_CARDBG_C (new int[] {1366, 2, 339, 496}, PropType.CARDBG), + IMG_CARDBG_G (new int[] {2, 500, 339, 496}, PropType.CARDBG), + IMG_CARDBG_L (new int[] {343, 500, 339, 496}, PropType.CARDBG), + IMG_CARDBG_M (new int[] {684, 500, 339, 496}, PropType.CARDBG), + IMG_CARDBG_R (new int[] {1025, 500, 339, 496}, PropType.CARDBG), + IMG_CARDBG_RG (new int[] {1366, 500, 339, 496}, PropType.CARDBG), + IMG_CARDBG_U (new int[] {2, 998, 339, 496}, PropType.CARDBG), + IMG_CARDBG_UB (new int[] {343, 998, 339, 496}, PropType.CARDBG), + IMG_CARDBG_UG (new int[] {684, 998, 339, 496}, PropType.CARDBG), + IMG_CARDBG_UR (new int[] {1025, 998, 339, 496}, PropType.CARDBG), + IMG_CARDBG_V (new int[] {1366, 998, 339, 496}, PropType.CARDBG), + IMG_CARDBG_W (new int[] {2, 1496, 339, 496}, PropType.CARDBG), + IMG_CARDBG_WB (new int[] {343, 1496, 339, 496}, PropType.CARDBG), + IMG_CARDBG_WG (new int[] {684, 1496, 339, 496}, PropType.CARDBG), + IMG_CARDBG_WR (new int[] {1025, 1496, 339, 496}, PropType.CARDBG), + IMG_CARDBG_WU (new int[] {1366, 1496, 339, 496}, PropType.CARDBG), + IMG_FAV1 (new int[] {0, 0, 100, 100}, PropType.FAVICON), IMG_FAV2 (new int[] {100, 0, 100, 100}, PropType.FAVICON), IMG_FAV3 (new int[] {200, 0, 100, 100}, PropType.FAVICON), @@ -514,6 +536,7 @@ public enum FSkinProp { DECKBOX, SETLOGO, WATERMARKS, + CARDBG, FAVICON } }