From b40e7222b3fa39c5389963103620e849cba759f8 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 19 Sep 2024 13:42:23 +0400 Subject: [PATCH] Dungeon improves: * Dungeons: added dungeon name hint to room's game log and choices (part of #12274); * GUI, game: added card popup hints support in feedback panel (yes/no choices); * Images: fixed miss images for dungeons in command zone, game logs and choice dialogs; --- .../client/components/MageEditorPane.java | 12 ++++++- .../mage/client/dialog/PickChoiceDialog.java | 2 +- .../java/mage/client/game/FeedbackPanel.java | 5 +-- .../main/java/mage/client/game/GamePanel.java | 23 ++++++++---- .../java/mage/client/game/HelperPanel.java | 4 ++- .../src/main/java/mage/view/CardView.java | 18 ++++++---- Mage/src/main/java/mage/game/GameImpl.java | 11 +++++- .../main/java/mage/game/command/Dungeon.java | 36 ++++++++++++++++--- .../java/mage/game/command/DungeonRoom.java | 9 +++-- 9 files changed, 94 insertions(+), 26 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/components/MageEditorPane.java b/Mage.Client/src/main/java/mage/client/components/MageEditorPane.java index 6cd2e782184..48616418a5e 100644 --- a/Mage.Client/src/main/java/mage/client/components/MageEditorPane.java +++ b/Mage.Client/src/main/java/mage/client/components/MageEditorPane.java @@ -8,10 +8,12 @@ import mage.client.cards.BigCard; import mage.client.cards.VirtualCardInfo; import mage.client.dialog.PreferencesDialog; import mage.client.game.GamePanel; +import mage.game.command.Dungeon; import mage.game.command.Plane; import mage.util.CardUtil; import mage.util.GameLog; import mage.view.CardView; +import mage.view.DungeonView; import mage.view.PlaneView; import javax.swing.*; @@ -156,7 +158,7 @@ public class MageEditorPane extends JEditorPane { // show real object by priority (workable card hints and actual info) CardView cardView = needCard; - // if no game object found then show default card + // if no game object found then show default card/object if (cardView == null) { CardInfo card = CardRepository.instance.findCards(cardName).stream().findFirst().orElse(null); if (card != null) { @@ -172,6 +174,14 @@ public class MageEditorPane extends JEditorPane { } } + // dungeon + if (cardView == null) { + Dungeon dungeon = Dungeon.createDungeon(cardName, false); + if (dungeon != null) { + cardView = new CardView(new DungeonView(dungeon)); + } + } + // TODO: add other objects like dungeon, emblem, commander if (cardView != null) { diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java index 8090d65da04..8b2693d25ca 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java @@ -314,7 +314,7 @@ public class PickChoiceDialog extends MageDialog { cardInfo.init(item.getHint(), this.bigCard, this.gameId); } else if (item.getHintType() == ChoiceHintType.CARD_DUNGEON) { // as card name - CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(item.getHint()))); + CardView cardView = new CardView(new DungeonView(Dungeon.createDungeon(item.getHint(), true))); cardInfo.init(cardView, this.bigCard, this.gameId); } else if (item.getHintType() == ChoiceHintType.GAME_OBJECT) { // as object diff --git a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java index 90db8ae049e..bd32fd99840 100644 --- a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java @@ -2,6 +2,7 @@ package mage.client.game; import mage.client.MageFrame; import mage.client.SessionHandler; +import mage.client.cards.BigCard; import mage.client.chat.ChatPanelBasic; import mage.client.dialog.MageDialog; import mage.client.util.audio.AudioManager; @@ -56,9 +57,9 @@ public class FeedbackPanel extends javax.swing.JPanel { customInitComponents(); } - public void init(UUID gameId) { + public void init(UUID gameId, BigCard bigCard) { this.gameId = gameId; - helper.init(gameId); + helper.init(gameId, bigCard); setGUISize(); } 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 c22d72ce1c5..70f9a813aa0 100644 --- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java +++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java @@ -196,11 +196,20 @@ public final class GamePanel extends javax.swing.JPanel { 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 + // commanders and custom emblems player.getCommandObjectList() - .stream() - .filter(c -> c instanceof CardView) - .map(c -> (CardView) c) - .forEach(c -> this.allCardsIndex.put(c.getId(), c)); + .forEach(object -> { + if (object instanceof CardView) { + // commanders and custom emblems + this.allCardsIndex.put(object.getId(), (CardView) object); + } else if (object instanceof DungeonView) { + // dungeons + this.allCardsIndex.put(object.getId(), new CardView((DungeonView) object)); + } else { + // TODO: enable after all view types added here? + //throw new IllegalArgumentException("Unsupported object type: " + object.getName() + " - " + object.getClass().getSimpleName()); + } + }); }); } @@ -808,7 +817,7 @@ public final class GamePanel extends javax.swing.JPanel { this.gamePane = gamePane; this.playerId = playerId; MageFrame.addGame(gameId, this); - this.feedbackPanel.init(gameId); + this.feedbackPanel.init(gameId, bigCard); this.feedbackPanel.clear(); this.abilityPicker.init(gameId, bigCard); this.btnConcede.setVisible(true); @@ -851,7 +860,7 @@ public final class GamePanel extends javax.swing.JPanel { this.gamePane = gamePane; this.playerId = null; MageFrame.addGame(gameId, this); - this.feedbackPanel.init(gameId); + this.feedbackPanel.init(gameId, bigCard); this.feedbackPanel.clear(); this.btnConcede.setVisible(false); @@ -886,7 +895,7 @@ public final class GamePanel extends javax.swing.JPanel { this.gameId = gameId; this.playerId = null; MageFrame.addGame(gameId, this); - this.feedbackPanel.init(gameId); + this.feedbackPanel.init(gameId, bigCard); this.feedbackPanel.clear(); this.btnConcede.setVisible(false); this.btnSkipToNextTurn.setVisible(false); diff --git a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java index 074ef407182..3ae0d814c18 100644 --- a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java +++ b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java @@ -1,6 +1,7 @@ package mage.client.game; import mage.client.SessionHandler; +import mage.client.cards.BigCard; import mage.client.components.MageTextArea; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; @@ -89,8 +90,9 @@ public class HelperPanel extends JPanel { initComponents(); } - public void init(UUID gameId) { + public void init(UUID gameId, BigCard bigCard) { this.gameId = gameId; + this.dialogTextArea.setGameData(gameId, bigCard); } public void changeGUISize() { diff --git a/Mage.Common/src/main/java/mage/view/CardView.java b/Mage.Common/src/main/java/mage/view/CardView.java index 1462b395b35..bc03a3d3633 100644 --- a/Mage.Common/src/main/java/mage/view/CardView.java +++ b/Mage.Common/src/main/java/mage/view/CardView.java @@ -878,7 +878,8 @@ public class CardView extends SimpleCardView { this.displayName = name; this.displayFullName = name; this.rules = new ArrayList<>(emblem.getRules()); - // emblem images are always with common (black) symbol + + // image - emblem are always with common (black) symbol this.frameStyle = FrameStyle.M15_NORMAL; this.expansionSetCode = emblem.getExpansionSetCode(); this.cardNumber = emblem.getCardNumber(); @@ -901,12 +902,13 @@ public class CardView extends SimpleCardView { this.displayName = name; this.displayFullName = name; this.rules = new ArrayList<>(dungeon.getRules()); - // emblem images are always with common (black) symbol - this.frameStyle = FrameStyle.M15_NORMAL; + + // image + this.frameStyle = FrameStyle.M15_NORMAL; // TODO: needs in full art? Test dungeon choose dialog this.expansionSetCode = dungeon.getExpansionSetCode(); this.cardNumber = ""; - this.imageFileName = ""; - this.imageNumber = 0; + this.imageFileName = dungeon.getImageFileName(); + this.imageNumber = dungeon.getImageNumber(); this.rarity = Rarity.SPECIAL; this.playableStats = dungeon.playableStats.copy(); @@ -923,7 +925,8 @@ public class CardView extends SimpleCardView { this.displayName = name; this.displayFullName = name; this.rules = new ArrayList<>(plane.getRules()); - // Display the plane in landscape (similar to Fused cards) + + // image - display the plane in landscape (similar to Fused cards) this.rotate = true; this.frameStyle = FrameStyle.M15_NORMAL; this.expansionSetCode = plane.getExpansionSetCode(); @@ -947,6 +950,8 @@ public class CardView extends SimpleCardView { this.displayFullName = name; this.rules = new ArrayList<>(); this.rules.add(stackAbility.getRule(designation.getName())); + + // image this.frameStyle = FrameStyle.M15_NORMAL; this.cardNumber = designation.getCardNumber(); this.expansionSetCode = designation.getExpansionSetCode(); @@ -954,6 +959,7 @@ public class CardView extends SimpleCardView { this.imageFileName = ""; this.imageNumber = 0; this.rarity = Rarity.SPECIAL; + // no playable/chooseable marks for designations } diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index ba5d909dcf1..4631cb50f98 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -584,6 +584,9 @@ public abstract class GameImpl implements Game { return emblem; } TheRingEmblem newEmblem = new TheRingEmblem(playerId); + + // TODO: add image info + state.addCommandObject(newEmblem); return newEmblem; } @@ -1971,7 +1974,9 @@ public abstract class GameImpl implements Game { ability.setSourceId(newEmblem.getId()); } - state.addCommandObject(newEmblem); // TODO: generate image for emblem here? + // image info setup in setSourceObject + + state.addCommandObject(newEmblem); } /** @@ -1999,6 +2004,9 @@ public abstract class GameImpl implements Game { for (Ability ability : newPlane.getAbilities()) { ability.setSourceId(newPlane.getId()); } + + // image info setup in setSourceObject + state.addCommandObject(newPlane); informPlayers("You have planeswalked to " + newPlane.getLogName()); @@ -2020,6 +2028,7 @@ public abstract class GameImpl implements Game { @Override public Dungeon addDungeon(Dungeon dungeon, UUID playerId) { dungeon.setControllerId(playerId); + dungeon.setSourceObject(); state.addCommandObject(dungeon); return dungeon; } diff --git a/Mage/src/main/java/mage/game/command/Dungeon.java b/Mage/src/main/java/mage/game/command/Dungeon.java index adf15b5b8f4..8643378c17a 100644 --- a/Mage/src/main/java/mage/game/command/Dungeon.java +++ b/Mage/src/main/java/mage/game/command/Dungeon.java @@ -13,6 +13,8 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.hint.HintUtils; import mage.cards.FrameStyle; +import mage.cards.repository.TokenInfo; +import mage.cards.repository.TokenRepository; import mage.choices.Choice; import mage.choices.ChoiceHintType; import mage.choices.ChoiceImpl; @@ -87,6 +89,11 @@ public class Dungeon extends CommandObjectImpl { } public void moveToNextRoom(UUID playerId, Game game) { + Dungeon dungeon = game.getPlayerDungeon(playerId); + if (dungeon == null) { + return; + } + if (currentRoom == null) { currentRoom = dungeonRooms.get(0); } else { @@ -94,7 +101,7 @@ public class Dungeon extends CommandObjectImpl { } Player player = game.getPlayer(getControllerId()); if (player != null) { - game.informPlayers(player.getLogName() + " has entered " + currentRoom.getName()); + game.informPlayers(player.getLogName() + " has entered " + currentRoom.getName() + " (dungeon: " + dungeon.getLogName() + ")"); } game.fireEvent(GameEvent.getEvent( GameEvent.EventType.ROOM_ENTERED, currentRoom.getId(), null, playerId @@ -139,14 +146,14 @@ public class Dungeon extends CommandObjectImpl { choice.setChoices(dungeonNames); player.choose(Outcome.Neutral, choice, game); if (choice.getChoice() != null) { - return createDungeon(choice.getChoice()); + return createDungeon(choice.getChoice(), true); } else { // on disconnect - return createDungeon("Tomb of Annihilation"); + return createDungeon("Tomb of Annihilation", true); } } - public static Dungeon createDungeon(String name) { + public static Dungeon createDungeon(String name, boolean isNameMustExists) { switch (name) { case "Tomb of Annihilation": return new TombOfAnnihilationDungeon(); @@ -155,7 +162,26 @@ public class Dungeon extends CommandObjectImpl { case "Dungeon of the Mad Mage": return new DungeonOfTheMadMageDungeon(); default: - throw new UnsupportedOperationException("A dungeon should have been chosen"); + if (isNameMustExists) { + throw new UnsupportedOperationException("A dungeon should have been chosen"); + } else { + return null; + } + } + } + + public void setSourceObject() { + // choose set code due source + TokenInfo foundInfo = TokenRepository.instance.findPreferredTokenInfoForClass(this.getClass().getName(), null); + if (foundInfo != null) { + this.setExpansionSetCode(foundInfo.getSetCode()); + this.setUsesVariousArt(false); + this.setCardNumber(""); + this.setImageFileName(""); // use default + this.setImageNumber(foundInfo.getImageNumber()); + } else { + // how-to fix: add dungeon to the tokens-database + throw new IllegalArgumentException("Wrong code usage: can't find token info for the dungeon: " + this.getClass().getName()); } } diff --git a/Mage/src/main/java/mage/game/command/DungeonRoom.java b/Mage/src/main/java/mage/game/command/DungeonRoom.java index ba2174a7ecc..121264cef47 100644 --- a/Mage/src/main/java/mage/game/command/DungeonRoom.java +++ b/Mage/src/main/java/mage/game/command/DungeonRoom.java @@ -77,6 +77,11 @@ public class DungeonRoom { } public DungeonRoom chooseNextRoom(UUID playerId, Game game) { + Dungeon dungeon = game.getPlayerDungeon(playerId); + if (dungeon == null) { + return null; + } + switch (nextRooms.size()) { case 0: return null; @@ -90,8 +95,8 @@ public class DungeonRoom { return null; } return player.chooseUse( - Outcome.Neutral, "Choose which room to go to", - null, room1.name, room2.name, null, game + Outcome.Neutral, "Choose which room to go to in", + "dungeon: " + dungeon.getLogName(), room1.name, room2.name, null, game ) ? room1 : room2; default: throw new UnsupportedOperationException("there shouldn't be more than two rooms to go to");