From d478e9c5a117548d1fa53ad357f2092379c144b3 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 5 Oct 2020 05:46:29 +0800 Subject: [PATCH 1/4] Various GUI fixes Fix choice list card image display for Modal, Split, Adventure and special case for Aftermath. Fix cards exiled facedown with backside show their original state when viewing the hidden card. --- .../main/java/forge/game/card/CardUtil.java | 1 - .../main/java/forge/game/card/CardView.java | 32 +++++++++++++++++++ .../forge/trackable/TrackableProperty.java | 7 ++++ .../src/forge/card/CardImageRenderer.java | 12 ++++++- .../src/forge/card/CardRenderer.java | 15 +++++---- forge-gui-mobile/src/forge/card/CardZoom.java | 23 ++++++++++--- .../src/forge/screens/match/views/VStack.java | 2 +- .../src/forge/toolbox/FChoiceList.java | 28 ++++++++++++++-- 8 files changed, 103 insertions(+), 17 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index 9a025e20f0d..47c5d8211b7 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -339,7 +339,6 @@ public final class CardUtil { //show hidden if exiled facedown ret.setImageKey(ImageKeys.getTokenKey(c.isInZone(ZoneType.Exile) ? ImageKeys.HIDDEN_CARD : ImageKeys.MORPH_IMAGE)); - //TODO: the imagey key here don't support cards with backside... hmmm cards with backside and hidden should display its faceup verion not their alternate... return ret; } 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 57ba9fa06db..d753c8acdcf 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -134,6 +134,18 @@ public class CardView extends GameEntityView { return get(TrackableProperty.SplitCard); } + public boolean isDoubleFacedCard() { + return get(TrackableProperty.DoubleFaced); + } + + public boolean isAdventureCard() { + return get(TrackableProperty.Adventure); + } + + public boolean isModalCard() { + return get(TrackableProperty.Modal); + } + /* public boolean isTransformed() { return getCurrentState().getState() == CardStateName.Transformed; @@ -678,6 +690,12 @@ public class CardView extends GameEntityView { public CardStateView getAlternateState() { return get(TrackableProperty.AlternateState); } + + public boolean hasBackSide() { + return get(TrackableProperty.HasBackSide); + } + public String getBackSideName() { return get(TrackableProperty.BackSideName); } + CardStateView createAlternateState(final CardStateName state0) { return new CardStateView(getId(), state0, tracker); } @@ -685,6 +703,10 @@ public class CardView extends GameEntityView { public CardStateView getState(final boolean alternate0) { return alternate0 ? getAlternateState() : getCurrentState(); } + void updateBackSide(String stateName, boolean hasBackSide) { + set(TrackableProperty.HasBackSide, hasBackSide); + set(TrackableProperty.BackSideName, stateName); + } void updateState(Card c) { updateName(c); updateDamage(c); @@ -694,6 +716,13 @@ public class CardView extends GameEntityView { set(TrackableProperty.SplitCard, isSplitCard); set(TrackableProperty.FlipCard, c.isFlipCard()); set(TrackableProperty.Facedown, c.isFaceDown()); + set(TrackableProperty.Adventure, c.isAdventureCard()); + set(TrackableProperty.DoubleFaced, c.isDoubleFaced()); + set(TrackableProperty.Modal, c.isModal()); + + //backside + if (c.getAlternateState()!=null) + updateBackSide(c.getAlternateState().getName(), c.hasBackSide()); final Card cloner = c.getCloner(); @@ -733,6 +762,9 @@ public class CardView extends GameEntityView { alternateState = c.getState(CardStateName.Original); } + if (c.hasBackSide() && isFaceDown()) //fixes facedown cards with backside... + alternateState = c.getState(CardStateName.Original); + if (alternateState == null) { set(TrackableProperty.AlternateState, null); } diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 8d09ad364df..99228d48b56 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -25,6 +25,9 @@ public enum TrackableProperty { Flipped(TrackableTypes.BooleanType), Facedown(TrackableTypes.BooleanType), + Modal(TrackableTypes.BooleanType), + Adventure(TrackableTypes.BooleanType), + DoubleFaced(TrackableTypes.BooleanType), //TODO? Cloner(TrackableTypes.StringType), @@ -164,6 +167,10 @@ public enum TrackableProperty { CanPlay(TrackableTypes.BooleanType), PromptIfOnlyPossibleAbility(TrackableTypes.BooleanType), + //HasBackSide + BackSideName(TrackableTypes.StringType), + HasBackSide(TrackableTypes.BooleanType), + //StackItem Key(TrackableTypes.StringType), SourceTrigger(TrackableTypes.IntegerType), diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index 1dcb5140997..acc9a260243 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -336,7 +336,17 @@ 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) { boolean canshow = MatchController.instance.mayView(card); - final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(), true); + Texture image = null; + try { + image = ImageCache.getImage(card.getState(altState).getImageKey(), true); + } catch (Exception ex) { + System.err.println(card.toString()+" : " +ex.getMessage()); + //TODO: don't know why this is needed, needs further investigation... + if (!card.hasAlternateState()) { + altState = false; + image = ImageCache.getImage(card.getState(altState).getImageKey(), true); + } + } FImage sleeves = MatchController.getPlayerSleeve(card.getOwner()); if (image == null) { //draw details if can't draw zoom drawDetails(g, card, gameView, altState, x, y, w, h); diff --git a/forge-gui-mobile/src/forge/card/CardRenderer.java b/forge-gui-mobile/src/forge/card/CardRenderer.java index 8f8ede1074d..2953bf9f89d 100644 --- a/forge-gui-mobile/src/forge/card/CardRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardRenderer.java @@ -485,9 +485,12 @@ public class CardRenderer { } } 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); + } + public static void drawCard(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean rotate, boolean showAltState) { 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(card.getCurrentState().getImageKey()); + Texture image = new RendererCachedCardImage(card, false).getImage( showAltState ? card.getAlternateState().getImageKey() : card.getCurrentState().getImageKey()); FImage sleeves = MatchController.getPlayerSleeve(card.getOwner()); float radius = (h - w)/8; float croppedArea = isModernFrame(card) ? CROP_MULTIPLIER : 0.97f; @@ -540,15 +543,15 @@ public class CardRenderer { } 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); + drawCardWithOverlays(g, card, x, y, w, h, pos, false, false); } - public static void drawCardWithOverlays(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean stackview) { + public static void drawCardWithOverlays(Graphics g, CardView card, float x, float y, float w, float h, CardStackPosition pos, boolean stackview, boolean showAltState) { boolean canShow = MatchController.instance.mayView(card); float oldAlpha = g.getfloatAlphaComposite(); 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); + drawCard(g, card, x, y, w, h, pos, false, showAltState); float padding = w * PADDING_MULTIPLIER; //adjust for card border x += padding; @@ -557,7 +560,7 @@ public class CardRenderer { h -= 2 * padding; // TODO: A hacky workaround is currently used to make the game not leak the color information for Morph cards. - final CardStateView details = card.getCurrentState(); + final CardStateView details = showAltState ? card.getAlternateState() : card.getCurrentState(); final boolean isFaceDown = card.isFaceDown(); final DetailColors borderColor = isFaceDown ? CardDetailUtil.DetailColors.FACE_DOWN : CardDetailUtil.getBorderColor(details, canShow); // canShow doesn't work here for face down Morphs Color color = FSkinColor.fromRGB(borderColor.r, borderColor.g, borderColor.b); @@ -934,7 +937,7 @@ public class CardRenderer { } } else { - drawManaCost(g, card.getCurrentState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); + drawManaCost(g, showAltState ? card.getAlternateState().getManaCost() : card.getCurrentState().getManaCost(), x - padding, y, w + 2 * padding, h, manaSymbolSize); } } } diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index a32af97b9d7..6b59dc4a424 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -1,6 +1,7 @@ package forge.card; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.Map.Entry; @@ -17,6 +18,7 @@ import forge.deck.CommanderDeckGenerator; import forge.deck.DeckProxy; import forge.game.GameView; import forge.game.card.CardView; +import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.item.InventoryItem; import forge.model.FModel; @@ -46,10 +48,15 @@ public class CardZoom extends FOverlay { private static String currentActivateAction; private static Rectangle flipIconBounds; private static boolean showAltState; + private static boolean showBackSide = false; public static void show(Object item) { + show(item, false); + } + public static void show(Object item, boolean showbackside) { List items0 = new ArrayList<>(); items0.add(item); + showBackSide = showbackside; //reverse the displayed zoomed card for the choice list show(items0, 0, null); } public static void show(FCollectionView items0, int currentIndex0, ActivateHandler activateHandler0) { @@ -158,10 +165,14 @@ public class CardZoom extends FOverlay { @Override public boolean tap(float x, float y, int count) { if (flipIconBounds != null && flipIconBounds.contains(x, y)) { - showAltState = !showAltState; + if (!showBackSide) + showAltState = !showAltState; + else + showBackSide = !showBackSide; return true; } hide(); + showBackSide = false; return true; } @@ -169,14 +180,17 @@ public class CardZoom extends FOverlay { public boolean fling(float velocityX, float velocityY) { if (Math.abs(velocityX) > Math.abs(velocityY)) { incrementCard(velocityX > 0 ? -1 : 1); + showBackSide = false; return true; } if (velocityY > 0) { zoomMode = !zoomMode; + showBackSide = false; return true; } if (currentActivateAction != null && activateHandler != null) { hide(); + showBackSide = false; activateHandler.activate(currentIndex); return true; } @@ -282,10 +296,9 @@ public class CardZoom extends FOverlay { float x = (w - cardWidth) / 2; y = (h - cardHeight) / 2; if (zoomMode) { - CardImageRenderer.drawZoom(g, currentCard, gameView, showAltState, x, y, cardWidth, cardHeight, getWidth(), getHeight(), true); - } - else { - CardImageRenderer.drawDetails(g, currentCard, gameView, showAltState, x, y, cardWidth, cardHeight); + CardImageRenderer.drawZoom(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight, getWidth(), getHeight(), true); + } else { + CardImageRenderer.drawDetails(g, currentCard, gameView, showBackSide? showBackSide : showAltState, x, y, cardWidth, cardHeight); } if (flipIconBounds != null) { diff --git a/forge-gui-mobile/src/forge/screens/match/views/VStack.java b/forge-gui-mobile/src/forge/screens/match/views/VStack.java index 567665e69bd..b3ae6edd666 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VStack.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VStack.java @@ -382,7 +382,7 @@ public class VStack extends FDropDown { x += PADDING; y += PADDING; - CardRenderer.drawCardWithOverlays(g, stackInstance.getSourceCard(), x, y, CARD_WIDTH, CARD_HEIGHT, CardStackPosition.Top, true); + CardRenderer.drawCardWithOverlays(g, stackInstance.getSourceCard(), x, y, CARD_WIDTH, CARD_HEIGHT, CardStackPosition.Top, true, false); x += CARD_WIDTH + PADDING; w -= x + PADDING - BORDER_THICKNESS; diff --git a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java index 770736b177e..96e19487634 100644 --- a/forge-gui-mobile/src/forge/toolbox/FChoiceList.java +++ b/forge-gui-mobile/src/forge/toolbox/FChoiceList.java @@ -367,6 +367,24 @@ public class FChoiceList extends FList implements ActivateHandler { g.drawText(getChoiceText(value), font, foreColor, x, y, w, h, false, Align.center, true); } } + //simple check for cardview needed on some special renderer for cards + private boolean showAlternate(CardView cardView, String value){ + boolean showAlt = false; + if(cardView.hasAlternateState()){ + if(cardView.hasBackSide()) + showAlt = value.contains(cardView.getBackSideName()); + else if (cardView.isAdventureCard()) + 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 + showAlt = value.equals(cardView.getAlternateState().getAbilityText()); + } + } + return showAlt; + } //special renderer for cards protected class PaperCardItemRenderer extends ItemRenderer { @Override @@ -464,7 +482,8 @@ public class FChoiceList extends FList implements ActivateHandler { @Override public boolean tap(Integer index, T value, float x, float y, int count) { if (x <= VStack.CARD_WIDTH + 2 * FList.PADDING) { - CardZoom.show(((IHasCardView)value).getCardView()); + CardView cv = ((IHasCardView)value).getCardView(); + CardZoom.show(cv, showAlternate(cv, value.toString())); return true; } return false; @@ -472,13 +491,16 @@ public class FChoiceList extends FList implements ActivateHandler { @Override public boolean longPress(Integer index, T value, float x, float y) { - CardZoom.show(((IHasCardView)value).getCardView()); + CardView cv = ((IHasCardView)value).getCardView(); + CardZoom.show(cv, showAlternate(cv, value.toString())); return true; } @Override public void drawValue(Graphics g, T value, FSkinFont font, FSkinColor foreColor, boolean pressed, float x, float y, float w, float h) { - CardRenderer.drawCardWithOverlays(g, ((IHasCardView)value).getCardView(), x, y, VStack.CARD_WIDTH, VStack.CARD_HEIGHT, CardStackPosition.Top); + CardView cv = ((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); float dx = VStack.CARD_WIDTH + FList.PADDING; x += dx; From 051c1af1ec2869e123e8b4fc3157e995d1e8e1f3 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 5 Oct 2020 06:03:12 +0800 Subject: [PATCH 2/4] reset zoom altstate when closing the overlay --- forge-gui-mobile/src/forge/card/CardImageRenderer.java | 2 +- forge-gui-mobile/src/forge/card/CardZoom.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index acc9a260243..e42bff76442 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -340,7 +340,7 @@ public class CardImageRenderer { try { image = ImageCache.getImage(card.getState(altState).getImageKey(), true); } catch (Exception ex) { - System.err.println(card.toString()+" : " +ex.getMessage()); + //System.err.println(card.toString()+" : " +ex.getMessage()); //TODO: don't know why this is needed, needs further investigation... if (!card.hasAlternateState()) { altState = false; diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index 6b59dc4a424..c80f47d0122 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -173,6 +173,7 @@ public class CardZoom extends FOverlay { } hide(); showBackSide = false; + showAltState = false; return true; } @@ -181,16 +182,19 @@ public class CardZoom extends FOverlay { if (Math.abs(velocityX) > Math.abs(velocityY)) { incrementCard(velocityX > 0 ? -1 : 1); showBackSide = false; + showAltState = false; return true; } if (velocityY > 0) { zoomMode = !zoomMode; showBackSide = false; + showAltState = false; return true; } if (currentActivateAction != null && activateHandler != null) { hide(); showBackSide = false; + showAltState = false; activateHandler.activate(currentIndex); return true; } From 65f0c4dc30c56d1a8b1a581ba4ee6fd562508cbc Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 5 Oct 2020 10:45:35 +0800 Subject: [PATCH 3/4] Fix facedown cards ie manifested cards with back side for viewing --- forge-game/src/main/java/forge/game/card/Card.java | 1 + 1 file changed, 1 insertion(+) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index b1ae887b9a5..327d21c3f4a 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -667,6 +667,7 @@ public class Card extends GameEntity implements Comparable { } facedown = false; + updateStateForView(); //fixes cards with backside viewable // need to run faceup commands, currently // it does cleanup the modified facedown state if (result) { From 58805979c245cedc628b4958b5119794c7826347 Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Mon, 5 Oct 2020 11:29:15 +0800 Subject: [PATCH 4/4] removed unused imports --- forge-gui-mobile/src/forge/card/CardZoom.java | 2 -- .../src/main/java/forge/quest/MainWorldEventDuelManager.java | 1 - 2 files changed, 3 deletions(-) diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index c80f47d0122..bd77c7618f0 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -1,7 +1,6 @@ package forge.card; import java.util.ArrayList; -import java.util.EnumSet; import java.util.List; import java.util.Map.Entry; @@ -18,7 +17,6 @@ import forge.deck.CommanderDeckGenerator; import forge.deck.DeckProxy; import forge.game.GameView; import forge.game.card.CardView; -import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.item.InventoryItem; import forge.model.FModel; diff --git a/forge-gui/src/main/java/forge/quest/MainWorldEventDuelManager.java b/forge-gui/src/main/java/forge/quest/MainWorldEventDuelManager.java index 7ff830776ad..3421238909d 100644 --- a/forge-gui/src/main/java/forge/quest/MainWorldEventDuelManager.java +++ b/forge-gui/src/main/java/forge/quest/MainWorldEventDuelManager.java @@ -1,6 +1,5 @@ package forge.quest; -import java.awt.image.renderable.RenderableImage; import java.io.File; import java.util.ArrayList; import java.util.Arrays;