From 939ff7b441b3c18d37237e5946b270ad88d0f867 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 26 Nov 2023 14:42:49 +0400 Subject: [PATCH] GUI: added real objects in card popup for game logs and hints toolbox (workable hints, actual abilities, etc - closes #9529) --- .../mage/client/components/ColorPane.java | 25 +++++--- .../main/java/mage/client/game/GamePanel.java | 59 +++++++++++++++---- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/components/ColorPane.java b/Mage.Client/src/main/java/mage/client/components/ColorPane.java index 79e8c3f7f95..93546310655 100644 --- a/Mage.Client/src/main/java/mage/client/components/ColorPane.java +++ b/Mage.Client/src/main/java/mage/client/components/ColorPane.java @@ -3,9 +3,11 @@ package mage.client.components; import mage.cards.action.TransferData; import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; +import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.cards.VirtualCardInfo; import mage.client.dialog.PreferencesDialog; +import mage.client.game.GamePanel; import mage.game.command.Plane; import mage.util.CardUtil; import mage.util.GameLog; @@ -80,6 +82,14 @@ public class ColorPane extends JEditorPane { } } + // try object first + CardView needCard = null; + GamePanel gamePanel = MageFrame.getGame(this.gameId); + if (gamePanel != null) { + UUID needObjectId = UUID.fromString(extraData.getOrDefault("object_id", "")); + needCard = gamePanel.getLastGameData().findCard(needObjectId); + } + String cardName = e.getDescription().substring(1); String alternativeName = CardUtil.urlDecode(extraData.getOrDefault("alternative_name", "")); if (!alternativeName.isEmpty()) { @@ -87,14 +97,15 @@ public class ColorPane extends JEditorPane { } if (e.getEventType() == EventType.ENTERED) { - CardView cardView = null; + // show real object by priority (workable card hints and actual info) + CardView cardView = needCard; - // TODO: add real game object first - - // card - CardInfo card = CardRepository.instance.findCards(cardName).stream().findFirst().orElse(null); - if (card != null) { - cardView = new CardView(card.getMockCard()); + // if no game object found then show default card + if (cardView == null) { + CardInfo card = CardRepository.instance.findCards(cardName).stream().findFirst().orElse(null); + if (card != null) { + cardView = new CardView(card.getMockCard()); + } } // plane diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java index 5fba1fd5cd6..f027a8adc51 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -125,16 +125,63 @@ public final class GamePanel extends javax.swing.JPanel { private JPopupMenu popupMenuTriggerOrder; // keep game data for updates/re-draws - static class LastGameData { + public static class LastGameData { int messageId; GameView game; boolean showPlayable; Map options; Set targets; + Map allCardsIndex = new HashMap<>(); // fast access to all game objects (for cards hints, etc) + + private void setNewGame(GameView game) { + this.game = game; + prepareAllCardsIndex(); + } + + private void prepareAllCardsIndex() { + this.allCardsIndex.clear(); + if (this.game == null) { + return; + } + + this.game.getHand().values().forEach(c -> this.allCardsIndex.put(c.getId(), c)); + this.game.getStack().values().forEach(c -> this.allCardsIndex.put(c.getId(), c)); + this.game.getExile() + .stream() + .flatMap(s -> s.values().stream()) + .forEach(c -> this.allCardsIndex.put(c.getId(), c)); + this.game.getLookedAt() + .stream() + .flatMap(s -> s.getCards().values().stream()) + .filter(c -> c instanceof CardView) + .map(c -> (CardView) c) + .forEach(c -> this.allCardsIndex.put(c.getId(), c)); + this.game.getRevealed().stream() + .flatMap(s -> s.getCards().values().stream()) + .forEach(c -> this.allCardsIndex.put(c.getId(), c)); + this.game.getPlayers().forEach(player -> { + player.getBattlefield().values().forEach(c -> this.allCardsIndex.put(c.getId(), c)); + player.getGraveyard().values().forEach(c -> this.allCardsIndex.put(c.getId(), c)); + Optional.ofNullable(player.getTopCard()).ifPresent(c -> this.allCardsIndex.put(c.getId(), c)); + // TODO: add support of dungeon, emblem all another non-card objects + player.getCommandObjectList() + .stream() + .filter(c -> c instanceof CardView) + .map(c -> (CardView) c) + .forEach(c -> this.allCardsIndex.put(c.getId(), c)); + }); + } + + public CardView findCard(UUID id) { + return this.allCardsIndex.getOrDefault(id, null); + } } private final LastGameData lastGameData = new LastGameData(); + public LastGameData getLastGameData() { + return this.lastGameData; + } public GamePanel() { initComponents = true; @@ -1416,7 +1463,7 @@ public final class GamePanel extends javax.swing.JPanel { private void keepLastGameData(int messageId, GameView game, boolean showPlayable, Map options, Set targets) { lastGameData.messageId = messageId; - lastGameData.game = game; + lastGameData.setNewGame(game); lastGameData.showPlayable = showPlayable; lastGameData.options = options; lastGameData.targets = targets; @@ -2930,14 +2977,6 @@ public final class GamePanel extends javax.swing.JPanel { return gameChatPanel.getText(); } - public Map getLoadedCards() { - return loadedCards; - } - - public void setLoadedCards(Map loadedCards) { - this.loadedCards = loadedCards; - } - public FeedbackPanel getFeedbackPanel() { return feedbackPanel; }