diff --git a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java index 1c747a74c8d..7f366f244e1 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CloneEffect.java @@ -11,6 +11,7 @@ import forge.game.card.CardCharacteristics; import forge.game.card.CardFactory; import forge.game.card.CardFactoryUtil; import forge.game.card.CardUtil; +import forge.game.event.GameEventCardStatsChanged; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.trigger.Trigger; @@ -57,6 +58,7 @@ public class CloneEffect extends SpellAbilityEffect { final Card host = sa.getHostCard(); Card tgtCard = host; Map origSVars = host.getSVars(); + final Game game = sa.getActivatingPlayer().getGame(); // find cloning source i.e. thing to be copied Card cardToCopy = null; @@ -179,7 +181,7 @@ public class CloneEffect extends SpellAbilityEffect { } }; - final Game game = sa.getActivatingPlayer().getGame(); + String duration = sa.getParam("Duration"); if (duration.equals("UntilEndOfTurn")) { game.getEndOfTurn().addUntil(unclone); @@ -188,6 +190,7 @@ public class CloneEffect extends SpellAbilityEffect { } } + game.fireEvent(new GameEventCardStatsChanged(tgtCard)); } // cloneResolve private void addExtraCharacteristics(final Card tgtCard, final SpellAbility sa, final Map origSVars) { 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 3fe8308e8a0..1b619b86e63 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -8247,20 +8247,6 @@ public class Card extends GameEntity implements Comparable { return this.timestamp; } - /** - * - * TODO Write javadoc for this method. - * - * @return an int - */ - public final int getFoil() { - final String foil = this.getCardForUi().getCharacteristics().getSVar("Foil"); - if (!foil.isEmpty()) { - return Integer.parseInt(foil); - } - return 0; - } - /** * Assign a random foil finish depending on the card edition. * diff --git a/forge-game/src/main/java/forge/game/card/CardCharacteristics.java b/forge-game/src/main/java/forge/game/card/CardCharacteristics.java index 8f5eec3a536..f499faec069 100644 --- a/forge-game/src/main/java/forge/game/card/CardCharacteristics.java +++ b/forge-game/src/main/java/forge/game/card/CardCharacteristics.java @@ -410,6 +410,20 @@ public class CardCharacteristics { this.sVars = newSVars; } + /** + * + * TODO Write javadoc for this method. + * + * @return an int + */ + public final int getFoil() { + final String foil = this.getSVar("Foil"); + if (!foil.isEmpty()) { + return Integer.parseInt(foil); + } + return 0; + } + /** *

* copy. diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index e7d4306b5ea..f58af18727d 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -247,6 +247,7 @@ public class GuiDesktop implements IGuiBase { VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player); SDisplayUtil.showTab(nextField); CPrompt.SINGLETON_INSTANCE.updateText(); + CMatchUI.SINGLETON_INSTANCE.repaintCardOverlays(); } @Override diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ImageView.java b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ImageView.java index 2ebf8a2956e..5b086bc8591 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ImageView.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ImageView.java @@ -1101,8 +1101,8 @@ public class ImageView extends ItemView { IPaperCard paperCard = (IPaperCard)item; if (paperCard.isFoil()) { final CardView card = ViewUtil.getCardForUi(paperCard); - if (card.getFoilIndex() == 0) { //if foil finish not yet established, assign a random one - card.setRandomFoil(); + if (card.getOriginal().getFoilIndex() == 0) { //if foil finish not yet established, assign a random one + card.getOriginal().setRandomFoil(); } CardPanel.drawFoilEffect(g, card, bounds.x, bounds.y, bounds.width, bounds.height, borderSize); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPicture.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPicture.java index 100ba583b8c..a06a5d08691 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPicture.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPicture.java @@ -83,8 +83,8 @@ public enum CPicture implements ICDoc { if (item instanceof IPaperCard) { final IPaperCard paperCard = ((IPaperCard)item); final CardView c = ViewUtil.getCardForUi(paperCard); - if (paperCard.isFoil() && c.getFoilIndex() == 0) { - c.setRandomFoil(); + if (paperCard.isFoil() && c.getOriginal().getFoilIndex() == 0) { + c.getOriginal().setRandomFoil(); } showCard(c, false); } else { diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FImageUtil.java b/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FImageUtil.java index efd8a7caff4..d2cb1418c43 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FImageUtil.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/imaging/FImageUtil.java @@ -49,7 +49,7 @@ public final class FImageUtil { */ public static BufferedImage getImage(final CardStateView card) { BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), true); - final int foilIndex = card.getCard().getFoilIndex(); + final int foilIndex = card.getFoilIndex(); if (image != null && foilIndex > 0) { image = getImageWithFoilEffect(image, foilIndex); } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanel.java b/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanel.java index 1564d5a3cbe..71fb430a65c 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanel.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanel.java @@ -328,7 +328,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl // White border if card is known to have it. if (this.getCard() != null) { CardEdition ed = FModel.getMagicDb().getEditions().get(this.getCard().getSetCode()); - if (ed != null && ed.isWhiteBorder() && this.getCard().getFoilIndex() == 0) { + if (ed != null && ed.isWhiteBorder() && this.getCard().getOriginal().getFoilIndex() == 0) { g2d.setColor(Color.white); int ins = 1; g2d.fillRoundRect(this.cardXOffset + ins, this.cardYOffset + ins, this.cardWidth - ins*2, this.cardHeight - ins*2, cornerSize-ins, cornerSize-ins); @@ -356,6 +356,81 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl return; } + displayIconOverlay(g); + drawFoilEffect(g, card, this.cardXOffset, this.cardYOffset, + this.cardWidth, this.cardHeight, Math.round(this.cardWidth * BLACK_BORDER_SIZE)); + } + + public static void drawFoilEffect(final Graphics g, final CardView card2, final int x, final int y, final int width, final int height, final int borderSize) { + if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT)) { + int foil = card2.getOriginal().getFoilIndex(); + if (foil > 0) { + CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), + x + borderSize, y + borderSize, width - 2 * borderSize, height - 2 * borderSize); + } + } + } + + @Override + public final void doLayout() { + final int borderSize = Math.round(this.cardWidth * CardPanel.BLACK_BORDER_SIZE); + + final Point imgPos = new Point(this.cardXOffset + borderSize, this.cardYOffset + borderSize); + final Dimension imgSize = new Dimension(this.cardWidth - (borderSize * 2), this.cardHeight - (borderSize * 2)); + + this.imagePanel.setLocation(imgPos); + this.imagePanel.setSize(imgSize); + + boolean showText = !this.imagePanel.hasImage() || !this.isAnimationPanel; + + displayCardNameOverlay(showText && showCardNameOverlay(), imgSize, imgPos); + displayPTOverlay(showText && showCardPowerOverlay(), imgSize, imgPos); + displayCardIdOverlay(showText && showCardIdOverlay(), imgSize, imgPos); + displayIconOverlay(getGraphics()); + } + + private void displayCardIdOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { + if (isVisible) { + final Dimension idSize = this.cardIdText.getPreferredSize(); + this.cardIdText.setSize(idSize.width, idSize.height); + final int idX = Math.round(imgSize.width * (24f / 480)); + final int idY = Math.round(imgSize.height * (650f / 680)) - 8; + this.cardIdText.setLocation(imgPos.x + idX, imgPos.y + idY); + } + this.cardIdText.setVisible(isVisible); + } + + private void displayPTOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { + if (isVisible) { + final int rightLine = Math.round(imgSize.width * (412f / 480)) + 3; + // Power + final Dimension ptSize = this.ptText.getPreferredSize(); + this.ptText.setSize(ptSize.width, ptSize.height); + final int ptX = rightLine - ptSize.width/2; + final int ptY = Math.round(imgSize.height * (650f / 680)) - 10; + this.ptText.setLocation(imgPos.x + ptX, imgPos.y + ptY); + // Toughness + final Dimension dmgSize = this.damageText.getPreferredSize(); + this.damageText.setSize(dmgSize.width, dmgSize.height); + final int dmgX = rightLine - dmgSize.width / 2; + final int dmgY = ptY - 16; + this.damageText.setLocation(imgPos.x + dmgX, imgPos.y + dmgY); + } + this.ptText.setVisible(isVisible); + this.damageText.setVisible(isVisible); + } + + private void displayCardNameOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { + if (isVisible) { + final int titleX = Math.round(imgSize.width * (24f / 480)); + final int titleY = Math.round(imgSize.height * (54f / 640)) - 15; + final int titleH = Math.round(imgSize.height * (360f / 640)); + this.titleText.setBounds(imgPos.x + titleX, imgPos.y + titleY + 2, imgSize.width - 2 * titleX, titleH - titleY); + } + this.titleText.setVisible(isVisible); + } + + private void displayIconOverlay(final Graphics g) { if (showCardManaCostOverlay() && this.cardWidth < 200) { final boolean showSplitMana = card.isSplitCard(); if (!showSplitMana) { @@ -407,77 +482,6 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl CardFaceSymbols.drawSymbol("sacrifice", g, (this.cardXOffset + (this.cardWidth / 2)) - 20, (this.cardYOffset + (this.cardHeight / 2)) - 20); } - - drawFoilEffect(g, card, this.cardXOffset, this.cardYOffset, - this.cardWidth, this.cardHeight, Math.round(this.cardWidth * BLACK_BORDER_SIZE)); - } - - public static void drawFoilEffect(final Graphics g, final CardView card2, final int x, final int y, final int width, final int height, final int borderSize) { - if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT)) { - int foil = card2.getFoilIndex(); - if (foil > 0) { - CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), - x + borderSize, y + borderSize, width - 2 * borderSize, height - 2 * borderSize); - } - } - } - - @Override - public final void doLayout() { - final int borderSize = Math.round(this.cardWidth * CardPanel.BLACK_BORDER_SIZE); - - final Point imgPos = new Point(this.cardXOffset + borderSize, this.cardYOffset + borderSize); - final Dimension imgSize = new Dimension(this.cardWidth - (borderSize * 2), this.cardHeight - (borderSize * 2)); - - this.imagePanel.setLocation(imgPos); - this.imagePanel.setSize(imgSize); - - boolean showText = !this.imagePanel.hasImage() || !this.isAnimationPanel; - - displayCardNameOverlay(showText && showCardNameOverlay(), imgSize, imgPos); - displayPTOverlay(showText && showCardPowerOverlay(), imgSize, imgPos); - displayCardIdOverlay(showText && showCardIdOverlay(), imgSize, imgPos); - } - - private void displayCardIdOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { - if (isVisible) { - final Dimension idSize = this.cardIdText.getPreferredSize(); - this.cardIdText.setSize(idSize.width, idSize.height); - final int idX = Math.round(imgSize.width * (24f / 480)); - final int idY = Math.round(imgSize.height * (650f / 680)) - 8; - this.cardIdText.setLocation(imgPos.x + idX, imgPos.y + idY); - } - this.cardIdText.setVisible(isVisible); - } - - private void displayPTOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { - if (isVisible) { - final int rightLine = Math.round(imgSize.width * (412f / 480)) + 3; - // Power - final Dimension ptSize = this.ptText.getPreferredSize(); - this.ptText.setSize(ptSize.width, ptSize.height); - final int ptX = rightLine - ptSize.width/2; - final int ptY = Math.round(imgSize.height * (650f / 680)) - 10; - this.ptText.setLocation(imgPos.x + ptX, imgPos.y + ptY); - // Toughness - final Dimension dmgSize = this.damageText.getPreferredSize(); - this.damageText.setSize(dmgSize.width, dmgSize.height); - final int dmgX = rightLine - dmgSize.width / 2; - final int dmgY = ptY - 16; - this.damageText.setLocation(imgPos.x + dmgX, imgPos.y + dmgY); - } - this.ptText.setVisible(isVisible); - this.damageText.setVisible(isVisible); - } - - private void displayCardNameOverlay(boolean isVisible, Dimension imgSize, Point imgPos) { - if (isVisible) { - final int titleX = Math.round(imgSize.width * (24f / 480)); - final int titleY = Math.round(imgSize.height * (54f / 640)) - 15; - final int titleH = Math.round(imgSize.height * (360f / 640)); - this.titleText.setBounds(imgPos.x + titleX, imgPos.y + titleY + 2, imgSize.width - 2 * titleX, titleH - titleY); - } - this.titleText.setVisible(isVisible); } @Override diff --git a/forge-gui-mobile/src/forge/card/CardRenderer.java b/forge-gui-mobile/src/forge/card/CardRenderer.java index 3512f5e47f3..62f7bdc2e6a 100644 --- a/forge-gui-mobile/src/forge/card/CardRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardRenderer.java @@ -505,8 +505,8 @@ public class CardRenderer { } if (pc.isFoil()) { //draw foil effect if needed final CardView card = ViewUtil.getCardForUi(pc); - if (card.getFoilIndex() == 0) { //if foil finish not yet established, assign a random one - card.setRandomFoil(); + if (card.getOriginal().getFoilIndex() == 0) { //if foil finish not yet established, assign a random one + card.getOriginal().setRandomFoil(); } drawFoilEffect(g, card, x, y, w, h); } @@ -686,7 +686,7 @@ public class CardRenderer { public static void drawFoilEffect(Graphics g, CardView card, float x, float y, float w, float h) { if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT)) { - int foil = card.getFoilIndex(); + int foil = card.getOriginal().getFoilIndex(); if (foil > 0) { CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h); } diff --git a/forge-gui/src/main/java/forge/util/DevModeUtil.java b/forge-gui/src/main/java/forge/util/DevModeUtil.java index 3709da0eb87..db5837227c7 100644 --- a/forge-gui/src/main/java/forge/util/DevModeUtil.java +++ b/forge-gui/src/main/java/forge/util/DevModeUtil.java @@ -46,6 +46,7 @@ import forge.util.gui.SGuiDialog; import forge.util.gui.SOptionPane; import forge.view.CardView; import forge.view.PlayerView; +import forge.view.SpellAbilityView; public final class DevModeUtil { @@ -437,7 +438,14 @@ public final class DevModeUtil { return; // when would it happen? } - final SpellAbility sa = choices.size() == 1 ? choices.get(0) : SGuiChoose.oneOrNone(controller.getGui(), "Choose", choices); + final SpellAbility sa; + if (choices.size() == 1) { + sa = choices.iterator().next(); + } else { + final SpellAbilityView saView = SGuiChoose.oneOrNone(controller.getGui(), "Choose", controller.getSpellAbilityViews(choices)); + sa = controller.getSpellAbility(saView); + } + if (sa == null) { return; // happens if cancelled } diff --git a/forge-gui/src/main/java/forge/view/CardView.java b/forge-gui/src/main/java/forge/view/CardView.java index f3263ecd03d..a43ef94f9df 100644 --- a/forge-gui/src/main/java/forge/view/CardView.java +++ b/forge-gui/src/main/java/forge/view/CardView.java @@ -34,7 +34,6 @@ public class CardView extends GameEntityView { private final boolean isUiDisplayable; private PlayerView owner, controller; private ZoneType zone; - private int foilIndex; private boolean isCloned, isFaceDown, isFlipCard, isFlipped, isSplitCard, isTransformed; private String setCode; private CardRarity rarity; @@ -71,7 +70,6 @@ public class CardView extends GameEntityView { this.owner = null; this.controller = null; this.zone = null; - this.foilIndex = 0; this.isCloned = false; this.isFaceDown = false; this.isFlipped = false; @@ -186,24 +184,6 @@ public class CardView extends GameEntityView { this.hasAltState = hasAltState; } - /** - * @return the foilIndex - */ - public int getFoilIndex() { - return foilIndex; - } - - /** - * @param foilIndex the foilIndex to set - */ - public void setFoilIndex(final int foilIndex) { - this.foilIndex = foilIndex; - } - - public void setRandomFoil() { - this.setFoilIndex(CardEdition.getRandomFoil(getSetCode())); - } - /** * @return the isCloned */ @@ -760,6 +740,7 @@ public class CardView extends GameEntityView { private Map changedColorWords, changedTypes; private boolean hasDeathtouch, hasInfect, hasStorm, hasTrample; + private int foilIndex; public CardStateView() { this.reset(); @@ -781,6 +762,7 @@ public class CardView extends GameEntityView { this.hasInfect = false; this.hasStorm = false; this.hasTrample = false; + this.foilIndex = 0; } @Override @@ -1006,6 +988,24 @@ public class CardView extends GameEntityView { this.hasTrample = hasTrample; } + /** + * @return the foilIndex + */ + public int getFoilIndex() { + return foilIndex; + } + + /** + * @param foilIndex the foilIndex to set + */ + public void setFoilIndex(final int foilIndex) { + this.foilIndex = foilIndex; + } + + public void setRandomFoil() { + this.setFoilIndex(CardEdition.getRandomFoil(getSetCode())); + } + public boolean isBasicLand() { return this.isLand() && Iterables.any(type, Predicates.in(CardType.getBasicTypes())); } diff --git a/forge-gui/src/main/java/forge/view/ViewUtil.java b/forge-gui/src/main/java/forge/view/ViewUtil.java index b6149c8240b..07c14108d5c 100644 --- a/forge-gui/src/main/java/forge/view/ViewUtil.java +++ b/forge-gui/src/main/java/forge/view/ViewUtil.java @@ -32,7 +32,6 @@ public final class ViewUtil { view.setZone(c.getZone() == null ? null : c.getZone().getZoneType()); view.setHasAltState(hasAltState); view.setFaceDown(c.isFaceDown()); - view.setFoilIndex(c.getFoil()); view.setCloned(c.isCloned()); view.setFlipCard(c.isFlipCard()); view.setFlipped(c.getCurState().equals(CardCharacteristicName.Flipped)); @@ -85,6 +84,7 @@ public final class ViewUtil { origView.setHasInfect(c.hasKeyword("Infect")); origView.setHasStorm(c.hasKeyword("Storm")); origView.setHasTrample(c.hasKeyword("Trample")); + origView.setFoilIndex(c.getCharacteristics().getFoil()); final CardStateView altView = view.getAlternate(); CardCharacteristicName altState = null; @@ -116,8 +116,9 @@ public final class ViewUtil { view.setManaCost(chars.getManaCost()); view.setPower(chars.getBaseAttack()); view.setToughness(chars.getBaseDefense()); - view.setLoyalty(0); // FIXME why is loyalty not a property of CardCharacteristic? + view.setLoyalty(0); // Q why is loyalty not a property of CardCharacteristic? A: because no alt states have a base loyalty (only candidate is Garruk Relentless). view.setText(chars.getOracleText()); + view.setFoilIndex(chars.getFoil()); } public static CardView getCardForUi(final IPaperCard pc) {