From 4a38b0d817af75d19fc6c6010349b24afed1b22e Mon Sep 17 00:00:00 2001 From: elcnesh Date: Tue, 17 Feb 2015 08:47:55 +0000 Subject: [PATCH] Huge update to the GUI codebase. - Make match screen in gui-desktop non-singleton, allowing multiple games to be played simultaneously. - Separate global gui commands (IGuiBase) from game-specific gui commands (IGuiGame), allowing games to send their commands to the correct gui. --- .gitattributes | 16 +- .../java/forge/ai/PlayerControllerAi.java | 4 + .../java/forge/ai/simulation/GameCopier.java | 2 +- .../java/forge/card/mana/ManaCostShard.java | 2 +- forge-game/src/main/java/forge/game/Game.java | 18 +- .../java/forge/game/GameLogEntryType.java | 1 + .../src/main/java/forge/game/GameType.java | 7 +- .../src/main/java/forge/game/GameView.java | 19 +- .../src/main/java/forge/game/Match.java | 42 +- .../forge/game/ability/AbilityFactory.java | 2 +- .../java/forge/game/card/CardFactoryUtil.java | 44 +- .../main/java/forge/game/card/CardView.java | 4 +- .../src/main/java/forge/game/event/Event.java | 5 + .../main/java/forge/game/event/GameEvent.java | 2 +- .../forge/game/player/PlayerController.java | 83 +-- .../java/forge/game/player/PlayerView.java | 21 + .../forge/game/trigger/TriggerHandler.java | 15 +- .../main/java/forge/game/zone/MagicStack.java | 2 +- .../forge/trackable/TrackableProperty.java | 1 + .../src/main/java/forge/GuiDesktop.java | 66 +- .../src/main/java/forge/ImageCache.java | 8 +- .../src/main/java/forge/control/FControl.java | 44 +- .../java/forge/control/KeyboardShortcuts.java | 72 +- .../java/forge/deckchooser/FDeckChooser.java | 10 +- .../java/forge/deckchooser/FDeckViewer.java | 6 +- .../main/java/forge/gui/CardDetailPanel.java | 5 +- .../main/java/forge/gui/CardPicturePanel.java | 2 +- .../src/main/java/forge/gui/DualListBox.java | 28 +- .../src/main/java/forge/gui/GuiChoose.java | 89 +-- .../src/main/java/forge/gui/GuiDialog.java | 13 +- .../src/main/java/forge/gui/GuiUtils.java | 37 - .../main/java/forge/gui/SOverlayUtils.java | 31 +- .../java/forge/gui/framework/CEmptyDoc.java | 4 + .../main/java/forge/gui/framework/EDocID.java | 101 +-- .../java/forge/gui/framework/FScreen.java | 142 ++-- .../main/java/forge/gui/framework/ICDoc.java | 33 +- .../java/forge/gui/framework/SLayoutIO.java | 52 ++ .../java/forge/itemmanager/CardManager.java | 6 +- .../java/forge/itemmanager/DeckManager.java | 43 +- .../java/forge/itemmanager/ItemManager.java | 9 +- .../forge/itemmanager/SpellShopManager.java | 5 +- .../forge/itemmanager/views/ImageView.java | 60 +- .../forge/itemmanager/views/ItemView.java | 54 +- .../src/main/java/forge/menus/ForgeMenu.java | 4 +- .../src/main/java/forge/menus/LayoutMenu.java | 56 +- .../java/forge/screens/bazaar/CBazaarUI.java | 4 + .../screens/deckeditor/CDeckEditorUI.java | 64 +- .../deckeditor/controllers/ACEditorBase.java | 7 + .../deckeditor/controllers/CAllDecks.java | 4 + .../deckeditor/controllers/CCardCatalog.java | 4 + .../deckeditor/controllers/CCurrentDeck.java | 4 + .../deckeditor/controllers/CDeckgen.java | 4 + .../controllers/CEditorCommander.java | 4 +- .../controllers/CEditorConstructed.java | 4 +- .../controllers/CEditorDraftingProcess.java | 4 +- .../controllers/CEditorLimited.java | 4 +- .../deckeditor/controllers/CEditorQuest.java | 4 +- .../controllers/CEditorQuestCardShop.java | 4 +- .../CEditorQuestDraftingProcess.java | 4 +- .../controllers/CEditorQuestLimited.java | 4 +- .../controllers/CEditorVariant.java | 4 +- .../controllers/CEditorWinstonProcess.java | 4 +- .../controllers/CProbabilities.java | 4 + .../deckeditor/controllers/CStatistics.java | 4 + .../screens/deckeditor/views/VAllDecks.java | 13 +- .../main/java/forge/screens/home/CHomeUI.java | 7 +- .../home/gauntlet/CSubmenuGauntletBuild.java | 4 + .../gauntlet/CSubmenuGauntletContests.java | 21 +- .../home/gauntlet/CSubmenuGauntletLoad.java | 17 +- .../home/gauntlet/CSubmenuGauntletQuick.java | 17 +- .../home/gauntlet/VSubmenuGauntletBuild.java | 2 +- .../gauntlet/VSubmenuGauntletContests.java | 2 +- .../home/gauntlet/VSubmenuGauntletQuick.java | 2 +- .../home/online/CSubmenuOnlineLobby.java | 5 + .../home/quest/CSubmenuChallenges.java | 4 + .../screens/home/quest/CSubmenuDuels.java | 4 + .../screens/home/quest/CSubmenuQuestData.java | 4 + .../home/quest/CSubmenuQuestDecks.java | 4 + .../home/quest/CSubmenuQuestDraft.java | 26 +- .../home/quest/CSubmenuQuestPrefs.java | 4 + .../home/quest/VSubmenuQuestDecks.java | 2 +- .../home/sanctioned/CSubmenuConstructed.java | 52 +- .../home/sanctioned/CSubmenuDraft.java | 19 +- .../home/sanctioned/CSubmenuSealed.java | 4 + .../home/sanctioned/CSubmenuWinston.java | 19 +- .../home/sanctioned/VSubmenuConstructed.java | 2 +- .../home/sanctioned/VSubmenuDraft.java | 4 +- .../home/sanctioned/VSubmenuSealed.java | 2 +- .../home/sanctioned/VSubmenuWinston.java | 2 +- .../home/settings/CSubmenuAchievements.java | 4 + .../home/settings/CSubmenuAvatars.java | 4 + .../home/settings/CSubmenuDownloaders.java | 4 + .../home/settings/CSubmenuPreferences.java | 7 +- .../home/settings/CSubmenuReleaseNotes.java | 4 + .../home/settings/VSubmenuPreferences.java | 52 +- .../java/forge/screens/match/CMatchUI.java | 584 +++++++++++----- .../forge/screens/match/ControlWinLose.java | 21 +- .../forge/screens/match/GauntletWinLose.java | 4 +- .../forge/screens/match/LimitedWinLose.java | 4 +- .../screens/match/QuestDraftWinLose.java | 30 +- .../forge/screens/match/QuestWinLose.java | 4 +- .../forge/screens/match/TargetingOverlay.java | 61 +- .../forge/screens/match/VAssignDamage.java | 28 +- .../java/forge/screens/match/VAutoYields.java | 14 +- .../java/forge/screens/match/VMatchUI.java | 95 ++- .../java/forge/screens/match/ViewWinLose.java | 27 +- .../java/forge/screens/match/ZoneAction.java | 6 +- .../screens/match/controllers/CAntes.java | 25 +- .../screens/match/controllers/CCombat.java | 22 +- .../screens/match/controllers/CCommand.java | 4 + .../screens/match/controllers/CDetail.java | 51 +- .../match/controllers/CDetailPicture.java | 98 +++ .../forge/screens/match/controllers/CDev.java | 98 +-- .../screens/match/controllers/CDock.java | 178 ++--- .../screens/match/controllers/CField.java | 30 +- .../screens/match/controllers/CHand.java | 26 +- .../forge/screens/match/controllers/CLog.java | 26 +- .../screens/match/controllers/CPicture.java | 118 ++-- .../screens/match/controllers/CPlayers.java | 25 +- .../screens/match/controllers/CPrompt.java | 39 +- .../screens/match/controllers/CStack.java | 25 +- .../screens/match/menus/CMatchUIMenus.java | 22 +- .../screens/match/menus/CardOverlaysMenu.java | 21 +- .../screens/match/menus/DevModeMenu.java | 79 ++- .../forge/screens/match/menus/GameMenu.java | 104 +-- .../forge/screens/match/views/VAntes.java | 20 +- .../forge/screens/match/views/VCombat.java | 14 +- .../forge/screens/match/views/VCommand.java | 6 +- .../forge/screens/match/views/VDetail.java | 11 +- .../java/forge/screens/match/views/VDev.java | 12 +- .../java/forge/screens/match/views/VDock.java | 12 +- .../forge/screens/match/views/VField.java | 12 +- .../java/forge/screens/match/views/VHand.java | 8 +- .../java/forge/screens/match/views/VLog.java | 18 +- .../forge/screens/match/views/VPicture.java | 11 +- .../forge/screens/match/views/VPlayers.java | 21 +- .../forge/screens/match/views/VPrompt.java | 12 +- .../forge/screens/match/views/VStack.java | 81 +-- .../forge/screens/workshop/CWorkshopUI.java | 20 +- .../workshop/controllers/CCardDesigner.java | 4 + .../workshop/controllers/CCardScript.java | 61 +- .../controllers/CWorkshopCatalog.java | 4 + .../screens/workshop/views/VCardScript.java | 40 +- .../workshop/views/VWorkshopCatalog.java | 32 +- .../main/java/forge/toolbox/FUndoManager.java | 26 +- .../forge/toolbox/imaging/FImageUtil.java | 16 +- .../forge/toolbox/special/CardZoomer.java | 12 +- .../toolbox/special/PlayerDetailsPanel.java | 24 +- .../src/main/java/forge/view/ButtonUtil.java | 82 --- .../src/main/java/forge/view/FDialog.java | 47 +- .../src/main/java/forge/view/FFrame.java | 30 +- .../main/java/forge/view/FNavigationBar.java | 65 +- .../src/main/java/forge/view/FView.java | 71 +- .../main/java/forge/view/SimulateMatch.java | 2 +- .../main/java/forge/view/arcane/CardArea.java | 7 +- .../java/forge/view/arcane/CardPanel.java | 23 +- .../forge/view/arcane/CardPanelContainer.java | 14 +- .../forge/view/arcane/FloatingCardArea.java | 48 +- .../main/java/forge/view/arcane/HandArea.java | 18 +- .../main/java/forge/view/arcane/PlayArea.java | 16 +- .../forge/view/arcane/util/Animation.java | 206 +----- .../ai/simulation/GameSimulatorTest.java | 2 +- .../gamesimulationtests/util/GameWrapper.java | 2 +- .../util/PlayerControllerForTests.java | 5 + forge-gui-mobile/src/forge/Forge.java | 14 +- forge-gui-mobile/src/forge/GuiMobile.java | 87 +-- .../src/forge/assets/ImageCache.java | 6 +- .../src/forge/card/CardImageRenderer.java | 12 +- .../src/forge/card/CardRenderer.java | 8 +- forge-gui-mobile/src/forge/card/CardZoom.java | 7 +- .../src/forge/screens/LaunchScreen.java | 21 +- .../constructed/ConstructedScreen.java | 3 + .../screens/limited/LoadSealedScreen.java | 2 +- .../forge/screens/match/MatchController.java | 177 ++++- .../src/forge/screens/match/MatchScreen.java | 30 +- .../screens/match/views/VAssignDamage.java | 3 +- .../screens/match/views/VAutoYields.java | 13 +- .../forge/screens/match/views/VAvatar.java | 3 +- .../screens/match/views/VCardDisplayArea.java | 6 +- .../forge/screens/match/views/VDevMenu.java | 36 +- .../forge/screens/match/views/VGameMenu.java | 30 +- .../src/forge/screens/match/views/VLog.java | 4 +- .../forge/screens/match/views/VManaPool.java | 6 +- .../screens/match/views/VPlayerPanel.java | 5 +- .../forge/screens/match/views/VPlayers.java | 8 +- .../src/forge/screens/match/views/VStack.java | 55 +- .../screens/match/winlose/ControlWinLose.java | 8 +- .../src/forge/toolbox/FDialog.java | 4 +- .../src/forge/toolbox/FOptionPane.java | 12 + .../achievement/AchievementCollection.java | 7 +- .../main/java/forge/card/CardDetailUtil.java | 8 +- .../java/forge/card/CardScriptParser.java | 522 ++++++++++++++ .../control/FControlGameEventHandler.java | 62 +- .../forge/control/FControlGamePlayback.java | 62 +- .../java/forge/control/WatchLocalGame.java | 56 +- .../java/forge/events/IUiEventVisitor.java | 1 + .../src/main/java/forge/events/UiEvent.java | 3 +- .../forge/events/UiEventAttackerDeclared.java | 5 +- .../forge/events/UiEventNextGameDecision.java | 28 + .../gauntlet/GauntletWinLoseController.java | 22 +- .../java/forge/interfaces/IDevModeCheats.java | 87 +++ .../forge/interfaces/IGameController.java | 45 ++ .../main/java/forge/interfaces/IGuiBase.java | 32 +- .../main/java/forge/interfaces/IGuiGame.java | 196 ++++++ .../java/forge/interfaces/IMayViewCards.java | 36 + .../main/java/forge/limited/GauntletMini.java | 20 +- .../java/forge/match/AbstractGuiGame.java | 648 ++++++++++++++++++ .../main/java/forge/match/HostedMatch.java | 358 ++++++++++ .../java/forge/match/IMatchController.java | 54 -- .../src/main/java/forge/match/MatchUtil.java | 459 ------------- .../java/forge/match/NextGameDecision.java | 7 + .../java/forge/match/input/ButtonUtil.java | 46 -- .../java/forge/match/input/InputAttack.java | 28 +- .../java/forge/match/input/InputBase.java | 72 +- .../java/forge/match/input/InputBlock.java | 16 +- .../java/forge/match/input/InputConfirm.java | 2 +- .../match/input/InputConfirmMulligan.java | 16 +- .../java/forge/match/input/InputLockUI.java | 12 +- .../forge/match/input/InputPassPriority.java | 31 +- .../java/forge/match/input/InputPayMana.java | 23 +- .../match/input/InputPlaybackControl.java | 23 +- .../forge/match/input/InputProliferate.java | 3 +- .../java/forge/match/input/InputProxy.java | 8 +- .../java/forge/match/input/InputQueue.java | 24 +- .../match/input/InputSelectManyBase.java | 7 +- .../forge/match/input/InputSelectTargets.java | 19 +- .../planarconquest/ConquestController.java | 22 +- .../java/forge/player/GamePlayerUtil.java | 12 - .../java/forge/player/HumanCostDecision.java | 70 +- .../src/main/java/forge/player/HumanPlay.java | 2 +- .../java/forge/player/LobbyPlayerHuman.java | 9 +- .../forge/player/PlayerControllerHuman.java | 367 ++++++---- .../java/forge/player/TargetSelection.java | 12 +- .../forge/properties/ForgePreferences.java | 1 + .../java/forge/quest/QuestDraftUtils.java | 121 ++-- .../java/forge/quest/QuestRewardCard.java | 9 +- .../forge/quest/QuestRewardCardChooser.java | 17 +- .../forge/quest/QuestRewardCardFiltered.java | 2 +- .../src/main/java/forge/quest/QuestUtil.java | 41 +- .../main/java/forge/quest/io/QuestDataIO.java | 3 +- .../java/forge/sound/EventVisualizer.java | 5 + .../main/java/forge/util/gui/SGuiChoose.java | 31 +- .../main/java/forge/util/gui/SGuiDialog.java | 39 -- .../main/java/forge/util/gui/SOptionPane.java | 5 - 244 files changed, 5532 insertions(+), 3554 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/event/Event.java create mode 100644 forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java delete mode 100644 forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java create mode 100644 forge-gui/src/main/java/forge/card/CardScriptParser.java create mode 100644 forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java create mode 100644 forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java create mode 100644 forge-gui/src/main/java/forge/interfaces/IGameController.java create mode 100644 forge-gui/src/main/java/forge/interfaces/IGuiGame.java create mode 100644 forge-gui/src/main/java/forge/interfaces/IMayViewCards.java create mode 100644 forge-gui/src/main/java/forge/match/AbstractGuiGame.java create mode 100644 forge-gui/src/main/java/forge/match/HostedMatch.java delete mode 100644 forge-gui/src/main/java/forge/match/IMatchController.java delete mode 100644 forge-gui/src/main/java/forge/match/MatchUtil.java create mode 100644 forge-gui/src/main/java/forge/match/NextGameDecision.java delete mode 100644 forge-gui/src/main/java/forge/match/input/ButtonUtil.java delete mode 100644 forge-gui/src/main/java/forge/util/gui/SGuiDialog.java diff --git a/.gitattributes b/.gitattributes index e270a904026..24d73faa4af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -514,6 +514,7 @@ forge-game/src/main/java/forge/game/cost/CostUntapType.java -text forge-game/src/main/java/forge/game/cost/ICostVisitor.java -text forge-game/src/main/java/forge/game/cost/PaymentDecision.java -text forge-game/src/main/java/forge/game/cost/package-info.java svneol=native#text/plain +forge-game/src/main/java/forge/game/event/Event.java -text forge-game/src/main/java/forge/game/event/EventValueChangeType.java -text forge-game/src/main/java/forge/game/event/GameEvent.java -text forge-game/src/main/java/forge/game/event/GameEventAnteCardsSelected.java -text @@ -1009,6 +1010,7 @@ forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java -tex forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java -text forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java -text forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java -text +forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java -text forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java -text forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java -text forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java -text @@ -1099,7 +1101,6 @@ forge-gui-desktop/src/main/java/forge/toolbox/special/PhaseLabel.java -text forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java -text forge-gui-desktop/src/main/java/forge/toolbox/special/package-info.java -text forge-gui-desktop/src/main/java/forge/util/AwtUtil.java -text -forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java -text forge-gui-desktop/src/main/java/forge/view/FDialog.java -text forge-gui-desktop/src/main/java/forge/view/FFrame.java -text forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java -text @@ -17343,6 +17344,7 @@ forge-gui/src/main/java/forge/card/CardDetailUtil.java -text forge-gui/src/main/java/forge/card/CardPreferences.java -text forge-gui/src/main/java/forge/card/CardReaderExperiments.java -text forge-gui/src/main/java/forge/card/CardScriptInfo.java -text +forge-gui/src/main/java/forge/card/CardScriptParser.java -text forge-gui/src/main/java/forge/control/ChatArea.java -text forge-gui/src/main/java/forge/control/FControlGameEventHandler.java -text forge-gui/src/main/java/forge/control/FControlGamePlayback.java -text @@ -17370,6 +17372,7 @@ forge-gui/src/main/java/forge/events/IUiEventVisitor.java -text forge-gui/src/main/java/forge/events/UiEvent.java -text forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java -text forge-gui/src/main/java/forge/events/UiEventBlockerAssigned.java -text +forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java -text forge-gui/src/main/java/forge/gauntlet/GauntletData.java -text forge-gui/src/main/java/forge/gauntlet/GauntletIO.java -text forge-gui/src/main/java/forge/gauntlet/GauntletUtil.java -text @@ -17377,9 +17380,13 @@ forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java -text forge-gui/src/main/java/forge/interfaces/IButton.java -text forge-gui/src/main/java/forge/interfaces/ICheckBox.java -text forge-gui/src/main/java/forge/interfaces/IComboBox.java -text +forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java -text forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java -text +forge-gui/src/main/java/forge/interfaces/IGameController.java -text forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text +forge-gui/src/main/java/forge/interfaces/IGuiGame.java -text forge-gui/src/main/java/forge/interfaces/IGuiTimer.java -text +forge-gui/src/main/java/forge/interfaces/IMayViewCards.java -text forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text forge-gui/src/main/java/forge/interfaces/ITextField.java -text forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text @@ -17414,10 +17421,10 @@ forge-gui/src/main/java/forge/limited/SealedDeckBuilder.java svneol=native#text/ forge-gui/src/main/java/forge/limited/WinstonDraft.java -text forge-gui/src/main/java/forge/limited/WinstonDraftAI.java -text forge-gui/src/main/java/forge/limited/package-info.java svneol=native#text/plain -forge-gui/src/main/java/forge/match/IMatchController.java -text +forge-gui/src/main/java/forge/match/AbstractGuiGame.java -text +forge-gui/src/main/java/forge/match/HostedMatch.java -text forge-gui/src/main/java/forge/match/MatchConstants.java -text -forge-gui/src/main/java/forge/match/MatchUtil.java -text -forge-gui/src/main/java/forge/match/input/ButtonUtil.java -text +forge-gui/src/main/java/forge/match/NextGameDecision.java -text forge-gui/src/main/java/forge/match/input/Input.java -text forge-gui/src/main/java/forge/match/input/InputAttack.java -text forge-gui/src/main/java/forge/match/input/InputBase.java -text @@ -17547,7 +17554,6 @@ forge-gui/src/main/java/forge/util/WaitCallback.java -text forge-gui/src/main/java/forge/util/WaitRunnable.java -text forge-gui/src/main/java/forge/util/XmlUtil.java -text forge-gui/src/main/java/forge/util/gui/SGuiChoose.java -text -forge-gui/src/main/java/forge/util/gui/SGuiDialog.java -text forge-gui/src/main/java/forge/util/gui/SOptionPane.java -text forge-gui/src/main/java/forge/util/package-info.java -text forge-gui/src/main/resources/proxy-template.ftl -text diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 383f97d8428..0bdc7e28290 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -854,4 +854,8 @@ public class PlayerControllerAi extends PlayerController { getAi().getCardMemory().clearAllRemembered(); } + @Override + public void autoPassCancel() { + // Do nothing + } } diff --git a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java index 3d0546e7807..dbc172ad3b3 100644 --- a/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java +++ b/forge-ai/src/main/java/forge/ai/simulation/GameCopier.java @@ -55,7 +55,7 @@ public class GameCopier { newPlayers.add(clonePlayer(p)); } GameRules currentRules = origGame.getRules(); - Match newMatch = new Match(currentRules, newPlayers); + Match newMatch = new Match(currentRules, newPlayers, origGame.getView().getTitle()); Game newGame = new Game(newPlayers, currentRules, newMatch); for (int i = 0; i < origGame.getPlayers().size(); i++) { Player origPlayer = origGame.getPlayers().get(i); diff --git a/forge-core/src/main/java/forge/card/mana/ManaCostShard.java b/forge-core/src/main/java/forge/card/mana/ManaCostShard.java index 29e07903823..a2872dc10d5 100644 --- a/forge-core/src/main/java/forge/card/mana/ManaCostShard.java +++ b/forge-core/src/main/java/forge/card/mana/ManaCostShard.java @@ -22,7 +22,7 @@ import forge.util.BinaryUtil; /** * The Class CardManaCostShard. */ -public enum ManaCostShard implements Comparable { +public enum ManaCostShard { // declaration order matters! Place the shards that offer least ways to be paid for first /* Pure colors */ diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 8e681b49cf7..d2e523cb8a9 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -44,7 +44,7 @@ import forge.game.card.CardLists; import forge.game.card.CardPredicates; import forge.game.card.CardView; import forge.game.combat.Combat; -import forge.game.event.GameEvent; +import forge.game.event.Event; import forge.game.event.GameEventGameOutcome; import forge.game.phase.Phase; import forge.game.phase.PhaseHandler; @@ -101,7 +101,6 @@ public class Game { private final Match match; private GameStage age = GameStage.BeforeMulligan; private GameOutcome outcome; - private boolean disableAutoYields; private final GameView view; private final Tracker tracker = new Tracker(); @@ -537,14 +536,10 @@ public class Game { * Fire only the events after they became real for gamestate and won't get replaced.
* The events are sent to UI, log and sound system. Network listeners are under development. */ - public void fireEvent(GameEvent event) { -// if (LOG_EVENTS) { -// System.out.println("GE: " + event.toString() + " \t\t " + FThreads.debugGetStackTraceItem(4, true)); -// } - + public void fireEvent(final Event event) { events.post(event); } - public void subscribeToEvents(Object subscriber) { + public void subscribeToEvents(final Object subscriber) { events.register(subscriber); } @@ -605,13 +600,6 @@ public class Game { return ++hiddenCardIdCounter; } - public boolean getDisableAutoYields() { - return disableAutoYields; - } - public void setDisableAutoYields(boolean b0) { - disableAutoYields = b0; - } - public Multimap chooseCardsForAnte(final boolean matchRarity) { Multimap anteed = ArrayListMultimap.create(); diff --git a/forge-game/src/main/java/forge/game/GameLogEntryType.java b/forge-game/src/main/java/forge/game/GameLogEntryType.java index 9b3f45cd54b..f2e671823d1 100644 --- a/forge-game/src/main/java/forge/game/GameLogEntryType.java +++ b/forge-game/src/main/java/forge/game/GameLogEntryType.java @@ -25,4 +25,5 @@ public enum GameLogEntryType { public String getCaption() { return caption; } + } \ No newline at end of file diff --git a/forge-game/src/main/java/forge/game/GameType.java b/forge-game/src/main/java/forge/game/GameType.java index c0ed7509bee..fa57097b8a8 100644 --- a/forge-game/src/main/java/forge/game/GameType.java +++ b/forge-game/src/main/java/forge/game/GameType.java @@ -8,7 +8,6 @@ import forge.deck.DeckFormat; import forge.deck.DeckSection; import forge.game.player.RegisteredPlayer; - public enum GameType { Sealed (DeckFormat.Limited, true, true, true, "Sealed", ""), Draft (DeckFormat.Limited, true, true, true, "Draft", ""), @@ -21,9 +20,9 @@ public enum GameType { Vanguard (DeckFormat.Vanguard, true, true, true, "Vanguard", "Each player has a special \"Avatar\" card that affects the game."), Commander (DeckFormat.Commander, false, false, false, "Commander", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors."), TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "Tiny Leaders", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Each card must have CMC less than 4."), - Planechase (DeckFormat.Planechase, false, false, true, "Planechase", "Plane cards apply global effects. Plane card changed when a player rolls \"Chaos\" on the planar die."), - Archenemy (DeckFormat.Archenemy, false, false, true, "Archenemy", "One player is the Archenemy and can play scheme cards."), - ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "Archenemy Rumble", "All players are Archenemies and can play scheme cards."), + Planechase (DeckFormat.Planechase, false, false, true, "Planechase", "Plane cards apply global effects. The Plane card changes when a player rolls \"Planeswalk\" on the planar die."), + Archenemy (DeckFormat.Archenemy, false, false, true, "Archenemy", "One player is the Archenemy and fights the other players by playing Scheme cards."), + ArchenemyRumble (DeckFormat.Archenemy, false, false, true, "Archenemy Rumble", "All players are Archenemies and can play Scheme cards."), MomirBasic (DeckFormat.Constructed, false, false, false, "Momir Basic", "Each player has a deck containing 60 basic lands and the Momir Vig avatar.", new Function() { @Override public Deck apply(RegisteredPlayer player) { diff --git a/forge-game/src/main/java/forge/game/GameView.java b/forge-game/src/main/java/forge/game/GameView.java index 5a790e84092..dc76102a796 100644 --- a/forge-game/src/main/java/forge/game/GameView.java +++ b/forge-game/src/main/java/forge/game/GameView.java @@ -22,11 +22,6 @@ import forge.trackable.TrackableProperty; import forge.util.FCollectionView; public class GameView extends TrackableObject { - private static GameView currentGame; - - public static GameView getCurrentGame() { - return currentGame; - } /*private final TrackableIndex cards = new TrackableIndex(); private final TrackableIndex players = new TrackableIndex(); @@ -38,8 +33,8 @@ public class GameView extends TrackableObject { public GameView(final Game game0) { super(-1, game0.getTracker()); //ID not needed - currentGame = this; game = game0; + set(TrackableProperty.Title, game.getMatch().getTitle()); set(TrackableProperty.WinningTeam, -1); GameRules rules = game.getRules(); @@ -58,6 +53,9 @@ public class GameView extends TrackableObject { return players; } + public String getTitle() { + return get(TrackableProperty.Title); + } public boolean isCommander() { return get(TrackableProperty.Commander); } @@ -117,9 +115,6 @@ public class GameView extends TrackableObject { set(TrackableProperty.GameOver, game.isGameOver()); set(TrackableProperty.MatchOver, game.getMatch().isMatchOver()); set(TrackableProperty.WinningTeam, game.getOutcome() == null ? -1 : game.getOutcome().getWinningTeam()); - if (game.isGameOver()) { - currentGame = null; - } } public GameLog getGameLog() { @@ -199,9 +194,9 @@ public class GameView extends TrackableObject { return game.getMatch().getGamesWonBy(questPlayer); } - public Deck getDeck(LobbyPlayer guiPlayer) { - for (Player p : game.getRegisteredPlayers()) { - if (p.getLobbyPlayer().equals(guiPlayer)) { + public Deck getDeck(final String lobbyPlayerName) { + for (final Player p : game.getRegisteredPlayers()) { + if (p.getLobbyPlayer().getName().equals(lobbyPlayerName)) { return p.getRegisteredPlayer().getDeck(); } } diff --git a/forge-game/src/main/java/forge/game/Match.java b/forge-game/src/main/java/forge/game/Match.java index ed6633dcef0..d230cd24471 100644 --- a/forge-game/src/main/java/forge/game/Match.java +++ b/forge-game/src/main/java/forge/game/Match.java @@ -1,6 +1,21 @@ package forge.game; -import com.google.common.collect.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Random; +import java.util.Set; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multiset; import forge.LobbyPlayer; import forge.deck.CardPool; @@ -19,25 +34,35 @@ import forge.item.PaperCard; import forge.util.FCollectionView; import forge.util.MyRandom; -import java.util.*; -import java.util.Map.Entry; - public class Match { private final List players; private final GameRules rules; + private final String title; private final List gamesPlayed = new ArrayList(); private final List gamesPlayedRo; - public Match(GameRules rules0, List players0) { + public Match(final GameRules rules0, final List players0, final String title) { gamesPlayedRo = Collections.unmodifiableList(gamesPlayed); players = Collections.unmodifiableList(Lists.newArrayList(players0)); rules = rules0; + this.title = title; } public GameRules getRules() { return rules; } + String getTitle() { + final Multiset wins = getGamesWon(); + final StringBuilder titleAppend = new StringBuilder(title); + titleAppend.append(" ("); + for (final RegisteredPlayer rp : players) { + titleAppend.append(wins.count(rp)).append('-'); + } + titleAppend.deleteCharAt(titleAppend.length() - 1); + titleAppend.append(')'); + return titleAppend.toString(); + } public final List getPlayedGames() { return gamesPlayedRo; @@ -124,6 +149,13 @@ public class Match { } return sum; } + public Multiset getGamesWon() { + final Multiset won = HashMultiset.create(players.size()); + for (final GameOutcome go : gamesPlayedRo) { + won.add(go.getWinningPlayer().getRegisteredPlayer()); + } + return won; + } public boolean isWonBy(LobbyPlayer questPlayer) { return getGamesWonBy(questPlayer) >= rules.getGamesToWinMatch(); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index beaa537eae1..c0f221d1d58 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -103,7 +103,7 @@ public final class AbilityFactory { AbilityRecordType type = AbilityRecordType.getRecordType(mapParams); if (null == type) { String source = hostCard.getName().isEmpty() ? abString : hostCard.getName(); - throw new RuntimeException("AbilityFactory : getAbility -- no API in " + source); + throw new RuntimeException("AbilityFactory : getAbility -- no API in " + source + ": " + abString); } return getAbility(mapParams, type, hostCard); } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 193ddfd359f..9ae851bb307 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -17,6 +17,18 @@ */ package forge.game.card; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.commons.lang3.StringUtils; + import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; @@ -32,18 +44,15 @@ import forge.card.mana.ManaCostShard; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameLogEntryType; -import forge.game.GameView; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; -import forge.game.card.CardCollectionView; import forge.game.card.CardPredicates.Presets; import forge.game.cost.Cost; import forge.game.cost.CostPayment; import forge.game.event.GameEventCardStatsChanged; import forge.game.phase.PhaseHandler; import forge.game.player.Player; -import forge.game.player.PlayerView; import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementLayer; @@ -65,11 +74,6 @@ import forge.util.Aggregates; import forge.util.FCollectionView; import forge.util.Lang; -import org.apache.commons.lang3.StringUtils; - -import java.util.*; -import java.util.Map.Entry; - /** *

* CardFactoryUtil class. @@ -2081,28 +2085,6 @@ public class CardFactoryUtil { } */ - public static final String getCommanderInfo(final PlayerView originPlayer) { - GameView game = GameView.getCurrentGame(); - if (game == null) { return ""; } - - StringBuilder sb = new StringBuilder(); - for (PlayerView p : game.getPlayers()) { - final String text; - if (p.equals(originPlayer)) { - text = "Commander Damage from own Commander: "; - } - else { - text = "Commander Damage to " + p.getName() + ": "; - } - - int damage = p.getCommanderDamage(originPlayer.getCommander()); - if (damage > 0) { - sb.append(text + damage + "\r\n"); - } - } - return sb.toString(); - } - /** *

* postFactoryKeywords. @@ -3366,7 +3348,7 @@ public class CardFactoryUtil { final String parse = card.getKeywords().get(n); final String[] k = parse.split(":"); final int num = Integer.parseInt(k[1]); - UUID triggerSvar = UUID.randomUUID(); + final String triggerSvar = "DBRipple"; final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | " + "Execute$ " + triggerSvar + " | Secondary$ True | TriggerDescription$" + 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 fe23b1e5a44..72663e84736 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -531,13 +531,13 @@ public class CardView extends GameEntityView { } } - String rulesText = state.getRulesText(); + final String rulesText = state.getRulesText(); if (!rulesText.isEmpty()) { sb.append(rulesText).append("\r\n\r\n"); } if (isCommander()) { sb.append(getOwner()).append("'s Commander\r\n"); - sb.append(CardFactoryUtil.getCommanderInfo(getOwner())).append("\r\n"); + sb.append(getOwner().getCommanderInfo()).append("\r\n"); } if (isSplitCard()) { diff --git a/forge-game/src/main/java/forge/game/event/Event.java b/forge-game/src/main/java/forge/game/event/Event.java new file mode 100644 index 00000000000..401c49b0803 --- /dev/null +++ b/forge-game/src/main/java/forge/game/event/Event.java @@ -0,0 +1,5 @@ +package forge.game.event; + +public abstract class Event { + +} diff --git a/forge-game/src/main/java/forge/game/event/GameEvent.java b/forge-game/src/main/java/forge/game/event/GameEvent.java index f633a6c88af..8e4714cc5c7 100644 --- a/forge-game/src/main/java/forge/game/event/GameEvent.java +++ b/forge-game/src/main/java/forge/game/event/GameEvent.java @@ -1,6 +1,6 @@ package forge.game.event; -public abstract class GameEvent { +public abstract class GameEvent extends Event { public abstract T visit(IGameEventVisitor visitor); } diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index 10c14fc2709..8445b32062d 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -1,9 +1,16 @@ package forge.game.player; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + import com.google.common.base.Predicate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; import forge.LobbyPlayer; import forge.card.ColorSet; @@ -25,7 +32,6 @@ import forge.game.cost.Cost; import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.mana.Mana; -import forge.game.phase.PhaseType; import forge.game.replacement.ReplacementEffect; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; @@ -38,15 +44,6 @@ import forge.item.PaperCard; import forge.util.FCollectionView; import forge.util.ITriggerEvent; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * A prototype for player controller class * @@ -75,7 +72,6 @@ public abstract class PlayerController { protected final Game game; - private PhaseType autoPassUntilPhase = null; protected final Player player; protected final LobbyPlayer lobbyPlayer; @@ -85,71 +81,10 @@ public abstract class PlayerController { lobbyPlayer = lp; } - /** - * Automatically pass priority until reaching the Cleanup phase of the - * current turn. - */ - public void autoPassUntilEndOfTurn() { - autoPassUntilPhase = PhaseType.CLEANUP; - } - - protected PhaseType getAutoPassUntilPhase() { - return autoPassUntilPhase; - } - - public void autoPassCancel() { - autoPassUntilPhase = null; - } - - public boolean mayAutoPass() { - if (autoPassUntilPhase == null) { return false; } - - PhaseType currentPhase = game.getPhaseHandler().getPhase(); - if (currentPhase.isBefore(autoPassUntilPhase)) { - if (currentPhase == PhaseType.COMBAT_DECLARE_BLOCKERS && game.getPhaseHandler().isPlayerTurn(player)) { - if (!game.getCombat().getAllBlockers().isEmpty()) { - return false; //prevent auto-passing on Declare Blockers phase if it's your turn and your opponent blocks a creature you attacked with - } - } - return true; - } - return false; - } - public boolean isAI() { return false; } - // Abilities to auto-yield to - private final Set autoYields = Sets.newHashSet(); - public Iterable getAutoYields() { - return autoYields; - } - public boolean shouldAutoYield(final String key) { - return autoYields.contains(key); - } - public void setShouldAutoYield(final String key, final boolean autoYield) { - if (autoYield) { - autoYields.add(key); - } - else { - autoYields.remove(key); - } - } - - // Triggers preliminary choice: ask, decline or play - private Map triggersAlwaysAccept = new HashMap(); - - public boolean shouldAlwaysAcceptTrigger(Integer trigger) { return Boolean.TRUE.equals(triggersAlwaysAccept.get(trigger)); } - public boolean shouldAlwaysDeclineTrigger(Integer trigger) { return Boolean.FALSE.equals(triggersAlwaysAccept.get(trigger)); } - public boolean shouldAlwaysAskTrigger(Integer trigger) { return !triggersAlwaysAccept.containsKey(trigger); } - - public void setShouldAlwaysAcceptTrigger(Integer trigger) { triggersAlwaysAccept.put(trigger, true); } - public void setShouldAlwaysDeclineTrigger(Integer trigger) { triggersAlwaysAccept.put(trigger, false); } - public void setShouldAlwaysAskTrigger(Integer trigger) { triggersAlwaysAccept.remove(trigger); } - - // End of Triggers preliminary choice - public Game getGame() { return game; } public Player getPlayer() { return player; } public LobbyPlayer getLobbyPlayer() { return lobbyPlayer; } @@ -290,6 +225,8 @@ public abstract class PlayerController { // better to have this odd method than those if playerType comparison in ChangeZone public abstract Card chooseSingleCardForZoneChange(ZoneType destination, List origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional, Player decider); + public abstract void autoPassCancel(); + public boolean isGuiPlayer() { return false; } diff --git a/forge-game/src/main/java/forge/game/player/PlayerView.java b/forge-game/src/main/java/forge/game/player/PlayerView.java index dca8695d49b..f6509344237 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerView.java +++ b/forge-game/src/main/java/forge/game/player/PlayerView.java @@ -1,9 +1,11 @@ package forge.game.player; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import forge.LobbyPlayer; @@ -85,6 +87,25 @@ public class PlayerView extends GameEntityView { return opponents != null && opponents.contains(other); } + public final String getCommanderInfo() { + final StringBuilder sb = new StringBuilder(); + + for (final PlayerView p : Iterables.concat(Collections.singleton(this), getOpponents())) { + final String text; + if (p.equals(this)) { + text = "Commander Damage from own Commander: "; + } else { + text = "Commander Damage to " + p.getName() + ": "; + } + + final int damage = p.getCommanderDamage(this.getCommander()); + if (damage > 0) { + sb.append(text + damage + "\r\n"); + } + } + return sb.toString(); + } + @Override public String toString() { return getName(); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java index bdbb20d8f55..bff87bc342d 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java @@ -145,17 +145,22 @@ public class TriggerHandler { } public static Trigger parseTrigger(final Map mapParams, final Card host, final boolean intrinsic) { - Trigger ret = null; - final TriggerType type = TriggerType.smartValueOf(mapParams.get("Mode")); - ret = type.createTrigger(mapParams, host, intrinsic); + final Trigger ret = type.createTrigger(mapParams, host, intrinsic); - String triggerZones = mapParams.get("TriggerZones"); + final String triggerZones = mapParams.get("TriggerZones"); if (null != triggerZones) { ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(triggerZones))); + } else if (type == TriggerType.ChangesZone) { + // Special case, because ChangesZone triggers on cards don't + // specify their TriggerZone + final String origin = mapParams.get("Destination"); + if (!"Any".equals(origin)) { + ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(origin))); + } } - String triggerPhases = mapParams.get("Phase"); + final String triggerPhases = mapParams.get("Phase"); if (null != triggerPhases) { ret.setTriggerPhases(PhaseType.parseRange(triggerPhases)); } diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 8bd431a367d..e63515e2a5e 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -225,7 +225,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { + final List sourceChoices, final List destChoices) { /*if ((sourceChoices != null && !sourceChoices.isEmpty() && sourceChoices.iterator().next() instanceof GameObject) || (destChoices != null && !destChoices.isEmpty() && destChoices.iterator().next() instanceof GameObject)) { System.err.println("Warning: GameObject passed to GUI! Printing stack trace."); Thread.dumpStack(); }*/ - return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode); - } - - @Override - public List sideboard(CardPool sideboard, CardPool main) { - return GuiChoose.sideboard(sideboard.toFlatList(), main.toFlatList()); - } - - @Override - public GameEntityView chooseSingleEntityForEffect(String title, FCollectionView optionList, DelayedReveal delayedReveal, boolean isOptional, PlayerControllerHuman controller) { - if (delayedReveal != null) { - delayedReveal.reveal(controller); //TODO: Merge this into search dialog - } - controller.tempShow(optionList); - List gameEntityViews = GameEntityView.getEntityCollection(optionList); - if (isOptional) { - return SGuiChoose.oneOrNone(title, gameEntityViews); - } - return SGuiChoose.one(title, gameEntityViews); + return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices); } @Override @@ -232,12 +196,6 @@ public class GuiDesktop implements IGuiBase { return 0; } - @Override - public void setCard(final CardView card) { - CMatchUI.SINGLETON_INSTANCE.setCard(card); - } - - @Override public String showFileDialog(String title, String defaultDir) { final JFileChooser fc = new JFileChooser(defaultDir); @@ -273,7 +231,7 @@ public class GuiDesktop implements IGuiBase { } @Override - public void browseToUrl(String url) throws Exception { + public void browseToUrl(String url) throws IOException, URISyntaxException { Desktop.getDesktop().browse(new URI(url)); } @@ -310,8 +268,12 @@ public class GuiDesktop implements IGuiBase { Singletons.getView().getFrame().validate(); } + public IGuiGame getNewGuiGame() { + return new CMatchUI(); + }; + @Override - public void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi) { - CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player.getName(), ihi.getIconImageKey()); + public HostedMatch hostMatch() { + return new HostedMatch(); } -} +} \ No newline at end of file diff --git a/forge-gui-desktop/src/main/java/forge/ImageCache.java b/forge-gui-desktop/src/main/java/forge/ImageCache.java index 0502f2d846a..6c5e627c886 100644 --- a/forge-gui-desktop/src/main/java/forge/ImageCache.java +++ b/forge-gui-desktop/src/main/java/forge/ImageCache.java @@ -34,8 +34,8 @@ import com.mortennobel.imagescaling.ResampleOp; import forge.assets.FSkinProp; import forge.game.card.CardView; +import forge.game.player.PlayerView; import forge.item.InventoryItem; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences.FPref; @@ -83,8 +83,8 @@ public class ImageCache { * retrieve an image from the cache. returns null if the image is not found in the cache * and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension. */ - public static BufferedImage getImage(final CardView card, final int width, final int height) { - final String key = MatchUtil.getCardImageKey(card.getCurrentState()); + public static BufferedImage getImage(final CardView card, final PlayerView viewer, final int width, final int height) { + final String key = card.getCurrentState().getImageKey(viewer); return scaleImage(key, width, height, true); } @@ -95,7 +95,7 @@ public class ImageCache { public static BufferedImage getImage(InventoryItem ii, int width, int height) { return scaleImage(ImageKeys.getImageKey(ii, false), width, height, true); } - + /** * retrieve an icon from the cache. returns the current skin's ICO_UNKNOWN if the icon image is not found * in the cache and cannot be loaded from disk. diff --git a/forge-gui-desktop/src/main/java/forge/control/FControl.java b/forge-gui-desktop/src/main/java/forge/control/FControl.java index 69ed1cb366d..3e0713fa949 100644 --- a/forge-gui-desktop/src/main/java/forge/control/FControl.java +++ b/forge-gui-desktop/src/main/java/forge/control/FControl.java @@ -18,6 +18,7 @@ package forge.control; import java.awt.Component; +import java.awt.Dimension; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; import java.awt.event.ComponentAdapter; @@ -33,11 +34,12 @@ import javax.swing.JLayeredPane; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; +import com.google.common.collect.Lists; + import forge.ImageCache; import forge.LobbyPlayer; import forge.Singletons; import forge.assets.FSkinProp; -import forge.control.KeyboardShortcuts.Shortcut; import forge.gui.GuiDialog; import forge.gui.SOverlayUtils; import forge.gui.framework.FScreen; @@ -45,7 +47,7 @@ import forge.gui.framework.InvalidLayoutFileException; import forge.gui.framework.SLayoutIO; import forge.gui.framework.SOverflowUtil; import forge.gui.framework.SResizingUtil; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.menus.ForgeMenu; import forge.model.FModel; import forge.player.GamePlayerUtil; @@ -55,7 +57,6 @@ import forge.properties.ForgePreferences.FPref; import forge.quest.data.QuestPreferences.QPref; import forge.quest.io.QuestDataIO; import forge.screens.deckeditor.CDeckEditorUI; -import forge.screens.match.CMatchUI; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; import forge.view.FFrame; @@ -73,16 +74,16 @@ public enum FControl implements KeyEventDispatcher { instance; private ForgeMenu forgeMenu; - private List shortcuts; private JLayeredPane display; private FScreen currentScreen; private boolean altKeyLastDown; private CloseAction closeAction; + private List currentMatches = Lists.newArrayList(); public static enum CloseAction { NONE, CLOSE_SCREEN, - EXIT_FORGE + EXIT_FORGE; } /** @@ -151,10 +152,10 @@ public enum FControl implements KeyEventDispatcher { public boolean canExitForge(boolean forRestart) { String action = (forRestart ? "Restart" : "Exit"); String userPrompt = "Are you sure you wish to " + (forRestart ? "restart" : "exit") + " Forge?"; - if (MatchUtil.getGame() != null) { + if (!currentMatches.isEmpty()) { userPrompt = "A game is currently active. " + userPrompt; } - if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", MatchUtil.getGame() == null)) { //default Yes if no game active + if (!FOptionPane.showConfirmDialog(userPrompt, action + " Forge", action, "Cancel", currentMatches.isEmpty())) { //default Yes if no game active return false; } if (!CDeckEditorUI.SINGLETON_INSTANCE.canSwitchAway(true)) { @@ -174,12 +175,9 @@ public enum FControl implements KeyEventDispatcher { /** After view and model have been initialized, control can start.*/ public void initialize() { - MatchUtil.setController(CMatchUI.SINGLETON_INSTANCE); - // Preloads skin components (using progress bar). FSkin.loadFull(true); - shortcuts = KeyboardShortcuts.attachKeyboardShortcuts(); display = FView.SINGLETON_INSTANCE.getLpnDocument(); final ForgePreferences prefs = FModel.getPreferences(); @@ -227,7 +225,7 @@ public enum FControl implements KeyEventDispatcher { } private void setGlobalKeyboardHandler() { - KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + final KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); manager.addKeyEventDispatcher(this); } @@ -245,10 +243,10 @@ public enum FControl implements KeyEventDispatcher { /** * Switches between display screens in top level JFrame. */ - public boolean setCurrentScreen(FScreen screen) { + public boolean setCurrentScreen(final FScreen screen) { return setCurrentScreen(screen, false); } - public boolean setCurrentScreen(FScreen screen, boolean previousScreenClosed) { + public boolean setCurrentScreen(final FScreen screen, final boolean previousScreenClosed) { //TODO: Uncomment the line below if this function stops being used to refresh //the current screen in some places (such as Continue and Restart in the match screen) //if (currentScreen == screen) { return; } @@ -258,8 +256,8 @@ public enum FControl implements KeyEventDispatcher { return false; } - if (currentScreen == FScreen.MATCH_SCREEN) { //hide targeting overlay and reset image if was on match screen - SOverlayUtils.hideTargetingOverlay(); + if (currentScreen != null && currentScreen.isMatchScreen()) { //hide targeting overlay and reset image if was on match screen + //SOverlayUtils.hideTargetingOverlay(); if (isMatchBackgroundImageVisible()) { FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(new ImageIcon()); } @@ -272,6 +270,7 @@ public enum FControl implements KeyEventDispatcher { currentScreen = screen; //load layout for new current screen + screen.getController().register(); try { SLayoutIO.loadLayout(null); } catch (InvalidLayoutFileException ex) { @@ -281,14 +280,14 @@ public enum FControl implements KeyEventDispatcher { } } - screen.getView().populate(); screen.getController().initialize(); + screen.getView().populate(); - if (screen == FScreen.MATCH_SCREEN) { + if (screen.isMatchScreen()) { if (isMatchBackgroundImageVisible()) { FView.SINGLETON_INSTANCE.getPnlInsets().setForegroundImage(FSkin.getIcon(FSkinProp.BG_MATCH)); } - SOverlayUtils.showTargetingOverlay(); + //SOverlayUtils.showTargetingOverlay(); } Singletons.getView().getNavigationBar().updateSelectedTab(); @@ -305,11 +304,6 @@ public enum FControl implements KeyEventDispatcher { return setCurrentScreen(screen); } - /** @return List A list of attached keyboard shortcut descriptions and properties. */ - public List getShortcuts() { - return shortcuts; - } - /** Remove all children from a specified layer. */ private void clearChildren(final int layer0) { final Component[] children = FView.SINGLETON_INSTANCE.getLpnDocument().getComponentsInLayer(layer0); @@ -331,6 +325,10 @@ public enum FControl implements KeyEventDispatcher { if (children.length != 0) { children[0].setSize(display.getSize()); } } + public Dimension getDisplaySize() { + return display.getSize(); + } + /* (non-Javadoc) * @see java.awt.KeyEventDispatcher#dispatchKeyEvent(java.awt.event.KeyEvent) */ diff --git a/forge-gui-desktop/src/main/java/forge/control/KeyboardShortcuts.java b/forge-gui-desktop/src/main/java/forge/control/KeyboardShortcuts.java index 840ac3c3346..13ec4af6ecb 100644 --- a/forge-gui-desktop/src/main/java/forge/control/KeyboardShortcuts.java +++ b/forge-gui-desktop/src/main/java/forge/control/KeyboardShortcuts.java @@ -1,20 +1,5 @@ package forge.control; -import forge.Singletons; -import forge.gui.framework.EDocID; -import forge.gui.framework.FScreen; -import forge.gui.framework.SDisplayUtil; -import forge.match.MatchUtil; -import forge.model.FModel; -import forge.properties.ForgePreferences; -import forge.properties.ForgePreferences.FPref; -import forge.screens.home.settings.VSubmenuPreferences.KeyboardShortcutField; -import forge.screens.match.controllers.CDock; - -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; - import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; @@ -22,6 +7,24 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.KeyStroke; + +import org.apache.commons.lang3.StringUtils; + +import forge.Singletons; +import forge.gui.framework.EDocID; +import forge.gui.framework.SDisplayUtil; +import forge.model.FModel; +import forge.properties.ForgePreferences; +import forge.properties.ForgePreferences.FPref; +import forge.screens.home.settings.VSubmenuPreferences.KeyboardShortcutField; +import forge.screens.match.CMatchUI; + /** * Consolidates keyboard shortcut assembly into one location * for all shortcuts in the project. @@ -30,6 +33,11 @@ import java.util.List; * and you're done. */ public class KeyboardShortcuts { + + public static List getKeyboardShortcuts() { + return attachKeyboardShortcuts(null); + } + /** * Attaches all keyboard shortcuts for match UI, * and returns a list of shortcuts with necessary properties for later access. @@ -37,19 +45,19 @@ public class KeyboardShortcuts { * @return List Shortcut objects */ @SuppressWarnings("serial") - public static List attachKeyboardShortcuts() { + public static List attachKeyboardShortcuts(final CMatchUI matchUI) { final JComponent c = Singletons.getView().getFrame().getLayeredPane(); final InputMap im = c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); final ActionMap am = c.getActionMap(); - List list = new ArrayList(); + final List list = new ArrayList(); //========== Match Shortcuts /** Show stack. */ final Action actShowStack = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); } }; @@ -58,7 +66,7 @@ public class KeyboardShortcuts { final Action actShowCombat = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc()); } }; @@ -67,7 +75,7 @@ public class KeyboardShortcuts { final Action actShowConsole = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); } }; @@ -76,7 +84,7 @@ public class KeyboardShortcuts { final Action actShowPlayers = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } SDisplayUtil.showTab(EDocID.REPORT_PLAYERS.getDoc()); } }; @@ -85,7 +93,7 @@ public class KeyboardShortcuts { final Action actShowDev = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } if (ForgePreferences.DEV_MODE) { SDisplayUtil.showTab(EDocID.DEV_MODE.getDoc()); } @@ -96,8 +104,9 @@ public class KeyboardShortcuts { final Action actConcede = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } - MatchUtil.concede(); + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } + if (matchUI == null) { return; } + matchUI.getGameController().concede(); } }; @@ -105,8 +114,9 @@ public class KeyboardShortcuts { final Action actEndTurn = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } - CDock.SINGLETON_INSTANCE.endTurn(); + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } + if (matchUI == null) { return; } + matchUI.getGameController().passPriorityUntilEndOfTurn(); } }; @@ -114,8 +124,9 @@ public class KeyboardShortcuts { final Action actAllAttack = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } - MatchUtil.alphaStrike(); + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } + if (matchUI == null) { return; } + matchUI.getGameController().alphaStrike(); } }; @@ -123,8 +134,9 @@ public class KeyboardShortcuts { final Action actTgtOverlay = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } - CDock.SINGLETON_INSTANCE.toggleTargeting(); + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { return; } + if (matchUI == null) { return; } + matchUI.getCDock().toggleTargeting(); } }; diff --git a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java index d355d3e43d3..832e25b2593 100644 --- a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java +++ b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java @@ -21,6 +21,7 @@ import forge.quest.QuestController; import forge.quest.QuestEvent; import forge.quest.QuestEventChallenge; import forge.quest.QuestUtil; +import forge.screens.match.controllers.CDetailPicture; import forge.toolbox.FLabel; import forge.toolbox.FOptionPane; import net.miginfocom.swing.MigLayout; @@ -42,7 +43,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { private NetDeckCategory netDeckCategory; private boolean refreshingDeckType; - private final DeckManager lstDecks = new DeckManager(GameType.Constructed); + private final DeckManager lstDecks; private final FLabel btnViewDeck = new FLabel.ButtonBuilder().text("View Deck").fontSize(14).build(); private final FLabel btnRandom = new FLabel.ButtonBuilder().fontSize(14).build(); @@ -52,9 +53,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { private FPref stateSetting = null; //Show dialog to select a deck - public static Deck promptForDeck(String title, DeckType defaultDeckType, boolean forAi) { + public static Deck promptForDeck(final CDetailPicture cDetailPicture, final String title, final DeckType defaultDeckType, final boolean forAi) { FThreads.assertExecutedByEdt(true); - final FDeckChooser chooser = new FDeckChooser(forAi); + final FDeckChooser chooser = new FDeckChooser(cDetailPicture, forAi); chooser.initialize(defaultDeckType); chooser.populate(); Dimension parentSize = JOptionPane.getRootFrame().getSize(); @@ -76,7 +77,8 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { return null; } - public FDeckChooser(boolean forAi) { + public FDeckChooser(final CDetailPicture cDetailPicture, final boolean forAi) { + lstDecks = new DeckManager(GameType.Constructed, cDetailPicture); setOpaque(false); isAi = forAi; UiCommand cmdViewDeck = new UiCommand() { diff --git a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java index 60c6e3b8eb9..aee20e3f376 100644 --- a/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java +++ b/forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java @@ -47,15 +47,15 @@ public class FDeckViewer extends FDialog { public static void show(final Deck deck) { if (deck == null) { return; } - FDeckViewer deckViewer = new FDeckViewer(deck); + final FDeckViewer deckViewer = new FDeckViewer(deck); deckViewer.setVisible(true); deckViewer.dispose(); } - private FDeckViewer(Deck deck0) { + private FDeckViewer(final Deck deck0) { this.deck = deck0; this.setTitle(deck.getName()); - this.cardManager = new CardManager(false) { + this.cardManager = new CardManager(null, false) { @Override //show hovered card in Image View in dialog instead of main Detail/Picture panes protected ImageView createImageView(final ItemManagerModel model0) { return new ImageView(this, model0) { diff --git a/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java b/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java index 1ba8cc91805..2a8574ba092 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java +++ b/forge-gui-desktop/src/main/java/forge/gui/CardDetailPanel.java @@ -31,16 +31,15 @@ import javax.swing.border.EmptyBorder; import org.apache.commons.lang3.StringUtils; import forge.card.CardDetailUtil; -import forge.card.CardRarity; import forge.card.CardDetailUtil.DetailColors; import forge.card.CardEdition; +import forge.card.CardRarity; import forge.game.card.Card; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.item.InventoryItemFromSet; -import forge.match.MatchUtil; import forge.model.FModel; import forge.toolbox.FHtmlViewer; import forge.toolbox.FLabel; @@ -189,7 +188,7 @@ public class CardDetailPanel extends SkinnedPanel { return; } - boolean canShow = MatchUtil.canCardBeShown(card); + boolean canShow = true; if (state.getManaCost().isNoCost() || !canShow) { nameCostLabel.setText(CardDetailUtil.formatCardName(card, canShow, isInAltState)); diff --git a/forge-gui-desktop/src/main/java/forge/gui/CardPicturePanel.java b/forge-gui-desktop/src/main/java/forge/gui/CardPicturePanel.java index 6c650f1012e..c50e6f71fa8 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/CardPicturePanel.java +++ b/forge-gui-desktop/src/main/java/forge/gui/CardPicturePanel.java @@ -73,7 +73,7 @@ public final class CardPicturePanel extends JPanel { } } - public BufferedImage getImage() { + private BufferedImage getImage() { if (displayed instanceof InventoryItem) { final InventoryItem item = (InventoryItem) displayed; return ImageCache.getOriginalImage(ImageKeys.getImageKey(item, false), true); diff --git a/forge-gui-desktop/src/main/java/forge/gui/DualListBox.java b/forge-gui-desktop/src/main/java/forge/gui/DualListBox.java index c0bf1099608..477e313f120 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/DualListBox.java +++ b/forge-gui-desktop/src/main/java/forge/gui/DualListBox.java @@ -69,11 +69,11 @@ public class DualListBox extends FDialog { private boolean sideboardingMode = false; private boolean showCard = true; - public DualListBox(int remainingSources, List sourceElements, List destElements) { - this(remainingSources, remainingSources, sourceElements, destElements); - } - - public DualListBox(int remainingSourcesMin, int remainingSourcesMax, List sourceElements, List destElements) { + private final CMatchUI matchUI; + + public DualListBox(final int remainingSourcesMin, final int remainingSourcesMax, final List sourceElements, final List destElements, final CMatchUI matchUI) { + this.matchUI = matchUI; + targetRemainingSourcesMin = remainingSourcesMin; targetRemainingSourcesMax = remainingSourcesMax; sourceListModel = new UnsortedListModel(); @@ -152,15 +152,15 @@ public class DualListBox extends FDialog { autoButton = new FButton("Auto"); autoButton.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) { _addAll(); _finish(); } }); - FPanel leftPanel = new FPanel(new BorderLayout()); + final FPanel leftPanel = new FPanel(new BorderLayout()); selectOrder = new FLabel.Builder().text("Select Order:").build(); leftPanel.add(selectOrder, BorderLayout.NORTH); leftPanel.add(new FScrollPane(sourceList, true), BorderLayout.CENTER); leftPanel.add(okButton, BorderLayout.SOUTH); - FPanel centerPanel = new FPanel(new GridLayout(6, 1)); + final FPanel centerPanel = new FPanel(new GridLayout(6, 1)); centerPanel.setBorderToggle(false); - JPanel emptyPanel = new JPanel(); + final JPanel emptyPanel = new JPanel(); emptyPanel.setOpaque(false); centerPanel.add(emptyPanel); // empty panel to take up the first slot centerPanel.add(addButton); @@ -170,7 +170,7 @@ public class DualListBox extends FDialog { orderedLabel = new FLabel.Builder().build(); - FPanel rightPanel = new FPanel(new BorderLayout()); + final FPanel rightPanel = new FPanel(new BorderLayout()); rightPanel.add(orderedLabel, BorderLayout.NORTH); rightPanel.add(new FScrollPane(destList, true), BorderLayout.CENTER); rightPanel.add(autoButton, BorderLayout.SOUTH); @@ -337,10 +337,12 @@ public class DualListBox extends FDialog { card = Card.getCardForUi((IPaperCard) obj).getView(); } - GuiUtils.clearPanelSelections(); - if (card != null) { - CMatchUI.SINGLETON_INSTANCE.setCard(card); - GuiUtils.setPanelSelection(card); + if (matchUI != null) { + matchUI.clearPanelSelections(); + if (card != null) { + matchUI.setCard(card); + matchUI.setPanelSelection(card); + } } } diff --git a/forge-gui-desktop/src/main/java/forge/gui/GuiChoose.java b/forge-gui-desktop/src/main/java/forge/gui/GuiChoose.java index da3b101d5f9..a868a981372 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/GuiChoose.java +++ b/forge-gui-desktop/src/main/java/forge/gui/GuiChoose.java @@ -188,6 +188,9 @@ public class GuiChoose { } public static List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display) { + return getChoices(message, min, max, choices, selected, display, null); + } + public static List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display, final CMatchUI matchUI) { if (choices == null || choices.isEmpty()) { if (min == 0) { return new ArrayList(); @@ -195,36 +198,38 @@ public class GuiChoose { throw new RuntimeException("choice required from empty list"); } - Callable> showChoice = new Callable>() { + final Callable> showChoice = new Callable>() { @Override public List call() { ListChooser c = new ListChooser(message, min, max, choices, display); final JList list = c.getLstChoices(); - list.addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(final ListSelectionEvent ev) { - final T sel = list.getSelectedValue(); - if (sel instanceof InventoryItem) { - CMatchUI.SINGLETON_INSTANCE.setCard((InventoryItem) list.getSelectedValue()); - return; - } + if (matchUI != null) { + list.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(final ListSelectionEvent ev) { + final T sel = list.getSelectedValue(); + if (sel instanceof InventoryItem) { + matchUI.setCard((InventoryItem) list.getSelectedValue()); + return; + } - final CardView card; - if (sel instanceof CardStateView) { - card = ((CardStateView) sel).getCard(); - } else if (sel instanceof CardView) { - card = (CardView) sel; - } else { - card = null; - } - if (card != null) { - CMatchUI.SINGLETON_INSTANCE.setCard(card); + final CardView card; + if (sel instanceof CardStateView) { + card = ((CardStateView) sel).getCard(); + } else if (sel instanceof CardView) { + card = (CardView) sel; + } else { + card = null; + } + if (card != null) { + matchUI.setCard(card); - GuiUtils.clearPanelSelections(); - GuiUtils.setPanelSelection(card); + matchUI.clearPanelSelections(); + matchUI.setPanelSelection(card); + } } - } - }); + }); + } if (selected != null) { c.show(selected); @@ -233,7 +238,9 @@ public class GuiChoose { c.show(); } - GuiUtils.clearPanelSelections(); + if (matchUI != null) { + matchUI.clearPanelSelections(); + } return c.getSelectedValues(); } }; @@ -248,34 +255,28 @@ public class GuiChoose { return null; } - public static List many(final String title, final String topCaption, int cnt, final List sourceChoices, final CardView referenceCard) { - return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false); - } - - public static List many(final String title, final String topCaption, int min, int max, final List sourceChoices, final CardView referenceCard) { - int m2 = min >= 0 ? sourceChoices.size() - min : -1; - int m1 = max >= 0 ? sourceChoices.size() - max : -1; - return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false); - } - - public static List order(final String title, final String top, final List sourceChoices, final CardView referenceCard) { - return order(title, top, 0, 0, sourceChoices, null, referenceCard, false); - } - - public static > List sideboard(List sideboard, List deck) { + public static > List sideboard(final CMatchUI matchUI, final List sideboard, final List deck) { Collections.sort(deck); Collections.sort(sideboard); return order("Sideboard", "Main Deck", -1, -1, sideboard, deck, null, true); } + public static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, + final List sourceChoices, final List destChoices) { + return order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, null, false, null); + } public static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { + return order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode, null); + } + public static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, + final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode, final CMatchUI matchUI) { // An input box for handling the order of choices. Callable> callable = new Callable>() { @Override public List call() throws Exception { - DualListBox dual = new DualListBox(remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices); + DualListBox dual = new DualListBox(remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, matchUI); dual.setSecondColumnLabelText(top); dual.setSideboardMode(sideboardingMode); @@ -283,8 +284,8 @@ public class GuiChoose { dual.setTitle(title); dual.pack(); dual.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - if (referenceCard != null) { - CMatchUI.SINGLETON_INSTANCE.setCard(referenceCard); + if (matchUI != null && referenceCard != null) { + matchUI.setCard(referenceCard); // MARKED FOR UPDATE } dual.setVisible(true); @@ -292,7 +293,9 @@ public class GuiChoose { List objects = dual.getOrderedList(); dual.dispose(); - GuiUtils.clearPanelSelections(); + if (matchUI != null) { + matchUI.clearPanelSelections(); + } return objects; } }; diff --git a/forge-gui-desktop/src/main/java/forge/gui/GuiDialog.java b/forge-gui-desktop/src/main/java/forge/gui/GuiDialog.java index 3d8d3e74558..5adc551d090 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/GuiDialog.java +++ b/forge-gui-desktop/src/main/java/forge/gui/GuiDialog.java @@ -20,21 +20,24 @@ public class GuiDialog { private static final String[] defaultConfirmOptions = { "Yes", "No" }; public static boolean confirm(final CardView c, final String question) { - return GuiDialog.confirm(c, question, true, null); + return confirm(c, question, true, null); } public static boolean confirm(final CardView c, final String question, final boolean defaultChoice) { - return GuiDialog.confirm(c, question, defaultChoice, null); + return confirm(c, question, defaultChoice, null); } public static boolean confirm(final CardView c, final String question, String[] options) { - return GuiDialog.confirm(c, question, true, options); + return confirm(c, question, true, options); } public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) { + return confirm(c, question, defaultIsYes, options, null); + } + public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options, final CMatchUI matchUI) { Callable confirmTask = new Callable() { @Override public Boolean call() throws Exception { - if (c != null) { - CMatchUI.SINGLETON_INSTANCE.setCard(c); + if (matchUI != null && c != null) { + matchUI.setCard(c); } final String title = c == null ? "Question" : c + " - Ability"; diff --git a/forge-gui-desktop/src/main/java/forge/gui/GuiUtils.java b/forge-gui-desktop/src/main/java/forge/gui/GuiUtils.java index 47b0ff81f15..e2b56ad6828 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/GuiUtils.java +++ b/forge-gui-desktop/src/main/java/forge/gui/GuiUtils.java @@ -24,7 +24,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; -import java.util.List; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -32,11 +31,6 @@ import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.KeyStroke; -import forge.game.card.CardView; -import forge.screens.match.VMatchUI; -import forge.screens.match.views.VField; -import forge.view.arcane.CardPanel; - /** *

* GuiUtils class. @@ -72,37 +66,6 @@ public final class GuiUtils { return ttf; } - /** - * Clear all visually highlighted card panels on the battlefield. - */ - public static void clearPanelSelections() { - List view = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); - for (VField v : view) { - for (CardPanel p : v.getTabletop().getCardPanels()) { - p.setSelected(false); - } - } - } - - /** - * Highlight a card on the playfield. - * - * @param card - * a card to be highlighted - */ - public static void setPanelSelection(final CardView card) { - mainLoop: - for (final VField v : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { - final List panels = v.getTabletop().getCardPanels(); - for (final CardPanel p : panels) { - if (p.getCard().equals(card)) { - p.setSelected(true); - break mainLoop; - } - } - } - } - private static final int minItemWidth = 100; private static final int itemHeight = 25; diff --git a/forge-gui-desktop/src/main/java/forge/gui/SOverlayUtils.java b/forge-gui-desktop/src/main/java/forge/gui/SOverlayUtils.java index d2f52102305..77bd54e75cd 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/SOverlayUtils.java +++ b/forge-gui-desktop/src/main/java/forge/gui/SOverlayUtils.java @@ -1,22 +1,25 @@ package forge.gui; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.FocusManager; +import javax.swing.JPanel; +import javax.swing.Timer; + +import net.miginfocom.swing.MigLayout; import forge.Singletons; import forge.assets.FSkinProp; -import forge.screens.match.TargetingOverlay; import forge.toolbox.FLabel; import forge.toolbox.FOverlay; import forge.toolbox.FPanel; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedButton; import forge.toolbox.FSkin.SkinnedLabel; -import net.miginfocom.swing.MigLayout; - -import javax.swing.FocusManager; -import javax.swing.*; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; /** * All overlay interaction is handled here. @@ -148,14 +151,4 @@ public final class SOverlayUtils { _overlayHasFocus = false; } - public static void showTargetingOverlay() { - TargetingOverlay.SINGLETON_INSTANCE.getPanel().setVisible(true); - } - - /** - * Removes child components and closes overlay. - */ - public static void hideTargetingOverlay() { - TargetingOverlay.SINGLETON_INSTANCE.getPanel().setVisible(false); - } } diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/CEmptyDoc.java b/forge-gui-desktop/src/main/java/forge/gui/framework/CEmptyDoc.java index cdf87ce142c..3578fff2ae4 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/CEmptyDoc.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/CEmptyDoc.java @@ -16,6 +16,10 @@ public class CEmptyDoc implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java b/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java index 89ddc6787fe..8d16021fc33 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/EDocID.java @@ -3,13 +3,23 @@ */ package forge.gui.framework; -import forge.screens.deckeditor.views.*; +import forge.screens.deckeditor.views.VAllDecks; +import forge.screens.deckeditor.views.VCardCatalog; +import forge.screens.deckeditor.views.VCurrentDeck; +import forge.screens.deckeditor.views.VDeckgen; +import forge.screens.deckeditor.views.VProbabilities; +import forge.screens.deckeditor.views.VStatistics; import forge.screens.home.gauntlet.VSubmenuGauntletBuild; import forge.screens.home.gauntlet.VSubmenuGauntletContests; import forge.screens.home.gauntlet.VSubmenuGauntletLoad; import forge.screens.home.gauntlet.VSubmenuGauntletQuick; import forge.screens.home.online.VSubmenuOnlineLobby; -import forge.screens.home.quest.*; +import forge.screens.home.quest.VSubmenuChallenges; +import forge.screens.home.quest.VSubmenuDuels; +import forge.screens.home.quest.VSubmenuQuestData; +import forge.screens.home.quest.VSubmenuQuestDecks; +import forge.screens.home.quest.VSubmenuQuestDraft; +import forge.screens.home.quest.VSubmenuQuestPrefs; import forge.screens.home.sanctioned.VSubmenuConstructed; import forge.screens.home.sanctioned.VSubmenuDraft; import forge.screens.home.sanctioned.VSubmenuSealed; @@ -19,7 +29,6 @@ import forge.screens.home.settings.VSubmenuAvatars; import forge.screens.home.settings.VSubmenuDownloaders; import forge.screens.home.settings.VSubmenuPreferences; import forge.screens.home.settings.VSubmenuReleaseNotes; -import forge.screens.match.views.*; import forge.screens.workshop.views.VCardDesigner; import forge.screens.workshop.views.VCardScript; import forge.screens.workshop.views.VWorkshopCatalog; @@ -31,9 +40,9 @@ import forge.screens.workshop.views.VWorkshopCatalog; *

(E at beginning of class name denotes an enum.) */ public enum EDocID { - CARD_PICTURE (VPicture.SINGLETON_INSTANCE), - CARD_DETAIL (VDetail.SINGLETON_INSTANCE), - CARD_ANTES (VAntes.SINGLETON_INSTANCE), + CARD_PICTURE (), + CARD_DETAIL (), + CARD_ANTES (), EDITOR_ALLDECKS (VAllDecks.SINGLETON_INSTANCE), EDITOR_STATISTICS (VStatistics.SINGLETON_INSTANCE), @@ -67,53 +76,63 @@ public enum EDocID { HOME_LOBBY (VSubmenuOnlineLobby.SINGLETON_INSTANCE), HOME_RELEASE_NOTES (VSubmenuReleaseNotes.SINGLETON_INSTANCE), - REPORT_MESSAGE (VPrompt.SINGLETON_INSTANCE), - REPORT_STACK (VStack.SINGLETON_INSTANCE), - REPORT_COMBAT (VCombat.SINGLETON_INSTANCE), - REPORT_LOG (VLog.SINGLETON_INSTANCE), - REPORT_PLAYERS (VPlayers.SINGLETON_INSTANCE), + REPORT_MESSAGE (), + REPORT_STACK (), + REPORT_COMBAT (), + REPORT_LOG (), + REPORT_PLAYERS (), - DEV_MODE (VDev.SINGLETON_INSTANCE), - BUTTON_DOCK (VDock.SINGLETON_INSTANCE), + DEV_MODE (), + BUTTON_DOCK (), - // Non-user battlefields (AI or teammate), use setDoc to register. - FIELD_0 (null), - FIELD_1 (null), - FIELD_2 (null), - FIELD_3 (null), - FIELD_4 (null), - FIELD_5 (null), - FIELD_6 (null), - FIELD_7 (null), + // Battlefields, use setDoc to register. + FIELD_0 (), + FIELD_1 (), + FIELD_2 (), + FIELD_3 (), + FIELD_4 (), + FIELD_5 (), + FIELD_6 (), + FIELD_7 (), - // Non-user hands (AI or teammate), use setDoc to register. - HAND_0 (null), - HAND_1 (null), - HAND_2 (null), - HAND_3 (null), - HAND_4 (null), - HAND_5 (null), - HAND_6 (null), - HAND_7 (null), + // Hands, use setDoc to register. + HAND_0 (), + HAND_1 (), + HAND_2 (), + HAND_3 (), + HAND_4 (), + HAND_5 (), + HAND_6 (), + HAND_7 (), - COMMAND_0 (null), - COMMAND_1 (null), - COMMAND_2 (null), - COMMAND_3 (null), - COMMAND_4 (null), - COMMAND_5 (null), - COMMAND_6 (null), - COMMAND_7 (null); + // Command zones, use setDoc to register. + COMMAND_0 (), + COMMAND_1 (), + COMMAND_2 (), + COMMAND_3 (), + COMMAND_4 (), + COMMAND_5 (), + COMMAND_6 (), + COMMAND_7 (); public final static EDocID[] Commands = new EDocID[] {COMMAND_0, COMMAND_1, COMMAND_2, COMMAND_3, COMMAND_4, COMMAND_5, COMMAND_6, COMMAND_7}; public final static EDocID[] Fields = new EDocID[] {FIELD_0, FIELD_1, FIELD_2, FIELD_3, FIELD_4, FIELD_5, FIELD_6, FIELD_7}; public final static EDocID[] Hands = new EDocID[] {HAND_0, HAND_1, HAND_2, HAND_3, HAND_4, HAND_5, HAND_6, HAND_7}; + static { + for (int i = 0; i < 8; i++) EDocID.Fields[i].setDoc(new VEmptyDoc(EDocID.Fields[i])); + for (int i = 0; i < 8; i++) EDocID.Commands[i].setDoc(new VEmptyDoc(EDocID.Commands[i])); + for (int i = 0; i < 8; i++) EDocID.Hands[i].setDoc(new VEmptyDoc(EDocID.Hands[i])); + } // End enum declarations, start enum methods. private IVDoc vDoc; + private EDocID() { + this(null); + } + /** @param doc0   {@link forge.gui.framework.IVDoc} */ - EDocID(final IVDoc doc0) { + private EDocID(final IVDoc doc0) { this.vDoc = doc0; } @@ -124,7 +143,7 @@ public enum EDocID { /** @return {@link forge.gui.framework.IVDoc} */ public IVDoc getDoc() { - if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); } + //if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); } return vDoc; } } diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/FScreen.java b/forge-gui-desktop/src/main/java/forge/gui/framework/FScreen.java index 977259b14a1..44bcfb4f76f 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/FScreen.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/FScreen.java @@ -1,5 +1,7 @@ package forge.gui.framework; +import java.io.File; + import forge.Singletons; import forge.assets.FSkinProp; import forge.properties.FileLocation; @@ -17,144 +19,152 @@ import forge.screens.workshop.VWorkshopUI; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinImage; - -import java.io.File; +import forge.view.FView; /** * Definitions for Forge screens - * */ -public enum FScreen { - HOME_SCREEN( +public class FScreen { + public static final FScreen HOME_SCREEN = new FScreen( VHomeUI.SINGLETON_INSTANCE, CHomeUI.SINGLETON_INSTANCE, "Home", FSkin.getIcon(FSkinProp.ICO_FAVICON), false, "Exit Forge", - null), - MATCH_SCREEN( - VMatchUI.SINGLETON_INSTANCE, - CMatchUI.SINGLETON_INSTANCE, - "Game", - FSkin.getIcon(FSkinProp.ICO_ALPHASTRIKE), //TODO: Create icon for match screen - true, - "Concede Game", - ForgeConstants.MATCH_LAYOUT_FILE), - WORKSHOP_SCREEN( + null, + false); + public static final FScreen WORKSHOP_SCREEN = new FScreen( VWorkshopUI.SINGLETON_INSTANCE, CWorkshopUI.SINGLETON_INSTANCE, "Workshop", FSkin.getIcon(FSkinProp.ICO_SETTINGS), //TODO: Create icon for workshop screen false, "Back to Home", - ForgeConstants.WORKSHOP_LAYOUT_FILE), - DECK_EDITOR_CONSTRUCTED( + ForgeConstants.WORKSHOP_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_CONSTRUCTED = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), false, "Back to Home", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_ARCHENEMY( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_ARCHENEMY = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Scheme Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_COMMANDER( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_COMMANDER = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Commander Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_PLANECHASE( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_PLANECHASE = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Planar Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_VANGUARD( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_VANGUARD = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Vanguard Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_DRAFT( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_DRAFT = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Draft Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_SEALED( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_SEALED = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Sealed Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_QUEST( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_QUEST = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Quest Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - DECK_EDITOR_QUEST_TOURNAMENT( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DECK_EDITOR_QUEST_TOURNAMENT = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Quest Tournament Deck Editor", FSkin.getImage(FSkinProp.IMG_PACK), true, "Close Editor", - ForgeConstants.EDITOR_LAYOUT_FILE), - QUEST_CARD_SHOP( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen QUEST_CARD_SHOP = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Spell Shop", FSkin.getIcon(FSkinProp.ICO_QUEST_BOOK), true, "Leave Shop", - ForgeConstants.EDITOR_LAYOUT_FILE), - DRAFTING_PROCESS( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen DRAFTING_PROCESS = new FScreen( VDeckEditorUI.SINGLETON_INSTANCE, CDeckEditorUI.SINGLETON_INSTANCE, "Draft", FSkin.getImage(FSkinProp.IMG_ZONE_HAND), true, "Leave Draft", - ForgeConstants.EDITOR_LAYOUT_FILE), - QUEST_BAZAAR( + ForgeConstants.EDITOR_LAYOUT_FILE, + false); + public static final FScreen QUEST_BAZAAR = new FScreen( VBazaarUI.SINGLETON_INSTANCE, CBazaarUI.SINGLETON_INSTANCE, "Bazaar", FSkin.getIcon(FSkinProp.ICO_QUEST_BOTTLES), true, "Leave Bazaar", - null); + null, + false); private final IVTopLevelUI view; private final ICDoc controller; - private final String tabCaption; + private String tabCaption; private final SkinImage tabIcon; private final boolean allowTabClose; private final String closeButtonTooltip; private final FileLocation layoutFile; - - private FScreen(IVTopLevelUI view0, ICDoc controller0, String tabCaption0, SkinImage tabIcon0, boolean allowTabClose0, String closeButtonTooltip0, FileLocation layoutFile0) { + private final boolean isMatch; + + private FScreen(final IVTopLevelUI view0, final ICDoc controller0, + final String tabCaption0, final SkinImage tabIcon0, + final boolean allowTabClose0, final String closeButtonTooltip0, + final FileLocation layoutFile0, final boolean isMatch) { this.view = view0; this.controller = controller0; this.tabCaption = tabCaption0; @@ -162,6 +172,19 @@ public enum FScreen { this.allowTabClose = allowTabClose0; this.closeButtonTooltip = closeButtonTooltip0; this.layoutFile = layoutFile0; + this.isMatch = isMatch; + } + + public static FScreen getMatchScreen(final CMatchUI controller, final VMatchUI view) { + return new FScreen( + view, + controller, + "Game", + FSkin.getIcon(FSkinProp.ICO_ALPHASTRIKE), //TODO: Create icon for match screen + true, + "Concede Game", + ForgeConstants.MATCH_LAYOUT_FILE, + true); } public IVTopLevelUI getView() { @@ -175,23 +198,27 @@ public enum FScreen { public String getTabCaption() { return tabCaption; } - + public void setTabCaption(final String caption) { + this.tabCaption = caption; + FView.SINGLETON_INSTANCE.getNavigationBar().updateTitle(this); + } + public SkinImage getTabIcon() { return tabIcon; } - + public boolean allowTabClose() { return allowTabClose; } - + public String getCloseButtonTooltip() { return closeButtonTooltip; } - + public boolean onSwitching(FScreen toScreen) { return view.onSwitching(this, toScreen); } - + public boolean onClosing() { return view.onClosing(this); } @@ -202,17 +229,22 @@ public enum FScreen { public boolean deleteLayoutFile() { if (layoutFile == null) { return false; } - + return deleteLayoutFile(layoutFile); + } + public static boolean deleteMatchLayoutFile() { + return deleteLayoutFile(ForgeConstants.MATCH_LAYOUT_FILE); + } + private static boolean deleteLayoutFile(final FileLocation file) { try { - File file = new File(layoutFile.userPrefLoc); - file.delete(); + File f = new File(file.userPrefLoc); + f.delete(); return true; - } - catch (final Exception e) { + } catch (final Exception e) { e.printStackTrace(); FOptionPane.showErrorDialog("Failed to delete layout file."); } return false; + } public void open() { @@ -222,4 +254,8 @@ public enum FScreen { public void close() { Singletons.getView().getNavigationBar().closeTab(this); } + + public boolean isMatchScreen() { + return isMatch; + } } diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/ICDoc.java b/forge-gui-desktop/src/main/java/forge/gui/framework/ICDoc.java index 2371de1b98a..4dcf935d7fa 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/ICDoc.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/ICDoc.java @@ -3,28 +3,33 @@ package forge.gui.framework; import forge.UiCommand; /** - * Dictates methods required for any controller - * of an {@link forge.gui.framework.IVDoc}. + * Dictates methods required for any controller of an + * {@link forge.gui.framework.IVDoc}. * - *

(I at beginning of class name denotes an interface.) - *
(C at beginning of class name denotes a controller class.) + *
+ *
+ * (I at beginning of class name denotes an interface.)
+ * (C at beginning of class name denotes a controller class.) */ public interface ICDoc { /** - * Fires when this controller's view tab is selected. - * Since this method is fired when all tabs are first - * initialized, be wary of NPEs created by referring to - * non-existent components. + * Fires when this controller's view tab is selected. Since this method is + * fired when all tabs are first initialized, be wary of NPEs created by + * referring to non-existent components. * - * @return {@link forge.UiCommand} */ + * @return {@link forge.UiCommand} + */ UiCommand getCommandOnSelect(); /** - * This method is called once, after the view singleton has been fully realized - * for the first time. It should execute operations which should only - * be done once, but require non-null view components. - *

- * This method should only be called once, in FView, after singletons are populated. + * Asks this controller to register its docs, so that a layout can be + * applied to them. + */ + void register(); + + /** + * This method is called every time the user switches to the tab containing + * this item. */ void initialize(); diff --git a/forge-gui-desktop/src/main/java/forge/gui/framework/SLayoutIO.java b/forge-gui-desktop/src/main/java/forge/gui/framework/SLayoutIO.java index 188864a86e8..d8fb7c5dbd5 100644 --- a/forge-gui-desktop/src/main/java/forge/gui/framework/SLayoutIO.java +++ b/forge-gui-desktop/src/main/java/forge/gui/framework/SLayoutIO.java @@ -1,9 +1,13 @@ package forge.gui.framework; +import forge.FThreads; import forge.Singletons; +import forge.gui.SOverlayUtils; import forge.properties.FileLocation; import forge.properties.ForgeConstants; import forge.toolbox.FAbsolutePositioner; +import forge.toolbox.SaveOpenDialog; +import forge.toolbox.SaveOpenDialog.Filetypes; import forge.util.CollectionSuppliers; import forge.util.ThreadUtil; import forge.util.maps.HashMapOfLists; @@ -49,6 +53,54 @@ public final class SLayoutIO { private final static AtomicBoolean saveWindowRequested = new AtomicBoolean(false); + + public static void saveLayout() { + final SaveOpenDialog dlgSave = new SaveOpenDialog(); + final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile(); + final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null; + final File saveFile = dlgSave.SaveDialog(defFile, Filetypes.LAYOUT); + if (saveFile != null) { + SLayoutIO.saveLayout(saveFile); + } + } + + public static void openLayout() { + SOverlayUtils.genericOverlay(); + + final SaveOpenDialog dlgOpen = new SaveOpenDialog(); + final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile(); + final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null; + final File loadFile = dlgOpen.OpenDialog(defFile, Filetypes.LAYOUT); + + if (loadFile != null) { + FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); + // let it redraw everything first + + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + if (loadFile != null) { + SLayoutIO.loadLayout(loadFile); + SLayoutIO.saveLayout(null); + } + SOverlayUtils.hideOverlay(); + } + }); + } + } + + public static void revertLayout() { + SOverlayUtils.genericOverlay(); + FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); + + FThreads.invokeInEdtLater(new Runnable(){ + @Override public void run() { + SLayoutIO.loadLayout(null); + SOverlayUtils.hideOverlay(); + } + }); + } + public static void saveWindowLayout() { if (saveWindowRequested.getAndSet(true)) { return; } ThreadUtil.delay(500, new Runnable() { diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/CardManager.java b/forge-gui-desktop/src/main/java/forge/itemmanager/CardManager.java index a51aff36f92..f64067e1668 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/CardManager.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/CardManager.java @@ -7,6 +7,8 @@ import forge.itemmanager.filters.*; import forge.model.FModel; import forge.quest.QuestWorld; import forge.screens.home.quest.DialogChooseSets; +import forge.screens.match.controllers.CDetailPicture; + import javax.swing.*; import java.util.HashMap; @@ -19,8 +21,8 @@ import java.util.Map.Entry; */ @SuppressWarnings("serial") public class CardManager extends ItemManager { - public CardManager(boolean wantUnique0) { - super(PaperCard.class, wantUnique0); + public CardManager(final CDetailPicture cDetailPicture, final boolean wantUnique0) { + super(PaperCard.class, cDetailPicture, wantUnique0); } @Override diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java b/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java index 1ab329c40b9..679e31f4951 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/DeckManager.java @@ -1,5 +1,23 @@ package forge.itemmanager; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.swing.JMenu; +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.apache.commons.lang3.StringUtils; + import forge.Singletons; import forge.UiCommand; import forge.assets.FSkinProp; @@ -12,7 +30,13 @@ import forge.game.IHasGameType; import forge.gui.GuiUtils; import forge.gui.framework.FScreen; import forge.item.InventoryItem; -import forge.itemmanager.filters.*; +import forge.itemmanager.filters.DeckColorFilter; +import forge.itemmanager.filters.DeckFolderFilter; +import forge.itemmanager.filters.DeckFormatFilter; +import forge.itemmanager.filters.DeckQuestWorldFilter; +import forge.itemmanager.filters.DeckSearchFilter; +import forge.itemmanager.filters.DeckSetFilter; +import forge.itemmanager.filters.ItemFilter; import forge.itemmanager.views.ItemCellRenderer; import forge.itemmanager.views.ItemListView; import forge.itemmanager.views.ItemTableColumn; @@ -24,21 +48,10 @@ import forge.screens.deckeditor.controllers.ACEditorBase; import forge.screens.deckeditor.controllers.CEditorLimited; import forge.screens.deckeditor.controllers.CEditorQuest; import forge.screens.home.quest.DialogChooseSets; +import forge.screens.match.controllers.CDetailPicture; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - -import java.awt.*; -import java.awt.event.MouseEvent; -import java.util.*; -import java.util.List; -import java.util.Map.Entry; - /** * ItemManager for decks * @@ -59,8 +72,8 @@ public final class DeckManager extends ItemManager implements IHasGam * * @param gt */ - public DeckManager(final GameType gt) { - super(DeckProxy.class, true); + public DeckManager(final GameType gt, final CDetailPicture cDetailPicture) { + super(DeckProxy.class, cDetailPicture, true); this.gameType = gt; this.addSelectionListener(new ListSelectionListener() { diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/ItemManager.java b/forge-gui-desktop/src/main/java/forge/itemmanager/ItemManager.java index 9ce85ef10cb..9fbda927d53 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/ItemManager.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/ItemManager.java @@ -31,6 +31,7 @@ import forge.itemmanager.ItemManagerConfig; import forge.itemmanager.ItemManagerModel; import forge.itemmanager.filters.ItemFilter; import forge.itemmanager.views.*; +import forge.screens.match.controllers.CDetailPicture; import forge.toolbox.*; import forge.toolbox.FSkin.Colors; import forge.toolbox.FSkin.SkinIcon; @@ -74,6 +75,7 @@ public abstract class ItemManager extends JPanel implem private UiCommand itemActivateCommand; private ContextMenuBuilder contextMenuBuilder; private final Class genericType; + private final CDetailPicture cDetailPicture; private ItemManagerConfig config; private final ArrayList selectionListeners = new ArrayList(); @@ -125,7 +127,8 @@ public abstract class ItemManager extends JPanel implem * @param statLabels0 stat labels for this item manager * @param wantUnique0 whether this table should display only one item with the same name */ - protected ItemManager(final Class genericType0, final boolean wantUnique0) { + protected ItemManager(final Class genericType0, final CDetailPicture cDetailPicture, final boolean wantUnique0) { + this.cDetailPicture = cDetailPicture; this.genericType = genericType0; this.wantUnique = wantUnique0; this.model = new ItemManagerModel(genericType0); @@ -144,6 +147,10 @@ public abstract class ItemManager extends JPanel implem return new ImageView(this, model0); } + public final CDetailPicture getCDetailPicture() { + return cDetailPicture; + } + /** * Initialize item manager if needed */ diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/SpellShopManager.java b/forge-gui-desktop/src/main/java/forge/itemmanager/SpellShopManager.java index 9735bda57ee..5ccb5144eb9 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/SpellShopManager.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/SpellShopManager.java @@ -2,6 +2,7 @@ package forge.itemmanager; import forge.item.InventoryItem; import forge.itemmanager.filters.ItemFilter; +import forge.screens.match.controllers.CDetailPicture; import javax.swing.*; @@ -11,8 +12,8 @@ import javax.swing.*; */ @SuppressWarnings("serial") public final class SpellShopManager extends ItemManager { - public SpellShopManager(boolean wantUnique0) { - super(InventoryItem.class, wantUnique0); + public SpellShopManager(final CDetailPicture cDetailPicture, final boolean wantUnique0) { + super(InventoryItem.class, cDetailPicture, wantUnique0); } @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 441d57135fb..bb458d7c16a 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 @@ -1,5 +1,34 @@ package forge.itemmanager.views; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseWheelEvent; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JViewport; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; + import forge.ImageCache; import forge.assets.FSkinProp; import forge.deck.DeckProxy; @@ -14,26 +43,19 @@ import forge.itemmanager.ItemManager; import forge.itemmanager.ItemManagerConfig; import forge.itemmanager.ItemManagerModel; import forge.itemmanager.SItemManagerUtil; -import forge.screens.match.controllers.CDetail; -import forge.screens.match.controllers.CPicture; -import forge.toolbox.*; +import forge.screens.match.controllers.CDetailPicture; +import forge.toolbox.FComboBoxWrapper; +import forge.toolbox.FLabel; +import forge.toolbox.FMouseAdapter; +import forge.toolbox.FScrollPane; +import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinColor; import forge.toolbox.FSkin.SkinFont; import forge.toolbox.FSkin.SkinImage; +import forge.toolbox.FTextField; import forge.toolbox.special.CardZoomer; import forge.view.arcane.CardPanel; -import javax.swing.*; - -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - public class ImageView extends ItemView { private static final int PADDING = 5; private static final float PILE_SPACING_Y = 0.1f; @@ -137,7 +159,7 @@ public class ImageView extends ItemView { private final FComboBoxWrapper cbPileByOptions = new FComboBoxWrapper(); private final FComboBoxWrapper cbColumnCount = new FComboBoxWrapper(); - public ImageView(ItemManager itemManager0, ItemManagerModel model0) { + public ImageView(final ItemManager itemManager0, final ItemManagerModel model0) { super(itemManager0, model0); SItemManagerUtil.populateImageViewOptions(itemManager0, cbGroupByOptions, cbPileByOptions); @@ -728,9 +750,11 @@ public class ImageView extends ItemView { return true; } - protected void showHoveredItem(T item) { - CDetail.SINGLETON_INSTANCE.showCard(item); - CPicture.SINGLETON_INSTANCE.showImage(item); + protected void showHoveredItem(final T item) { + final CDetailPicture cDetailPicture = itemManager.getCDetailPicture(); + if (cDetailPicture != null) { + cDetailPicture.showItem(item); + } } @Override diff --git a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemView.java b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemView.java index b8146cc8e34..cf876329278 100644 --- a/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemView.java +++ b/forge-gui-desktop/src/main/java/forge/itemmanager/views/ItemView.java @@ -1,5 +1,40 @@ package forge.itemmanager.views; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseWheelEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.swing.JComponent; +import javax.swing.JViewport; +import javax.swing.Popup; +import javax.swing.PopupFactory; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import net.miginfocom.swing.MigLayout; + +import org.apache.commons.lang3.CharUtils; +import org.apache.commons.lang3.StringUtils; + import forge.item.InventoryItem; import forge.itemmanager.ColumnDef; import forge.itemmanager.ItemManager; @@ -9,24 +44,9 @@ import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; import forge.toolbox.FScrollPanel; import forge.toolbox.FSkin; -import forge.toolbox.ToolTipListener; import forge.toolbox.FSkin.SkinColor; import forge.toolbox.FSkin.SkinImage; -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.CharUtils; -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - -import java.awt.*; -import java.awt.event.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import forge.toolbox.ToolTipListener; public abstract class ItemView { private static final SkinColor BORDER_COLOR = FSkin.getColor(FSkin.Colors.CLR_TEXT); @@ -44,7 +64,7 @@ public abstract class ItemView { private boolean isIncrementalSearchActive = false; @SuppressWarnings("serial") - protected ItemView(ItemManager itemManager0, ItemManagerModel model0) { + protected ItemView(final ItemManager itemManager0, final ItemManagerModel model0) { this.itemManager = itemManager0; this.model = model0; this.scroller = new FScrollPane(false) { diff --git a/forge-gui-desktop/src/main/java/forge/menus/ForgeMenu.java b/forge-gui-desktop/src/main/java/forge/menus/ForgeMenu.java index 75330cc3482..0e56f6208ba 100644 --- a/forge-gui-desktop/src/main/java/forge/menus/ForgeMenu.java +++ b/forge-gui-desktop/src/main/java/forge/menus/ForgeMenu.java @@ -43,7 +43,7 @@ public final class ForgeMenu { provider = provider0; refresh(); } - + public void refresh() { activeShortcuts.clear(); popupMenu = new JPopupMenu(); @@ -66,7 +66,7 @@ public final class ForgeMenu { } } } - add(LayoutMenu.getMenu()); + add(new LayoutMenu().getMenu()); add(HelpMenu.getMenu()); addSeparator(); add(getMenuItem_Restart()); diff --git a/forge-gui-desktop/src/main/java/forge/menus/LayoutMenu.java b/forge-gui-desktop/src/main/java/forge/menus/LayoutMenu.java index 47088efdc54..65bb56db171 100644 --- a/forge-gui-desktop/src/main/java/forge/menus/LayoutMenu.java +++ b/forge-gui-desktop/src/main/java/forge/menus/LayoutMenu.java @@ -1,40 +1,46 @@ package forge.menus; +import java.awt.Cursor; +import java.awt.Image; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +import javax.swing.ButtonGroup; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.KeyStroke; + import forge.Singletons; import forge.assets.FSkinProp; import forge.gui.GuiChoose; import forge.gui.MouseUtil; import forge.gui.framework.FScreen; +import forge.gui.framework.SLayoutIO; import forge.model.FModel; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; -import forge.screens.match.controllers.CDock; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedMenuItem; import forge.view.FFrame; import forge.view.FView; -import javax.swing.*; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; - /** * Returns a JMenu containing options associated with game screen layout. *

* Replicates options available in Dock tab. */ public final class LayoutMenu { - private LayoutMenu() { } + public LayoutMenu() { + } - private static final CDock controller = CDock.SINGLETON_INSTANCE; - private static FScreen currentScreen; + private FScreen currentScreen; private static final ForgePreferences prefs = FModel.getPreferences(); - private static boolean showIcons = false; + private boolean showIcons = false; - public static JMenu getMenu() { + public JMenu getMenu() { currentScreen = Singletons.getControl().getCurrentScreen(); JMenu menu = new JMenu("Layout"); @@ -53,16 +59,16 @@ public final class LayoutMenu { return menu; } - private static JMenu getMenu_ViewOptions() { + private JMenu getMenu_ViewOptions() { JMenu menu = new JMenu("View"); menu.add(getMenuItem_ShowTabs()); - if (currentScreen == FScreen.MATCH_SCREEN) { + if (currentScreen != null && currentScreen.isMatchScreen()) { menu.add(getMenuItem_ShowBackgroundImage()); } return menu; } - private static JMenu getMenu_FileOptions() { + private JMenu getMenu_FileOptions() { JMenu menu = new JMenu("File"); menu.add(getMenuItem_OpenLayout()); menu.add(getMenuItem_SaveLayout()); @@ -138,50 +144,50 @@ public final class LayoutMenu { }; } - private static JMenuItem getMenuItem_SaveLayout() { + private JMenuItem getMenuItem_SaveLayout() { SkinnedMenuItem menuItem = new SkinnedMenuItem("Save Current Layout"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_SAVELAYOUT) : null)); menuItem.addActionListener(getSaveLayoutAction()); return menuItem; } - private static ActionListener getSaveLayoutAction() { + private ActionListener getSaveLayoutAction() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - controller.saveLayout(); + SLayoutIO.saveLayout(); } }; } - private static JMenuItem getMenuItem_OpenLayout() { + private JMenuItem getMenuItem_OpenLayout() { SkinnedMenuItem menuItem = new SkinnedMenuItem("Open..."); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_OPENLAYOUT) : null)); menuItem.addActionListener(getOpenLayoutAction()); return menuItem; } - private static ActionListener getOpenLayoutAction() { + private ActionListener getOpenLayoutAction() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - controller.openLayout(); + SLayoutIO.openLayout(); } }; } - private static JMenuItem getMenuItem_RevertLayout() { + private JMenuItem getMenuItem_RevertLayout() { SkinnedMenuItem menuItem = new SkinnedMenuItem("Refresh"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_REVERTLAYOUT) : null)); menuItem.addActionListener(getRevertLayoutAction()); return menuItem; } - private static ActionListener getRevertLayoutAction() { + private ActionListener getRevertLayoutAction() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - controller.revertLayout(); + SLayoutIO.revertLayout(); } }; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/bazaar/CBazaarUI.java b/forge-gui-desktop/src/main/java/forge/screens/bazaar/CBazaarUI.java index d6fc426afce..60c980f3f4c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/bazaar/CBazaarUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/bazaar/CBazaarUI.java @@ -51,6 +51,10 @@ public enum CBazaarUI implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/CDeckEditorUI.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/CDeckEditorUI.java index 779054aef26..6f6e8998197 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/CDeckEditorUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/CDeckEditorUI.java @@ -17,32 +17,36 @@ */ package forge.screens.deckeditor; -import forge.UiCommand; -import forge.Singletons; -import forge.deck.DeckBase; -import forge.deck.DeckProxy; -import forge.deck.io.DeckPreferences; -import forge.gui.framework.FScreen; -import forge.gui.framework.ICDoc; -import forge.item.InventoryItem; -import forge.itemmanager.ItemManager; -import forge.screens.deckeditor.controllers.*; -import forge.screens.deckeditor.views.VAllDecks; -import forge.screens.deckeditor.views.VCardCatalog; -import forge.screens.deckeditor.views.VCurrentDeck; -import forge.screens.match.controllers.CDetail; -import forge.screens.match.controllers.CPicture; -import forge.util.ItemPool; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.HashMap; import java.util.Map.Entry; +import javax.swing.SwingUtilities; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import forge.Singletons; +import forge.UiCommand; +import forge.deck.DeckBase; +import forge.deck.DeckProxy; +import forge.deck.io.DeckPreferences; +import forge.gui.framework.EDocID; +import forge.gui.framework.FScreen; +import forge.gui.framework.ICDoc; +import forge.item.InventoryItem; +import forge.itemmanager.ItemManager; +import forge.screens.deckeditor.controllers.ACEditorBase; +import forge.screens.deckeditor.controllers.CEditorConstructed; +import forge.screens.deckeditor.controllers.CProbabilities; +import forge.screens.deckeditor.controllers.CStatistics; +import forge.screens.deckeditor.controllers.DeckController; +import forge.screens.deckeditor.views.VAllDecks; +import forge.screens.deckeditor.views.VCardCatalog; +import forge.screens.deckeditor.views.VCurrentDeck; +import forge.screens.match.controllers.CDetailPicture; +import forge.util.ItemPool; + /** * Constructs instance of deck editor UI controller, used as a single point of * top-level control for child UIs. Tasks targeting the view of individual @@ -57,9 +61,14 @@ public enum CDeckEditorUI implements ICDoc { private final HashMap> screenChildControllers; private ACEditorBase childController; + private final CDetailPicture cDetailPicture; + private final VAllDecks vAllDecks; private CDeckEditorUI() { screenChildControllers = new HashMap>(); + this.cDetailPicture = new CDetailPicture(); + this.vAllDecks = VAllDecks.SINGLETON_INSTANCE; + this.vAllDecks.setCDetailPicture(cDetailPicture); } /** @@ -67,8 +76,7 @@ public enum CDeckEditorUI implements ICDoc { * @param item */ public void setCard(final InventoryItem item) { - CDetail.SINGLETON_INSTANCE.showCard(item); - CPicture.SINGLETON_INSTANCE.showImage(item); + cDetailPicture.showItem(item); } public boolean hasChanges() { @@ -292,6 +300,12 @@ public enum CDeckEditorUI implements ICDoc { return null; } + @Override + public void register() { + EDocID.CARD_PICTURE.setDoc(cDetailPicture.getCPicture().getView()); + EDocID.CARD_DETAIL.setDoc(cDetailPicture.getCDetail().getView()); + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -308,9 +322,9 @@ public enum CDeckEditorUI implements ICDoc { String currentDeckStr = DeckPreferences.getCurrentDeck(); if (currentDeckStr != null) { - DeckProxy deck = VAllDecks.SINGLETON_INSTANCE.getLstDecks().stringToItem(currentDeckStr); + DeckProxy deck = vAllDecks.getLstDecks().stringToItem(currentDeckStr); if (deck != null) { - VAllDecks.SINGLETON_INSTANCE.getLstDecks().setSelectedItem(deck); + vAllDecks.getLstDecks().setSelectedItem(deck); childController.getDeckController().load(deck.getPath(), deck.getName()); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java index 15c54e87563..eb21491881e 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/ACEditorBase.java @@ -36,6 +36,7 @@ import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.menus.CDeckEditorUIMenus; import forge.screens.deckeditor.views.VCardCatalog; import forge.screens.deckeditor.views.VCurrentDeck; +import forge.screens.match.controllers.CDetailPicture; import forge.toolbox.ContextMenuBuilder; import forge.toolbox.FLabel; import forge.toolbox.FSkin; @@ -71,6 +72,7 @@ public abstract class ACEditorBase catalogManager; private ItemManager deckManager; protected DeckSection sectionMode = DeckSection.Main; + private final CDetailPicture cDetailPicture = new CDetailPicture(); // card transfer buttons private final FLabel btnAdd = new FLabel.Builder() @@ -119,6 +121,10 @@ public abstract class ACEditorBase { commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.CAN_BE_COMMANDER, PaperCard.FN_GET_RULES)),PaperCard.class); normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class); - CardManager catalogManager = new CardManager(true); - CardManager deckManager = new CardManager(true); + CardManager catalogManager = new CardManager(getCDetailPicture(), true); + CardManager deckManager = new CardManager(getCDetailPicture(), true); catalogManager.setCaption("Catalog"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java index 4eff573a62d..9a077a210aa 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorConstructed.java @@ -74,8 +74,8 @@ public final class CEditorConstructed extends ACEditorBase { schemePool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_SCHEME, PaperCard.FN_GET_RULES)), PaperCard.class); conspiracyPool = ItemPool.createFrom(FModel.getMagicDb().getVariantCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.IS_CONSPIRACY, PaperCard.FN_GET_RULES)), PaperCard.class); - CardManager catalogManager = new CardManager(false); // TODO: restore the functionality of the "want uniques only" toggle - CardManager deckManager = new CardManager(false); // IMPORTANT: must *always* show all cards in the deck, otherwise cards with different art get ignored! + CardManager catalogManager = new CardManager(getCDetailPicture(), false); // TODO: restore the functionality of the "want uniques only" toggle + CardManager deckManager = new CardManager(getCDetailPicture(), false); // IMPORTANT: must *always* show all cards in the deck, otherwise cards with different art get ignored! catalogManager.setCaption("Catalog"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorDraftingProcess.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorDraftingProcess.java index 76bcd1b42e8..42e62431ed1 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorDraftingProcess.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorDraftingProcess.java @@ -66,8 +66,8 @@ public class CEditorDraftingProcess extends ACEditorBase { public CEditorDraftingProcess() { super(FScreen.DRAFTING_PROCESS); - final CardManager catalogManager = new CardManager(false); - final CardManager deckManager = new CardManager(false); + final CardManager catalogManager = new CardManager(getCDetailPicture(), false); + final CardManager deckManager = new CardManager(getCDetailPicture(), false); //hide filters and options panel so more of pack is visible by default catalogManager.setHideViewOptions(1, true); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java index 75fb3cc60d4..040927d4328 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorLimited.java @@ -61,8 +61,8 @@ public final class CEditorLimited extends ACEditorBase { public CEditorLimited(final IStorage deckMap0, FScreen screen0) { super(screen0); - final CardManager catalogManager = new CardManager(false); - final CardManager deckManager = new CardManager(false); + final CardManager catalogManager = new CardManager(getCDetailPicture(), false); + final CardManager deckManager = new CardManager(getCDetailPicture(), false); catalogManager.setCaption("Sideboard"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java index b2dd6b04847..c3a6b6f71dd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuest.java @@ -99,8 +99,8 @@ public final class CEditorQuest extends ACEditorBase { this.questData = questData0; - final CardManager catalogManager = new CardManager(false); - final CardManager deckManager = new CardManager(false); + final CardManager catalogManager = new CardManager(getCDetailPicture(), false); + final CardManager deckManager = new CardManager(getCDetailPicture(), false); catalogManager.setCaption("Quest Inventory"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java index 92f792e882c..0a55018a032 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorQuestCardShop.java @@ -99,8 +99,8 @@ public final class CEditorQuestCardShop extends ACEditorBase { this.cardPoolCondition = poolCondition; this.sectionMode = deckSection0; - CardManager catalogManager = new CardManager(true); - CardManager deckManager = new CardManager(true); + CardManager catalogManager = new CardManager(getCDetailPicture(), true); + CardManager deckManager = new CardManager(getCDetailPicture(), true); catalogManager.setCaption("Catalog"); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorWinstonProcess.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorWinstonProcess.java index 6ce705d0438..eb9a6a9bbf6 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorWinstonProcess.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CEditorWinstonProcess.java @@ -76,8 +76,8 @@ public class CEditorWinstonProcess extends ACEditorBase { public CEditorWinstonProcess() { super(FScreen.DRAFTING_PROCESS); - final CardManager catalogManager = new CardManager(false); - final CardManager deckManager = new CardManager(false); + final CardManager catalogManager = new CardManager(getCDetailPicture(), false); + final CardManager deckManager = new CardManager(getCDetailPicture(), false); //hide filters and options panel so more of pack is visible by default catalogManager.setHideViewOptions(1, true); diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java index 9e2ff2447b7..d5f819b996b 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CProbabilities.java @@ -32,6 +32,10 @@ public enum CProbabilities implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java index 008691894ec..5ef082b48c5 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/controllers/CStatistics.java @@ -41,6 +41,10 @@ public enum CStatistics implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/views/VAllDecks.java b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/views/VAllDecks.java index 15daaa4b454..a86e22e3055 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/deckeditor/views/VAllDecks.java +++ b/forge-gui-desktop/src/main/java/forge/screens/deckeditor/views/VAllDecks.java @@ -8,6 +8,7 @@ import forge.gui.framework.IVDoc; import forge.itemmanager.DeckManager; import forge.itemmanager.ItemManagerContainer; import forge.screens.deckeditor.controllers.CAllDecks; +import forge.screens.match.controllers.CDetailPicture; import net.miginfocom.swing.MigLayout; import javax.swing.*; @@ -25,12 +26,7 @@ public enum VAllDecks implements IVDoc { private DragCell parentCell; private final DragTab tab = new DragTab("All Decks"); - private final DeckManager lstDecks = new DeckManager(GameType.Constructed); - - //========== Constructor - private VAllDecks() { - lstDecks.setCaption("Decks"); - } + private DeckManager lstDecks; //========== Overridden methods @@ -91,4 +87,9 @@ public enum VAllDecks implements IVDoc { public DeckManager getLstDecks() { return lstDecks; } + + public void setCDetailPicture(final CDetailPicture cDetailPicture) { + this.lstDecks = new DeckManager(GameType.Constructed, cDetailPicture); + this.lstDecks.setCaption("Decks"); + } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/CHomeUI.java b/forge-gui-desktop/src/main/java/forge/screens/home/CHomeUI.java index baa7b3816b1..2d8644e40aa 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/CHomeUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/CHomeUI.java @@ -72,6 +72,10 @@ public enum CHomeUI implements ICDoc, IMenuProvider { return lblSelected; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.view.home.ICDoc#intialize() */ @@ -128,8 +132,7 @@ public enum CHomeUI implements ICDoc, IMenuProvider { private void selectPrevious() { EDocID selected = null; try { - selected = EDocID.valueOf(FModel - .getPreferences().getPref(FPref.SUBMENU_CURRENTMENU)); + selected = EDocID.valueOf(FModel.getPreferences().getPref(FPref.SUBMENU_CURRENTMENU)); } catch (final Exception e) { } if (selected != null && VHomeUI.SINGLETON_INSTANCE.getAllSubmenuLabels().get(selected) != null) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java index 2fb53fabcf8..e79ff7713e5 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletBuild.java @@ -83,6 +83,10 @@ public enum CSubmenuGauntletBuild implements ICDoc { }); } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.home.ICSubmenu#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletContests.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletContests.java index c2420b97afe..1d490b6eb0a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletContests.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletContests.java @@ -1,5 +1,6 @@ package forge.screens.home.gauntlet; +import forge.GuiBase; import forge.UiCommand; import forge.deck.Deck; import forge.game.GameType; @@ -8,7 +9,7 @@ import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; @@ -51,6 +52,10 @@ public enum CSubmenuGauntletContests implements ICDoc { }); } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.home.ICSubmenu#initialize() */ @@ -82,8 +87,7 @@ public enum CSubmenuGauntletContests implements ICDoc { if (gd.getUserDeck() != null) { userDeck = gd.getUserDeck(); - } - else { + } else { userDeck = view.getLstDecks().getPlayer().getDeck(); gd.setUserDeck(userDeck); } @@ -99,14 +103,15 @@ public enum CSubmenuGauntletContests implements ICDoc { } }); - Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - List starter = new ArrayList(); - - starter.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); - MatchUtil.startMatch(GameType.Gauntlet, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java index 7f408924a9d..55432c873a0 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletLoad.java @@ -1,5 +1,6 @@ package forge.screens.home.gauntlet; +import forge.GuiBase; import forge.UiCommand; import forge.deck.Deck; import forge.deck.DeckType; @@ -10,7 +11,7 @@ import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; @@ -56,6 +57,10 @@ public enum CSubmenuGauntletLoad implements ICDoc { }); } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.home.ICSubmenu#initialize() */ @@ -113,7 +118,7 @@ public enum CSubmenuGauntletLoad implements ICDoc { Deck userDeck = gd.getUserDeck(); if (userDeck == null) { //give user a chance to select a deck if none saved with gauntlet - userDeck = FDeckChooser.promptForDeck("Select a deck to play for this gauntlet", DeckType.CUSTOM_DECK, false); + userDeck = FDeckChooser.promptForDeck(null, "Select a deck to play for this gauntlet", DeckType.CUSTOM_DECK, false); if (userDeck == null) { return; } //prevent crash if user doesn't select a deck gd.setUserDeck(userDeck); GauntletIO.saveGauntlet(gd); @@ -129,11 +134,13 @@ public enum CSubmenuGauntletLoad implements ICDoc { } }); - List starter = new ArrayList(); - starter.add(new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(userDeck).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); - MatchUtil.startMatch(GameType.Gauntlet, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletQuick.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletQuick.java index acd8681a504..20418c2fe02 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletQuick.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/CSubmenuGauntletQuick.java @@ -1,5 +1,6 @@ package forge.screens.home.gauntlet; +import forge.GuiBase; import forge.UiCommand; import forge.deck.DeckType; import forge.game.GameType; @@ -8,7 +9,7 @@ import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletUtil; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.player.GamePlayerUtil; import javax.swing.*; @@ -44,6 +45,10 @@ public enum CSubmenuGauntletQuick implements ICDoc { }); } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.home.ICSubmenu#initialize() */ @@ -64,7 +69,7 @@ public enum CSubmenuGauntletQuick implements ICDoc { }); // Find appropriate filename for new save, create and set new save file. - List allowedDeckTypes = new ArrayList(); + final List allowedDeckTypes = new ArrayList(); if (view.getBoxColorDecks().isSelected()) { allowedDeckTypes.add(DeckType.COLOR_DECK); } if (view.getBoxThemeDecks().isSelected()) { allowedDeckTypes.add(DeckType.THEME_DECK); } if (view.getBoxUserDecks().isSelected()) { allowedDeckTypes.add(DeckType.CUSTOM_DECK); } @@ -73,11 +78,13 @@ public enum CSubmenuGauntletQuick implements ICDoc { final GauntletData gd = GauntletUtil.createQuickGauntlet(view.getLstDecks().getPlayer().getDeck(), view.getSliOpponents().getValue(), allowedDeckTypes); - List starter = new ArrayList(); - starter.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(new RegisteredPlayer(gd.getDecks().get(gd.getCompleted())).setPlayer(GamePlayerUtil.createAiPlayer())); - MatchUtil.startMatch(GameType.Gauntlet, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Gauntlet, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletBuild.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletBuild.java index df09f2f1661..2f0be94b883 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletBuild.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletBuild.java @@ -40,7 +40,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu { private final JPanel pnlStrut = new JPanel(); private final JPanel pnlDirections = new JPanel(); - private final FDeckChooser lstLeft = new FDeckChooser(false); + private final FDeckChooser lstLeft = new FDeckChooser(null, false); private final JList lstRight = new FList(); private final FScrollPane scrRight = new FScrollPane(lstRight, true, diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletContests.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletContests.java index 227f400ec17..91a29c4f336 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletContests.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/VSubmenuGauntletContests.java @@ -42,7 +42,7 @@ public enum VSubmenuGauntletContests implements IVSubmenu { private final JCheckBox boxColorDecks = new FCheckBox(DeckType.COLOR_DECK.toString()); private final JCheckBox boxThemeDecks = new FCheckBox(DeckType.THEME_DECK.toString()); - private final FDeckChooser lstDecks = new FDeckChooser(false); + private final FDeckChooser lstDecks = new FDeckChooser(null, false); private final FLabel lblOptions = new FLabel.Builder().fontSize(16) .fontStyle(Font.BOLD).text("OPTIONS").fontAlign(SwingConstants.CENTER).build(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/online/CSubmenuOnlineLobby.java b/forge-gui-desktop/src/main/java/forge/screens/home/online/CSubmenuOnlineLobby.java index d6a3d1a96b8..4b63f52fdc4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/online/CSubmenuOnlineLobby.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/online/CSubmenuOnlineLobby.java @@ -4,6 +4,7 @@ import forge.UiCommand; import forge.gui.framework.ICDoc; import forge.menus.IMenuProvider; import forge.menus.MenuUtil; + import javax.swing.*; import java.util.ArrayList; @@ -26,6 +27,10 @@ public enum CSubmenuOnlineLobby implements ICDoc, IMenuProvider { }); } + @Override + public void register() { + } + @Override public void initialize() { } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java index 2a12e6bf0a3..d71b63648c3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java @@ -32,6 +32,10 @@ public enum CSubmenuChallenges implements ICDoc { /** */ SINGLETON_INSTANCE; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java index d62ba3cb3d1..efb411b702c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java @@ -26,6 +26,10 @@ public enum CSubmenuDuels implements ICDoc { /** */ SINGLETON_INSTANCE; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java index 3a541ceefc8..122fc54fbb1 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java @@ -45,6 +45,10 @@ public enum CSubmenuQuestData implements ICDoc { private final UiCommand cmdQuestUpdate = new UiCommand() { @Override public void run() { update(); } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java index 0716077c3f1..95a4e87ff51 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java @@ -48,6 +48,10 @@ public enum CSubmenuQuestDecks implements ICDoc { } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java index 028fced2da4..de436e0431d 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java @@ -13,6 +13,7 @@ import forge.gui.GuiChoose; import forge.gui.framework.EDocID; import forge.gui.framework.FScreen; import forge.gui.framework.ICDoc; +import forge.interfaces.IGuiGame; import forge.item.BoosterPack; import forge.item.PaperCard; import forge.itemmanager.DeckManager; @@ -38,6 +39,7 @@ import forge.toolbox.FSkin.SkinImage; import forge.toolbox.JXButtonPanel; import javax.swing.*; + import java.awt.event.*; import java.text.DecimalFormat; import java.util.ArrayList; @@ -56,7 +58,12 @@ public enum CSubmenuQuestDraft implements ICDoc { private static final DecimalFormat NUMBER_FORMATTER = new DecimalFormat("#,###"); private boolean drafting = false; - + private IGuiGame gui = null; + + @Override + public void register() { + } + @SuppressWarnings("serial") @Override public void initialize() { @@ -333,7 +340,7 @@ public enum CSubmenuQuestDraft implements ICDoc { view.setMode(Mode.TOURNAMENT_ACTIVE); } - QuestDraftUtils.update(); + QuestDraftUtils.update(gui); switch (view.getMode()) { @@ -489,7 +496,7 @@ public enum CSubmenuQuestDraft implements ICDoc { } private void editDeck() { - VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft)); + VCurrentDeck.SINGLETON_INSTANCE.setItemManager(new DeckManager(GameType.Draft, null)); Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST_TOURNAMENT); CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorQuestLimited(FModel.getQuest())); FModel.getQuest().save(); @@ -549,15 +556,16 @@ public enum CSubmenuQuestDraft implements ICDoc { } private void startNextMatch() { - - String message = QuestDraftUtils.getDeckLegality(); - - if (message != null) { + + final String message = QuestDraftUtils.getDeckLegality(); + + if (message != null) { FOptionPane.showMessageDialog(message, "Deck Invalid"); return; } - - QuestDraftUtils.startNextMatch(); + + gui = GuiBase.getInterface().getNewGuiGame(); + QuestDraftUtils.startNextMatch(gui); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java index e992e62c8e4..c69c34106fb 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java @@ -18,6 +18,10 @@ public enum CSubmenuQuestPrefs implements ICDoc { /** */ SINGLETON_INSTANCE; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java index f574c89c2c3..2672705d696 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestDecks.java @@ -36,7 +36,7 @@ public enum VSubmenuQuestDecks implements IVSubmenu { /** */ private final LblHeader lblTitle = new LblHeader("Quest Decks"); - private final DeckManager lstDecks = new DeckManager(GameType.Quest); + private final DeckManager lstDecks = new DeckManager(GameType.Quest, null); private final FLabel lblInfo = new FLabel.Builder() .fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuConstructed.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuConstructed.java index b119feb8f88..f21670e1a0f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuConstructed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuConstructed.java @@ -1,5 +1,6 @@ package forge.screens.home.sanctioned; +import forge.GuiBase; import forge.LobbyPlayer; import forge.UiCommand; import forge.deck.CardPool; @@ -12,8 +13,9 @@ import forge.game.GameType; import forge.game.player.RegisteredPlayer; import forge.gui.GuiDialog; import forge.gui.framework.ICDoc; +import forge.interfaces.IGuiGame; import forge.item.PaperCard; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.menus.IMenuProvider; import forge.menus.MenuUtil; import forge.model.CardCollections; @@ -28,10 +30,13 @@ import forge.util.storage.IStorage; import javax.swing.*; +import com.beust.jcommander.internal.Maps; + import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.Vector; @@ -49,6 +54,10 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { private final VSubmenuConstructed view = VSubmenuConstructed.SINGLETON_INSTANCE; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.home.ICSubmenu#initialize() */ @@ -226,10 +235,13 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { } } - List players = new ArrayList(); + final List players = new ArrayList(); + final Map guis = Maps.newHashMap(); + final IGuiGame gui = GuiBase.getInterface().getNewGuiGame(); for (final int i : view.getParticipants()) { - String name = view.getPlayerName(i); - LobbyPlayer lobbyPlayer = view.isPlayerAI(i) + final String name = view.getPlayerName(i); + final boolean isAI = view.isPlayerAI(i); + final LobbyPlayer lobbyPlayer = isAI ? GamePlayerUtil.createAiPlayer(name, view.getPlayerAvatar(i), view.getAiOptions(i)) : GamePlayerUtil.getGuiPlayer(name, i); RegisteredPlayer rp = view.getDeckChooser(i).getPlayer(); @@ -237,25 +249,23 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { if (variantTypes.isEmpty()) { rp.setTeamNumber(view.getTeam(i)); players.add(rp.setPlayer(lobbyPlayer)); - } - else { + } else { Deck deck = null; PaperCard vanguardAvatar = null; if (isCommanderMatch) { - Object selected = view.getCommanderDeckLists().get(i).getSelectedValue(); + final Object selected = view.getCommanderDeckLists().get(i).getSelectedValue(); if (selected instanceof String) { - String sel = (String) selected; - IStorage comDecks = FModel.getDecks().getCommander(); + final String sel = (String) selected; + final IStorage comDecks = FModel.getDecks().getCommander(); if (sel.equals("Random") && comDecks.size() > 0) { deck = Aggregates.random(comDecks); } - } - else { + } else { deck = (Deck) selected; } GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : GameType.Commander; if (deck == null) { //Can be null if player deselects the list selection or chose Generate - deck = DeckgenUtil.generateCommanderDeck(view.isPlayerAI(i), commanderGameType); + deck = DeckgenUtil.generateCommanderDeck(isAI, commanderGameType); } if (checkLegality) { String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck); @@ -264,8 +274,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { return; } } - } - else if (autoGenerateVariant != null) { + } else if (autoGenerateVariant != null) { deck = autoGenerateVariant.autoGenerateDeck(rp); CardPool avatarPool = deck.get(DeckSection.Avatar); if (avatarPool != null) { @@ -276,7 +285,7 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { // Initialise variables for other variants deck = deck == null ? rp.getDeck() : deck; Iterable schemes = null; - boolean playerIsArchenemy = view.isPlayerArchenemy(i); + final boolean playerIsArchenemy = view.isPlayerArchenemy(i); Iterable planes = null; //Archenemy @@ -354,10 +363,10 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { if (sel.contains("Use deck's default avatar") && deck.has(DeckSection.Avatar)) { vanguardAvatar = deck.get(DeckSection.Avatar).get(0); } else { //Only other string is "Random" - if (!view.isPlayerAI(i)) { //Human - vanguardAvatar = Aggregates.random(view.getNonRandomHumanAvatars()); - } else { //AI + if (isAI) { //AI vanguardAvatar = Aggregates.random(view.getNonRandomAiAvatars()); + } else { //Human + vanguardAvatar = Aggregates.random(view.getNonRandomHumanAvatars()); } } } else { @@ -374,10 +383,15 @@ public enum CSubmenuConstructed implements ICDoc, IMenuProvider { rp.setTeamNumber(view.getTeam(i)); players.add(rp.setPlayer(lobbyPlayer)); } + + if (!isAI) { + guis.put(rp, gui); + } view.getDeckChooser(i).saveState(); } - MatchUtil.startMatch(GameType.Constructed, variantTypes, players); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Constructed, variantTypes, players, guis); } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuDraft.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuDraft.java index a7d19a32bd1..ee7dacfebe2 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuDraft.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuDraft.java @@ -1,5 +1,6 @@ package forge.screens.home.sanctioned; +import forge.GuiBase; import forge.UiCommand; import forge.Singletons; import forge.deck.Deck; @@ -14,7 +15,7 @@ import forge.gui.framework.ICDoc; import forge.itemmanager.ItemManagerConfig; import forge.limited.BoosterDraft; import forge.limited.LimitedPoolType; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.properties.ForgePreferences.FPref; @@ -47,6 +48,10 @@ public enum CSubmenuDraft implements ICDoc { } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ @@ -131,20 +136,22 @@ public enum CSubmenuDraft implements ICDoc { } }); - DeckGroup opponentDecks = FModel.getDecks().getDraft().get(humanDeck.getName()); - Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); + final DeckGroup opponentDecks = FModel.getDecks().getDraft().get(humanDeck.getName()); + final Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); if (aiDeck == null) { throw new IllegalStateException("Draft: Computer deck is null!"); } - List starter = new ArrayList(); - starter.add(new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); for (RegisteredPlayer pl : starter) { pl.assignConspiracies(); } - MatchUtil.startMatch(GameType.Draft, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Draft, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /** */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuSealed.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuSealed.java index 429e8bb2d6e..8ec54d5012e 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuSealed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuSealed.java @@ -40,6 +40,10 @@ public enum CSubmenuSealed implements ICDoc { } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuWinston.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuWinston.java index cbff51996c1..b758a7e4524 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuWinston.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/CSubmenuWinston.java @@ -1,5 +1,6 @@ package forge.screens.home.sanctioned; +import forge.GuiBase; import forge.UiCommand; import forge.Singletons; import forge.deck.Deck; @@ -8,7 +9,7 @@ import forge.game.GameType; import forge.game.player.RegisteredPlayer; import forge.gui.GuiChoose; import forge.gui.SOverlayUtils; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.screens.deckeditor.CDeckEditorUI; import forge.deck.DeckProxy; @@ -47,6 +48,10 @@ public enum CSubmenuWinston implements ICDoc { } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ @@ -122,17 +127,19 @@ public enum CSubmenuWinston implements ICDoc { } }); - DeckGroup opponentDecks = FModel.getDecks().getWinston().get(humanDeck.getName()); - Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); + final DeckGroup opponentDecks = FModel.getDecks().getWinston().get(humanDeck.getName()); + final Deck aiDeck = opponentDecks.getAiDecks().get(aiIndex); if (aiDeck == null) { throw new IllegalStateException("Draft: Computer deck is null!"); } - List starter = new ArrayList(); - starter.add(new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(humanDeck.getDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); - MatchUtil.startMatch(GameType.Winston, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Winston, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /** */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuConstructed.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuConstructed.java index 051335bb8a6..d5fa9e0e06a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuConstructed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuConstructed.java @@ -286,7 +286,7 @@ public enum VSubmenuConstructed implements IVSubmenu { String labelConstraints = "gaptop 10px, gapbottom 5px"; // Main deck - final FDeckChooser mainChooser = new FDeckChooser(isPlayerAI(playerIndex)); + final FDeckChooser mainChooser = new FDeckChooser(null, isPlayerAI(playerIndex)); mainChooser.initialize(); mainChooser.getLstDecks().setSelectCommand(new UiCommand() { @Override diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuDraft.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuDraft.java index 94a979acc2a..e79c8871285 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuDraft.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuDraft.java @@ -34,7 +34,7 @@ public enum VSubmenuDraft implements IVSubmenu { private final JPanel pnlStart = new JPanel(); private final StartButton btnStart = new StartButton(); - private final DeckManager lstDecks = new DeckManager(GameType.Draft); + private final DeckManager lstDecks = new DeckManager(GameType.Draft, null); private final JRadioButton radSingle = new FRadioButton("Play one opponent"); private final JRadioButton radAll = new FRadioButton("Play all 7 opponents"); @@ -66,7 +66,7 @@ public enum VSubmenuDraft implements IVSubmenu { lblTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); lstDecks.setCaption("Draft Decks"); - JXButtonPanel grpPanel = new JXButtonPanel(); + final JXButtonPanel grpPanel = new JXButtonPanel(); grpPanel.add(radSingle, "w 200px!, h 30px!"); grpPanel.add(radAll, "w 200px!, h 30px!"); radSingle.setSelected(true); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuSealed.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuSealed.java index 2fb2bf4310f..8d591270bc8 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuSealed.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuSealed.java @@ -44,7 +44,7 @@ public enum VSubmenuSealed implements IVSubmenu { private final LblHeader lblTitle = new LblHeader("Sanctioned Format: Sealed Deck"); private final StartButton btnStart = new StartButton(); - private final DeckManager lstDecks = new DeckManager(GameType.Sealed); + private final DeckManager lstDecks = new DeckManager(GameType.Sealed, null); private final FLabel lblInfo = new FLabel.Builder() .fontAlign(SwingConstants.LEFT).fontSize(16).fontStyle(Font.BOLD) diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuWinston.java b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuWinston.java index 480fe3cf123..dddb446964a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuWinston.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/sanctioned/VSubmenuWinston.java @@ -34,7 +34,7 @@ public enum VSubmenuWinston implements IVSubmenu { private final JPanel pnlStart = new JPanel(); private final StartButton btnStart = new StartButton(); - private final DeckManager lstDecks = new DeckManager(GameType.Winston); + private final DeckManager lstDecks = new DeckManager(GameType.Winston, null); private final JList lstAI = new FList(); private final JLabel lblInfo = new FLabel.Builder() diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAchievements.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAchievements.java index c02bdd2ef94..8a0bb991e41 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAchievements.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAchievements.java @@ -20,6 +20,10 @@ public enum CSubmenuAchievements implements ICDoc { public void initialize() { } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAvatars.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAvatars.java index 9f1f67df253..a75e28d38e6 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAvatars.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuAvatars.java @@ -13,6 +13,10 @@ public enum CSubmenuAvatars implements ICDoc { private final VSubmenuAvatars view = VSubmenuAvatars.SINGLETON_INSTANCE; + @Override + public void register() { + } + @Override public void initialize() { } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java index 371ecce6bd5..3e2da227460 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java @@ -40,6 +40,10 @@ public enum CSubmenuDownloaders implements ICDoc { public void run() { BugReporter.reportBug(null); } }; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java index 758cf786c66..e17aab4fb4f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java @@ -47,6 +47,10 @@ public enum CSubmenuPreferences implements ICDoc { private final List> lstControls = new ArrayList>(); + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ @@ -105,6 +109,7 @@ public enum CSubmenuPreferences implements ICDoc { lstControls.add(Pair.of(view.getCbCompactMainMenu(), FPref.UI_COMPACT_MAIN_MENU)); lstControls.add(Pair.of(view.getCbPromptFreeBlocks(), FPref.MATCHPREF_PROMPT_FREE_BLOCKS)); lstControls.add(Pair.of(view.getCbPauseWhileMinimized(), FPref.UI_PAUSE_WHILE_MINIMIZED)); + lstControls.add(Pair.of(view.getCbWorkshopSyntax(), FPref.DEV_WORKSHOP_SYNTAX)); lstControls.add(Pair.of(view.getCbCompactPrompt(), FPref.UI_COMPACT_PROMPT)); lstControls.add(Pair.of(view.getCbHideReminderText(), FPref.UI_HIDE_REMINDER_TEXT)); @@ -250,7 +255,7 @@ public enum CSubmenuPreferences implements ICDoc { "the Dock tab -> Save Layout option in the Match screen.\n\n" + "Reset layout?"; if (FOptionPane.showConfirmDialog(userPrompt, "Reset Match Screen Layout")) { - if (FScreen.MATCH_SCREEN.deleteLayoutFile()) { + if (FScreen.deleteMatchLayoutFile()) { FOptionPane.showMessageDialog("Match Screen layout has been reset."); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuReleaseNotes.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuReleaseNotes.java index 6878779b3e1..de1179b8adf 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuReleaseNotes.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuReleaseNotes.java @@ -37,6 +37,10 @@ public enum CSubmenuReleaseNotes implements ICDoc { //private ForgePreferences prefs; private boolean isReleaseNotesUpdated = false; + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#update() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java index b98e034c1cf..31670e671fd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java @@ -1,6 +1,27 @@ package forge.screens.home.settings; -import forge.Singletons; +import java.awt.Color; +import java.awt.Font; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; + +import org.apache.commons.lang3.StringUtils; + import forge.control.FControl.CloseAction; import forge.control.KeyboardShortcuts; import forge.control.KeyboardShortcuts.Shortcut; @@ -13,22 +34,13 @@ import forge.properties.ForgePreferences.FPref; import forge.screens.home.EMenuGroup; import forge.screens.home.IVSubmenu; import forge.screens.home.VHomeUI; -import forge.toolbox.*; +import forge.toolbox.FCheckBox; +import forge.toolbox.FComboBoxPanel; +import forge.toolbox.FLabel; +import forge.toolbox.FScrollPane; +import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedLabel; import forge.toolbox.FSkin.SkinnedTextField; -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; - -import java.awt.*; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.util.*; -import java.util.List; /** * Assembles Swing components of preferences submenu singleton. @@ -66,6 +78,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final JCheckBox cbManaBurn = new OptionsCheckBox("Mana Burn"); private final JCheckBox cbManaLostPrompt = new OptionsCheckBox("Prompt Mana Pool Emptying"); private final JCheckBox cbDevMode = new OptionsCheckBox("Developer Mode"); + private final JCheckBox cbWorkshopSyntax = new OptionsCheckBox("Workshop Syntax Checker"); private final JCheckBox cbEnforceDeckLegality = new OptionsCheckBox("Deck Conformance"); private final JCheckBox cbCloneImgSource = new OptionsCheckBox("Clones Use Original Card Art"); private final JCheckBox cbScaleLarger = new OptionsCheckBox("Scale Image Larger"); @@ -181,6 +194,9 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbDevMode, regularConstraints); pnlPrefs.add(new NoteLabel("Enables menu with functions for testing during development."), regularConstraints); + pnlPrefs.add(cbWorkshopSyntax, regularConstraints); + pnlPrefs.add(new NoteLabel("Enables syntax checking of card scripts in the Workshop. Note: functionality still in testing phase!"), regularConstraints); + pnlPrefs.add(cbpGameLogEntryType, "w 80%!, gap 10% 0 0 10px, span 2 1"); pnlPrefs.add(new NoteLabel("Changes how much information is displayed in the game log. Sorted by least to most verbose."), regularConstraints); @@ -240,7 +256,7 @@ public enum VSubmenuPreferences implements IVSubmenu { final JLabel lblShortcuts = new SectionLabel("Keyboard Shortcuts"); pnlPrefs.add(lblShortcuts, sectionConstraints + ", gaptop 2%"); - final List shortcuts = Singletons.getControl().getShortcuts(); + final List shortcuts = KeyboardShortcuts.getKeyboardShortcuts(); for (final Shortcut s : shortcuts) { pnlPrefs.add(new FLabel.Builder().text(s.getDescription()) @@ -486,6 +502,10 @@ public enum VSubmenuPreferences implements IVSubmenu { return cbDevMode; } + public JCheckBox getCbWorkshopSyntax() { + return cbWorkshopSyntax; + } + public FComboBoxPanel getAiProfilesComboBoxPanel() { return cbpAiProfiles; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 561e43854b8..6497cacef90 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -21,9 +21,13 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicReference; import javax.swing.JMenu; import javax.swing.JPopupMenu; @@ -32,21 +36,30 @@ import javax.swing.MenuElement; import javax.swing.MenuSelectionManager; import javax.swing.SwingUtilities; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; + import forge.FThreads; import forge.ImageCache; import forge.LobbyPlayer; import forge.Singletons; import forge.UiCommand; -import forge.game.Game; +import forge.assets.FSkinProp; +import forge.control.KeyboardShortcuts; +import forge.deck.CardPool; +import forge.deck.Deck; +import forge.deckchooser.FDeckViewer; +import forge.game.GameEntity; import forge.game.GameEntityView; import forge.game.GameView; -import forge.game.Match; import forge.game.card.CardView; import forge.game.combat.CombatView; import forge.game.phase.PhaseType; -import forge.game.player.Player; +import forge.game.player.DelayedReveal; +import forge.game.player.IHasIcon; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; @@ -62,33 +75,38 @@ import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SLayoutIO; import forge.interfaces.IButton; import forge.item.InventoryItem; -import forge.match.IMatchController; -import forge.match.MatchUtil; +import forge.item.PaperCard; +import forge.match.AbstractGuiGame; import forge.menus.IMenuProvider; import forge.model.FModel; +import forge.player.PlayerControllerHuman; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.screens.match.controllers.CAntes; import forge.screens.match.controllers.CCombat; -import forge.screens.match.controllers.CDetail; +import forge.screens.match.controllers.CDetailPicture; +import forge.screens.match.controllers.CDev; +import forge.screens.match.controllers.CDock; import forge.screens.match.controllers.CLog; -import forge.screens.match.controllers.CPicture; +import forge.screens.match.controllers.CPlayers; import forge.screens.match.controllers.CPrompt; import forge.screens.match.controllers.CStack; import forge.screens.match.menus.CMatchUIMenus; import forge.screens.match.views.VCommand; import forge.screens.match.views.VField; import forge.screens.match.views.VHand; -import forge.screens.match.views.VPlayers; -import forge.screens.match.views.VPrompt; import forge.toolbox.FButton; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; -import forge.toolbox.MouseTriggerEvent; import forge.toolbox.FSkin.SkinImage; +import forge.toolbox.MouseTriggerEvent; import forge.toolbox.special.PhaseIndicator; import forge.toolbox.special.PhaseLabel; +import forge.util.FCollectionView; import forge.util.ITriggerEvent; +import forge.util.gui.SGuiChoose; +import forge.util.gui.SOptionPane; +import forge.view.FView; import forge.view.arcane.CardPanel; import forge.view.arcane.FloatingCardArea; @@ -100,17 +118,119 @@ import forge.view.arcane.FloatingCardArea; * *

(C at beginning of class name denotes a control class.) */ -public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { - SINGLETON_INSTANCE; +public final class CMatchUI + extends AbstractGuiGame + implements ICDoc, IMenuProvider { - private List sortedPlayers; + private final FScreen screen; + + private FCollectionView sortedPlayers; + /** Players attached to this UI */ private VMatchUI view; private boolean allHands; private boolean showOverlay = true; private IVDoc selectedDocBeforeCombat; public final Map avatarImages = new HashMap(); - + private final CAntes cAntes = new CAntes(this); + private final CCombat cCombat = new CCombat(); + private final CDetailPicture cDetailPicture = new CDetailPicture(this); + private final CDev cDev = new CDev(this); + private final CDock cDock = new CDock(this); + private final CLog cLog = new CLog(this); + private final CPlayers cPlayers = new CPlayers(this); + private final CPrompt cPrompt = new CPrompt(this); + private final CStack cStack = new CStack(this); + private final TargetingOverlay targetingOverlay = new TargetingOverlay(this); + private final Map> myDocs; + + public CMatchUI() { + this.view = new VMatchUI(this); + this.screen = FScreen.getMatchScreen(this, view); + Singletons.getView().getLpnDocument().add(targetingOverlay.getPanel(), FView.TARGETING_LAYER); + targetingOverlay.getPanel().setSize(Singletons.getControl().getDisplaySize()); + this.myDocs = new EnumMap>(EDocID.class); + this.myDocs.put(EDocID.CARD_PICTURE, getCDetailPicture().getCPicture().getView()); + this.myDocs.put(EDocID.CARD_DETAIL, getCDetailPicture().getCDetail().getView()); + this.myDocs.put(EDocID.CARD_ANTES, getCAntes().getView()); + this.myDocs.put(EDocID.REPORT_MESSAGE, getCPrompt().getView()); + this.myDocs.put(EDocID.REPORT_STACK, getCStack().getView()); + this.myDocs.put(EDocID.REPORT_COMBAT, getCCombat().getView()); + this.myDocs.put(EDocID.REPORT_LOG, getCLog().getView()); + this.myDocs.put(EDocID.REPORT_PLAYERS, getCPlayers().getView()); + this.myDocs.put(EDocID.DEV_MODE, getCDev().getView()); + this.myDocs.put(EDocID.BUTTON_DOCK, getCDock().getView());; + } + + private void registerDocs() { + for (final Entry> doc : myDocs.entrySet()) { + doc.getKey().setDoc(doc.getValue()); + } + } + + public boolean isCurrentScreen() { + return Singletons.getControl().getCurrentScreen() == this.screen; + } + + private boolean isInGame() { + return getGameView() != null; + } + + @Override + public void setGameView(final GameView gameView) { + super.setGameView(gameView); + screen.setTabCaption(gameView.getTitle()); + } + + @Override + protected void updateCurrentPlayer(final PlayerView player) { + // No action necessary + } + + public CAntes getCAntes() { + return cAntes; + } + public CCombat getCCombat() { + return cCombat; + } + public CDetailPicture getCDetailPicture() { + return cDetailPicture; + } + public CDev getCDev() { + return cDev; + } + public CDock getCDock() { + return cDock; + } + public CLog getCLog() { + return cLog; + } + public CPlayers getCPlayers() { + return cPlayers; + } + public CPrompt getCPrompt() { + return cPrompt; + } + public CStack getCStack() { + return cStack; + } + public TargetingOverlay getTargetingOverlay() { + return targetingOverlay; + } + + /** + * View deck list. + */ + public void viewDeckList() { + if (!isInGame()) { + return; + } + final Deck deck = getGameView().getDeck(getCurrentPlayer().getLobbyPlayerName()); + if (deck != null) { + FDeckViewer.show(deck); + } + } + private SkinImage getPlayerAvatar(final PlayerView p, final int defaultIndex) { if (avatarImages.containsKey(p.getLobbyPlayerName())) { return ImageCache.getIcon(avatarImages.get(p.getLobbyPlayerName())); @@ -125,11 +245,10 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { view.getLblAvatar().getResizeTimer().start(); } - public void initMatch(final List sortedPlayers0, final boolean allHands0) { - sortedPlayers = sortedPlayers0; - allHands = allHands0; - view = VMatchUI.SINGLETON_INSTANCE; - // TODO fix for use with multiplayer + public void initMatch(final FCollectionView sortedPlayers, final FCollectionView myPlayers) { + this.sortedPlayers = sortedPlayers; + this.setLocalPlayers(myPlayers); + allHands = sortedPlayers.size() == getLocalPlayerCount(); final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(","); @@ -140,10 +259,15 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { for (final PlayerView p : sortedPlayers) { // A field must be initialized after it's instantiated, to update player info. // No player, no init. - VField f = new VField(EDocID.Fields[i], p); - VCommand c = new VCommand(EDocID.Commands[i], p); + final EDocID fieldDoc = EDocID.Fields[i]; + final VField f = new VField(this, fieldDoc, p); fields.add(f); + myDocs.put(fieldDoc, f); + + final EDocID commandDoc = EDocID.Commands[i]; + final VCommand c = new VCommand(this, commandDoc, p); commands.add(c); + myDocs.put(commandDoc, c); //setAvatar(f, new ImageIcon(FSkin.getAvatars().get())); setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0]))); @@ -152,24 +276,26 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { i++; } - // Replace old instances view.setCommandViews(commands); view.setFieldViews(fields); - VPlayers.SINGLETON_INSTANCE.init(sortedPlayers0); + getCPlayers().getView().init(this.sortedPlayers); initHandViews(); + registerDocs(); } - public void initHandViews() { + private void initHandViews() { final List hands = new ArrayList(); int i = 0; for (final PlayerView p : sortedPlayers) { - if (allHands || !p.isAI() || CardView.mayViewAny(p.getHand(), p)) { - VHand newHand = new VHand(EDocID.Hands[i], p); + if (allHands || isLocalPlayer(p) || CardView.mayViewAny(p.getHand(), getCurrentPlayer())) { + final EDocID doc = EDocID.Hands[i]; + final VHand newHand = new VHand(this, doc, p); newHand.getLayoutControl().initialize(); hands.add(newHand); + myDocs.put(doc, newHand); } i++; } @@ -187,23 +313,28 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } } - public void showMessage(final String s0) { - CPrompt.SINGLETON_INSTANCE.setMessage(s0); + public List getFieldViews() { + return view.getFieldViews(); + } + public VField getFieldViewFor(final PlayerView p) { + final int idx = getPlayerIndex(p); + return idx < 0 ? null : getFieldViews().get(idx); } - public VField getFieldViewFor(PlayerView p) { - int idx = getPlayerIndex(p); - return idx < 0 ? null :view.getFieldViews().get(idx); + public List getCommandViews() { + return view.getCommandViews(); + } + public VCommand getCommandFor(final PlayerView p) { + final int idx = getPlayerIndex(p); + return idx < 0 ? null : getCommandViews().get(idx); } - public VCommand getCommandFor(PlayerView p) { - int idx = getPlayerIndex(p); - return idx < 0 ? null :view.getCommandViews().get(idx); + public List getHandViews() { + return view.getHands(); } - - public VHand getHandFor(PlayerView p) { - int idx = getPlayerIndex(p); - List allHands = view.getHands(); + public VHand getHandFor(final PlayerView p) { + final int idx = getPlayerIndex(p); + final List allHands = getHandViews(); return idx < 0 || idx >= allHands.size() ? null : allHands.get(idx); } @@ -215,26 +346,25 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { * @param phase   {@link java.lang.String} * @return boolean */ + @Override public final boolean stopAtPhase(final PlayerView turn, final PhaseType phase) { - VField vf = getFieldViewFor(turn); - PhaseLabel label = vf.getPhaseIndicator() - .getLabelFor(phase); + final VField vf = getFieldViewFor(turn); + final PhaseLabel label = vf.getPhaseIndicator() .getLabelFor(phase); return label == null || label.getEnabled(); } + @Override public void setCard(final CardView c) { this.setCard(c, false); } public void setCard(final CardView c, final boolean isInAltState) { FThreads.assertExecutedByEdt(true); - CDetail.SINGLETON_INSTANCE.showCard(c, isInAltState); - CPicture.SINGLETON_INSTANCE.showCard(c, isInAltState); + cDetailPicture.showCard(c, isInAltState); } - public void setCard(final InventoryItem c) { - CDetail.SINGLETON_INSTANCE.showCard(c); - CPicture.SINGLETON_INSTANCE.showImage(c); + public void setCard(final InventoryItem item) { + cDetailPicture.showItem(item); } private int getPlayerIndex(PlayerView player) { @@ -243,8 +373,8 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void showCombat() { - CombatView combat = MatchUtil.getGameView().getCombat(); - if (combat != null && combat.getNumAttackers() > 0 && MatchUtil.getGameView().peekStack() == null) { + final CombatView combat = getGameView().getCombat(); + if (combat != null && combat.getNumAttackers() > 0 && getGameView().peekStack() == null) { if (selectedDocBeforeCombat == null) { IVDoc combatDoc = EDocID.REPORT_COMBAT.getDoc(); if (combatDoc.getParentCell() != null) { @@ -262,22 +392,22 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { SDisplayUtil.showTab(selectedDocBeforeCombat); selectedDocBeforeCombat = null; } - CCombat.SINGLETON_INSTANCE.setModel(combat); - CCombat.SINGLETON_INSTANCE.update(); + getCCombat().setModel(combat); + getCCombat().update(); } // showCombat(CombatView) - public void updateZones(List> zonesToUpdate) { - //System.out.println("updateZones " + zonesToUpdate); - for (Pair kv : zonesToUpdate) { - PlayerView owner = kv.getKey(); - ZoneType zt = kv.getValue(); + @Override + public void updateZones(final List> zonesToUpdate) { + for (final Pair kv : zonesToUpdate) { + final PlayerView owner = kv.getKey(); + final ZoneType zt = kv.getValue(); switch (zt) { case Battlefield: getFieldViewFor(owner).getTabletop().setupPlayZone(); break; case Hand: - VHand vHand = getHandFor(owner); + final VHand vHand = getHandFor(owner); if (vHand != null) { vHand.getLayoutControl().updateHand(); } @@ -288,7 +418,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { getCommandFor(owner).getTabletop().setupPlayZone(); break; case Ante: - CAntes.SINGLETON_INSTANCE.update(); + cAntes.update(); break; default: final VField vf = getFieldViewFor(owner); @@ -302,6 +432,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } // Player's mana pool changes + @Override public void updateManaPool(final Iterable manaPoolUpdate) { for (final PlayerView p : manaPoolUpdate) { getFieldViewFor(p).getDetailsPanel().updateManaPool(); @@ -310,19 +441,21 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } // Player's lives and poison counters + @Override public void updateLives(final Iterable livesUpdate) { for (final PlayerView p : livesUpdate) { getFieldViewFor(p).updateDetails(); } } + @Override public void updateSingleCard(final CardView c) { - ZoneType zone = c.getZone(); + final ZoneType zone = c.getZone(); if (zone == null) { return; } switch (zone) { case Battlefield: - VField battlefield = getFieldViewFor(c.getController()); + final VField battlefield = getFieldViewFor(c.getController()); if (battlefield != null) { battlefield.getTabletop().updateCard(c, false); } @@ -337,7 +470,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } break; case Command: - VCommand command = getCommandFor(c.getController()); + final VCommand command = getCommandFor(c.getController()); if (command != null) { command.getTabletop().updateCard(c, false); } @@ -347,15 +480,9 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } } - public void refreshCardDetails(final Iterable cards) { - for (final CardView c : cards) { - updateSingleCard(c); - } - } - @Override public List getMenus() { - return new CMatchUIMenus().getMenus(); + return new CMatchUIMenus(this).getMenus(cDev); } @Override @@ -364,28 +491,42 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { } @Override - public void initialize() { - Singletons.getControl().getForgeMenu().setProvider(this); + public void register() { + initHandViews(); + registerDocs(); } @Override - public void update() { } + public void initialize() { + Singletons.getControl().getForgeMenu().setProvider(this); + updatePlayerControl(); + KeyboardShortcuts.attachKeyboardShortcuts(this); + for (final IVDoc view : myDocs.values()) { + final ICDoc layoutControl = view.getLayoutControl(); + layoutControl.initialize(); + layoutControl.update(); + } + } + + @Override + public void update() { + } public void repaintCardOverlays() { - List panels = getVisibleCardPanels(); - for (CardPanel panel : panels) { + final List panels = getVisibleCardPanels(); + for (final CardPanel panel : panels) { panel.repaintOverlays(); } } private List getVisibleCardPanels() { - List panels = new ArrayList(); - for (VHand h : view.getHands()) { + final List panels = new ArrayList(); + for (final VHand h : view.getHands()) { panels.addAll(h.getHandArea().getCardPanels()); } - for (VField f : view.getFieldViews()) { + for (final VField f : view.getFieldViews()) { panels.addAll(f.getTabletop().getCardPanels()); } - for (VCommand c : view.getCommandViews()) { + for (final VCommand c : view.getCommandViews()) { panels.addAll(c.getTabletop().getCardPanels()); } return panels; @@ -393,28 +534,17 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public boolean resetForNewGame() { - if (MatchUtil.getGame() != null) { - Singletons.getControl().setCurrentScreen(FScreen.MATCH_SCREEN); - SOverlayUtils.hideOverlay(); - FOptionPane.showMessageDialog("Cannot start a new game while another game is already in progress."); - return false; //TODO: See if it's possible to run multiple games at once without crashing - } return true; } @Override - public boolean hotSeatMode() { - return true; //Desktop game only supports hot seat mode for Human v. Human + public IButton getBtnOK(final PlayerView playerView) { + return view.getBtnOK(); } @Override - public IButton getBtnOK(PlayerView playerView) { - return VMatchUI.SINGLETON_INSTANCE.getBtnOK(); - } - - @Override - public IButton getBtnCancel(PlayerView playerView) { - return VMatchUI.SINGLETON_INSTANCE.getBtnCancel(); + public IButton getBtnCancel(final PlayerView playerView) { + return view.getBtnCancel(); } @Override @@ -432,18 +562,16 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void flashIncorrectAction() { - SDisplayUtil.remind(VPrompt.SINGLETON_INSTANCE); + SDisplayUtil.remind(getCPrompt().getView()); } @Override public void updatePhase() { - GameView gameView = MatchUtil.getGameView(); - final PlayerView p = gameView.getPlayerTurn(); - final PhaseType ph = gameView.getPhase(); - final CMatchUI matchUi = CMatchUI.SINGLETON_INSTANCE; - PhaseLabel lbl = matchUi.getFieldViewFor(p).getPhaseIndicator().getLabelFor(ph); + final PlayerView p = getGameView().getPlayerTurn(); + final PhaseType ph = getGameView().getPhase(); + PhaseLabel lbl = getFieldViewFor(p).getPhaseIndicator().getLabelFor(ph); - matchUi.resetAllPhaseButtons(); + resetAllPhaseButtons(); if (lbl != null) { lbl.setActive(true); } @@ -451,18 +579,18 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void updateTurn(final PlayerView player) { - VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player); + VField nextField = getFieldViewFor(player); SDisplayUtil.showTab(nextField); - CPrompt.SINGLETON_INSTANCE.updateText(); - CMatchUI.SINGLETON_INSTANCE.repaintCardOverlays(); + cPrompt.updateText(); + repaintCardOverlays(); } @Override public void updatePlayerControl() { - CMatchUI.SINGLETON_INSTANCE.initHandViews(); + initHandViews(); SLayoutIO.loadLayout(null); - VMatchUI.SINGLETON_INSTANCE.populate(); - for (VHand h : VMatchUI.SINGLETON_INSTANCE.getHands()) { + view.populate(); + for (final VHand h : getHandViews()) { h.getLayoutControl().updateHand(); } } @@ -480,7 +608,9 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void finishGame() { FloatingCardArea.closeAll(); //ensure floating card areas cleared and closed after the game - new ViewWinLose(MatchUtil.getGameView()); + if (hasLocalPlayers() || getGameView().isMatchOver()) { + new ViewWinLose(getGameView(), this); + } if (showOverlay) { SOverlayUtils.showOverlay(); } @@ -488,12 +618,38 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void updateStack() { - CStack.SINGLETON_INSTANCE.update(); + getCStack().update(); } + /** + * Clear all visually highlighted card panels on the battlefield. + */ + public void clearPanelSelections() { + final List fields = view.getFieldViews(); + for (final VField field : fields) { + for (final CardPanel p : field.getTabletop().getCardPanels()) { + p.setSelected(false); + } + } + } + + /** + * Highlight a card on the playfield. + * + * @param card + * a card to be highlighted + */ @Override - public void setPanelSelection(final CardView c) { - GuiUtils.setPanelSelection(c); + public void setPanelSelection(final CardView card) { + for (final VField v : view.getFieldViews()) { + final List panels = v.getTabletop().getCardPanels(); + for (final CardPanel p : panels) { + if (p.getCard().equals(card)) { + p.setSelected(true); + return; + } + } + } } @Override @@ -534,7 +690,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { new Runnable() { @Override public void run() { - CPrompt.SINGLETON_INSTANCE.selectAbility(ab); + cPrompt.selectAbility(ab); } }, enabled); if (shortcut > 0) { @@ -559,7 +715,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { @Override public void showPromptMessage(final PlayerView playerView, final String message) { - CMatchUI.SINGLETON_INSTANCE.showMessage(message); + cPrompt.setMessage(message); } public Object showManaPool(final PlayerView player) { @@ -571,6 +727,121 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { //not needed since mana pool icons are always visible } + @Override + public Map assignDamage(final CardView attacker, + final List blockers, final int damage, + final GameEntityView defender, final boolean overrideOrder) { + if (damage <= 0) { + return Collections.emptyMap(); + } + + // If the first blocker can absorb all of the damage, don't show the Assign Damage dialog + final CardView firstBlocker = blockers.get(0); + if (!overrideOrder && !attacker.getCurrentState().hasDeathtouch() && firstBlocker.getLethalDamage() >= damage) { + return ImmutableMap.of(firstBlocker, damage); + } + + final AtomicReference> result = new AtomicReference>(); + FThreads.invokeInEdtAndWait(new Runnable() { + @Override + public void run() { + final VAssignDamage v = new VAssignDamage(CMatchUI.this, attacker, blockers, damage, defender, overrideOrder); + result.set(v.getDamageMap()); + }}); + return result.get(); + } + + @Override + public void hear(LobbyPlayer player, String message) { + FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message); + } + + @Override + public void openView(final FCollectionView myPlayers) { + getGameView().getGameLog().addObserver(getCLog()); + + initMatch(getGameView().getPlayers(), myPlayers); + + actuateMatchPreferences(); + + Singletons.getControl().setCurrentScreen(screen); + SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); + + // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch + //Set Field shown to current player. + //if (util.getHumanCount() > 0) { + final VField nextField = getFieldViewFor(getGameView().getPlayers().get(0)); + SDisplayUtil.showTab(nextField); + //} + SOverlayUtils.hideOverlay(); + } + + @Override + public void afterGameEnd() { + Singletons.getView().getNavigationBar().closeTab(screen); + } + + @Override + public int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { + return FOptionPane.showOptionDialog(message, title, icon == null ? null : FSkin.getImage(icon), options, defaultOption); + } + + @Override + public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp skinIcon, final String[] options, final int defaultOption) { + if (card != null) { + setCard(card); + } + return showOptionDialog(message, title, skinIcon, options, defaultOption); + } + + @Override + public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { + return FOptionPane.showInputDialog(message, title, icon == null ? null : FSkin.getImage(icon), initialInput, inputOptions); + } + + @Override + public List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display) { + /*if ((choices != null && !choices.isEmpty() && choices.iterator().next() instanceof GameObject) || selected instanceof GameObject) { + System.err.println("Warning: GameObject passed to GUI! Printing stack trace."); + Thread.dumpStack(); + }*/ + return GuiChoose.getChoices(message, min, max, choices, selected, display); + } + + @Override + public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, + final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { + /*if ((sourceChoices != null && !sourceChoices.isEmpty() && sourceChoices.iterator().next() instanceof GameObject) + || (destChoices != null && !destChoices.isEmpty() && destChoices.iterator().next() instanceof GameObject)) { + System.err.println("Warning: GameObject passed to GUI! Printing stack trace."); + Thread.dumpStack(); + }*/ + return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode); + } + + @Override + public List sideboard(final CardPool sideboard, final CardPool main) { + return GuiChoose.sideboard(this, sideboard.toFlatList(), main.toFlatList()); + } + + @Override + public GameEntityView chooseSingleEntityForEffect(final String title, final FCollectionView optionList, final DelayedReveal delayedReveal, final boolean isOptional, final PlayerControllerHuman controller) { + if (delayedReveal != null) { + delayedReveal.reveal(controller); //TODO: Merge this into search dialog + } + controller.tempShow(optionList); + final List gameEntityViews = GameEntityView.getEntityCollection(optionList); + if (isOptional) { + return oneOrNone(title, gameEntityViews); + } + return one(title, gameEntityViews); + } + + @Override + public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) { + avatarImages.put(player.getName(), ihi.getIconImageKey()); + } + @Override public boolean openZones(final Collection zones, final Map players) { if (zones.size() == 1) { @@ -589,66 +860,10 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { public void restoreOldZones(final Map playersToRestoreZonesFor) { } - @SuppressWarnings("unchecked") @Override - public Map assignDamage(final CardView attacker, - final List blockers, final int damage, - final GameEntityView defender, final boolean overrideOrder) { - final Object[] result = { null }; // how else can I extract a value from EDT thread? - FThreads.invokeInEdtAndWait(new Runnable() { - @Override - public void run() { - VAssignDamage v = new VAssignDamage(attacker, blockers, damage, defender, overrideOrder); - result[0] = v.getDamageMap(); - }}); - return (Map)result[0]; - } - - @Override - public void hear(LobbyPlayer player, String message) { - FNetOverlay.SINGLETON_INSTANCE.addMessage(player.getName(), message); - } - - @Override - public void startNewMatch(final Match match) { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - MatchUtil.startGame(match); - } - }); - } - - @Override - public void openView(List sortedPlayers) { - Game game = MatchUtil.getGame(); - game.getGameLog().addObserver(CLog.SINGLETON_INSTANCE); - - List sortedPlayerViews = new ArrayList(); - for (Player p : sortedPlayers) { - sortedPlayerViews.add(PlayerView.get(p)); - } - CMatchUI.SINGLETON_INSTANCE.initMatch(sortedPlayerViews, MatchUtil.getHumanCount() != 1); - - actuateMatchPreferences(); - - Singletons.getControl().setCurrentScreen(FScreen.MATCH_SCREEN); - SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc()); - - // per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch - //Set Field shown to current player. - if (MatchUtil.getHumanCount() > 0) { - final VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(sortedPlayerViews.get(0)); - SDisplayUtil.showTab(nextField); - } - SOverlayUtils.hideOverlay(); - } - - @Override - public void afterGameEnd() { - Singletons.getView().getNavigationBar().closeTab(FScreen.MATCH_SCREEN); + public boolean isUiSetToSkipPhase(final PlayerView playerTurn, final PhaseType phase) { + final PhaseLabel label = getFieldViewFor(playerTurn).getPhaseIndicator().getLabelFor(phase); + return label != null && !label.getEnabled(); } /** @@ -656,7 +871,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { */ public void writeMatchPreferences() { final ForgePreferences prefs = FModel.getPreferences(); - final List fieldViews = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); + final List fieldViews = getFieldViews(); // AI field is at index [1] PhaseIndicator fvAi = fieldViews.get(1).getPhaseIndicator(); @@ -696,7 +911,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { */ private void actuateMatchPreferences() { final ForgePreferences prefs = FModel.getPreferences(); - final List fieldViews = VMatchUI.SINGLETON_INSTANCE.getFieldViews(); + final List fieldViews = getFieldViews(); // Human field is at index [0] PhaseIndicator fvHuman = fieldViews.get(0).getPhaseIndicator(); @@ -732,4 +947,31 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController { //Singletons.getView().getViewMatch().setLayoutParams(prefs.getPref(FPref.UI_LAYOUT_PARAMS)); } + + @Override + public void message(String message, String title) { + SOptionPane.showMessageDialog(message, title); + } + + @Override + public void showErrorDialog(String message, String title) { + SOptionPane.showErrorDialog(message, title); + } + + @Override + public boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) { + final String title = c == null ? "Question" : c + " - Ability"; + final String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question; + final String[] opts = options == null ? SGuiChoose.defaultConfirmOptions : options; + final int reply = FOptionPane.showOptionDialog(questionToUse, title, FOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1); + return reply == 0; + } + + @Override + public boolean showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final boolean defaultYes) { + final String[] options = {yesButtonText, noButtonText}; + final int reply = SOptionPane.showOptionDialog(message, title, SOptionPane.QUESTION_ICON, options, defaultYes ? 0 : 1); + return reply == 0; + } + } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ControlWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/ControlWinLose.java index 6c04527166a..95e7fc47afb 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/ControlWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/ControlWinLose.java @@ -9,7 +9,8 @@ import forge.Singletons; import forge.game.GameView; import forge.gui.SOverlayUtils; import forge.gui.framework.FScreen; -import forge.match.MatchUtil; +import forge.interfaces.IGameController; +import forge.match.NextGameDecision; /** * Default controller for a ViewWinLose object. This class can @@ -20,12 +21,14 @@ import forge.match.MatchUtil; public class ControlWinLose { private final ViewWinLose view; protected final GameView lastGame; + protected final CMatchUI matchUI; /** @param v   ViewWinLose * @param match */ - public ControlWinLose(final ViewWinLose v, final GameView game0) { + public ControlWinLose(final ViewWinLose v, final GameView game0, final CMatchUI matchUI) { this.view = v; this.lastGame = game0; + this.matchUI = matchUI; addListeners(); } @@ -58,21 +61,27 @@ public class ControlWinLose { public void actionOnContinue() { SOverlayUtils.hideOverlay(); saveOptions(); - MatchUtil.continueMatch(); + for (final IGameController controller : matchUI.getGameControllers()) { + controller.nextGameDecision(NextGameDecision.CONTINUE); + } } /** Action performed when "restart" button is pressed in default win/lose UI. */ public void actionOnRestart() { SOverlayUtils.hideOverlay(); saveOptions(); - MatchUtil.restartMatch(); + for (final IGameController controller : matchUI.getGameControllers()) { + controller.nextGameDecision(NextGameDecision.NEW); + } } /** Action performed when "quit" button is pressed in default win/lose UI. */ public void actionOnQuit() { // Reset other stuff saveOptions(); - MatchUtil.endCurrentGame(); + for (final IGameController controller : matchUI.getGameControllers()) { + controller.nextGameDecision(NextGameDecision.QUIT); + } Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN); SOverlayUtils.hideOverlay(); } @@ -82,7 +91,7 @@ public class ControlWinLose { * with other game modes. */ public void saveOptions() { - CMatchUI.SINGLETON_INSTANCE.writeMatchPreferences(); + matchUI.writeMatchPreferences(); } /** diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java index 79f74faf452..df53c4f984b 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/GauntletWinLose.java @@ -45,8 +45,8 @@ public class GauntletWinLose extends ControlWinLose { * @param view0 ViewWinLose object * @param match */ - public GauntletWinLose(final ViewWinLose view0, final GameView game0) { - super(view0, game0); + public GauntletWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) { + super(view0, game0, matchUI); controller = new GauntletWinLoseController(view0, game0) { @Override protected void showOutcome(String message1, String message2, FSkinProp icon, List lstEventNames, List lstEventRecords, int len, int num) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java index 4cd23a44dc6..561435bab03 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/LimitedWinLose.java @@ -46,8 +46,8 @@ public class LimitedWinLose extends ControlWinLose { * @param view0 {@link forge.screens.match.ViewWinLose} * @param match {@link forge.game.Match} */ - public LimitedWinLose(final ViewWinLose view0, final GameView game0) { - super(view0, game0); + public LimitedWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) { + super(view0, game0, matchUI); controller = new LimitedWinLoseController(view0, game0) { @Override protected void showOutcome(Runnable runnable) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java index 62d86d3fa73..90f6755f308 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java @@ -18,6 +18,7 @@ package forge.screens.match; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; + import forge.LobbyPlayer; import forge.Singletons; import forge.assets.FSkinProp; @@ -25,7 +26,7 @@ import forge.game.GameView; import forge.game.player.PlayerView; import forge.gui.SOverlayUtils; import forge.gui.framework.FScreen; -import forge.match.MatchUtil; +import forge.match.NextGameDecision; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.quest.QuestController; @@ -48,7 +49,6 @@ import forge.toolbox.FSkin; */ public class QuestDraftWinLose extends ControlWinLose { private final transient ViewWinLose view; - private final transient QuestController qData; /** @@ -57,8 +57,8 @@ public class QuestDraftWinLose extends ControlWinLose { * @param view0 ViewWinLose object * @param match2 */ - public QuestDraftWinLose(final ViewWinLose view0, final GameView game0) { - super(view0, game0); + public QuestDraftWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) { + super(view0, game0, matchUI); this.view = view0; qData = FModel.getQuest(); } @@ -97,11 +97,11 @@ public class QuestDraftWinLose extends ControlWinLose { if (lastGame.isMatchOver()) { this.actionOnQuitMatch(); QuestDraftUtils.matchInProgress = false; - QuestDraftUtils.update(); + QuestDraftUtils.update(matchUI); } else { this.actionOnContinue(); - QuestDraftUtils.update(); + QuestDraftUtils.update(matchUI); } return false; } @@ -113,21 +113,20 @@ public class QuestDraftWinLose extends ControlWinLose { view.getBtnQuit().setEnabled(true); view.getBtnContinue().setEnabled(false); view.getBtnQuit().setText("Continue Tournament"); - for (ActionListener listener : view.getBtnQuit().getActionListeners()) { + for (final ActionListener listener : view.getBtnQuit().getActionListeners()) { view.getBtnQuit().removeActionListener(listener); } view.getBtnQuit().addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { - MatchUtil.endCurrentGame(); + matchUI.getGameController().nextGameDecision(NextGameDecision.CONTINUE); QuestDraftUtils.matchInProgress = false; - QuestDraftUtils.continueMatches(); + QuestDraftUtils.continueMatches(matchUI); } }); - } - else { + } else { view.getBtnQuit().setEnabled(true); - for (ActionListener listener : view.getBtnQuit().getActionListeners()) { + for (final ActionListener listener : view.getBtnQuit().getActionListeners()) { view.getBtnQuit().removeActionListener(listener); } view.getBtnQuit().setText("Forfeit Tournament"); @@ -135,9 +134,9 @@ public class QuestDraftWinLose extends ControlWinLose { @Override public void actionPerformed(final ActionEvent e) { if (FOptionPane.showOptionDialog("Quitting the match now will forfeit the tournament!\n\nReally quit?", "Really Quit Tournament?", FSkin.getImage(FSkinProp.ICO_WARNING).scale(2), new String[] { "Yes", "No" }, 1) == 0) { - MatchUtil.endCurrentGame(); + matchUI.getGameController().nextGameDecision(NextGameDecision.QUIT); QuestDraftUtils.matchInProgress = false; - QuestDraftUtils.continueMatches(); + QuestDraftUtils.continueMatches(matchUI); } } }); @@ -156,9 +155,8 @@ public class QuestDraftWinLose extends ControlWinLose { qData.setCurrentEvent(null); qData.save(); FModel.getQuestPreferences().save(); - CMatchUI.SINGLETON_INSTANCE.writeMatchPreferences(); + matchUI.writeMatchPreferences(); - MatchUtil.endCurrentGame(); Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN); SOverlayUtils.hideOverlay(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java index a172960b668..cb8349d6a41 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/QuestWinLose.java @@ -39,8 +39,8 @@ public class QuestWinLose extends ControlWinLose { * @param view0 ViewWinLose object * @param match2 */ - public QuestWinLose(final ViewWinLose view0, final GameView game0) { - super(view0, game0); + public QuestWinLose(final ViewWinLose view0, final GameView game0, final CMatchUI matchUI) { + super(view0, game0, matchUI); controller = new QuestWinLoseController(game0, view0); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java b/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java index 7e2b5ec3374..74dcef0ad06 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/TargetingOverlay.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.swing.JPanel; @@ -40,11 +41,8 @@ import forge.game.card.CardView; import forge.game.combat.CombatView; import forge.game.player.PlayerView; import forge.game.spellability.StackItemView; -import forge.gui.framework.FScreen; -import forge.match.MatchUtil; -import forge.screens.match.controllers.CDock; +import forge.screens.match.controllers.CDock.ArcState; import forge.screens.match.views.VField; -import forge.screens.match.views.VStack; import forge.screens.match.views.VStack.StackInstanceTextArea; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedPanel; @@ -56,9 +54,8 @@ import forge.view.arcane.CardPanel; * */ @SuppressWarnings("serial") -public enum TargetingOverlay { - SINGLETON_INSTANCE; - +public class TargetingOverlay { + private final CMatchUI matchUI; private final OverlayPanel pnl = new OverlayPanel(); private final List cardPanels = new ArrayList(); private final List arcsFoe = new ArrayList(); @@ -67,7 +64,7 @@ public enum TargetingOverlay { private static class Arc { private final int x1, y1, x2, y2; - private Arc(Point end, Point start) { + private Arc(final Point end, final Point start) { x1 = start.x; y1 = start.y; x2 = end.x; @@ -75,15 +72,16 @@ public enum TargetingOverlay { } } - private HashSet cardsVisualized = new HashSet(); + private final Set cardsVisualized = new HashSet(); private CardPanel activePanel = null; /** * Semi-transparent overlay panel. Should be used with layered panes. */ - private TargetingOverlay() { + public TargetingOverlay(final CMatchUI matchUI) { + this.matchUI = matchUI; pnl.setOpaque(false); - pnl.setVisible(false); + pnl.setVisible(true); pnl.setFocusTraversalKeysEnabled(false); pnl.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA)); } @@ -103,18 +101,18 @@ public enum TargetingOverlay { cardPanels.clear(); cardsVisualized.clear(); - StackInstanceTextArea activeStackItem = VStack.SINGLETON_INSTANCE.getHoveredItem(); + final StackInstanceTextArea activeStackItem = matchUI.getCStack().getView().getHoveredItem(); - switch (CDock.SINGLETON_INSTANCE.getArcState()) { - case 0: + switch (matchUI.getCDock().getArcState()) { + case OFF: return; - case 1: + case MOUSEOVER: // Draw only hovered card activePanel = null; - for (VField f : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { + for (final VField f : matchUI.getFieldViews()) { cardPanels.addAll(f.getTabletop().getCardPanels()); - List cPanels = f.getTabletop().getCardPanels(); - for (CardPanel c : cPanels) { + final List cPanels = f.getTabletop().getCardPanels(); + for (final CardPanel c : cPanels) { if (c.isSelected()) { activePanel = c; break; @@ -123,9 +121,9 @@ public enum TargetingOverlay { } if (activePanel == null && activeStackItem == null) { return; } break; - default: + case ON: // Draw all - for (VField f : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) { + for (final VField f : matchUI.getFieldViews()) { cardPanels.addAll(f.getTabletop().getCardPanels()); } } @@ -147,7 +145,7 @@ public enum TargetingOverlay { } } - if (CDock.SINGLETON_INSTANCE.getArcState() == 1) { + if (matchUI.getCDock().getArcState() == ArcState.MOUSEOVER) { // Only work with the active panel if (activePanel != null) { addArcsForCard(activePanel.getCard(), endpoints, combat); @@ -185,9 +183,9 @@ public enum TargetingOverlay { } } - private Point getPlayerTargetingArrowPoint(PlayerView p, Point locOnScreen) { - JPanel avatarArea = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(p).getAvatarArea(); - Point point = avatarArea.getLocationOnScreen(); + private Point getPlayerTargetingArrowPoint(final PlayerView p, final Point locOnScreen) { + final JPanel avatarArea = matchUI.getFieldViewFor(p).getAvatarArea(); + final Point point = avatarArea.getLocationOnScreen(); point.x += avatarArea.getWidth() / 2 - locOnScreen.x; point.y += avatarArea.getHeight() / 2 - locOnScreen.y; return point; @@ -350,7 +348,7 @@ public enum TargetingOverlay { g2d.setTransform(af); } - public void drawArcs(Graphics2D g2d, Color color, List arcs) { + private void drawArcs(Graphics2D g2d, Color color, List arcs) { for (Arc arc : arcs) { drawArrow(g2d, arc.x1, arc.y1, arc.x2, arc.y2, color); } @@ -367,16 +365,19 @@ public enum TargetingOverlay { @Override public void paintComponent(final Graphics g) { // No need for this except in match view - if (Singletons.getControl().getCurrentScreen() != FScreen.MATCH_SCREEN) { return; } + if (!Singletons.getControl().getCurrentScreen().isMatchScreen()) { + return; + } super.paintComponent(g); - // 0 is off - int overlaystate = CDock.SINGLETON_INSTANCE.getArcState(); - if (overlaystate == 0) { return; } + final ArcState overlaystate = matchUI.getCDock().getArcState(); + + // Arcs are off + if (overlaystate == ArcState.OFF) { return; } // Arc drawing - final GameView gameView = MatchUtil.getGameView(); + final GameView gameView = matchUI.getGameView(); if (gameView != null) { assembleArcs(gameView.getCombat()); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java index d88a6ec1a18..a876291fa7d 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VAssignDamage.java @@ -41,7 +41,6 @@ import forge.game.GameEntityView; import forge.game.card.CardView; import forge.game.player.PlayerView; import forge.gui.SOverlayUtils; -import forge.match.MatchUtil; import forge.toolbox.FButton; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; @@ -60,6 +59,8 @@ import forge.view.arcane.CardPanel; *

(V at beginning of class name denotes a view class.) */ public class VAssignDamage { + private final CMatchUI matchUI; + // Width and height of blocker dialog private final int wDlg = 700; private final int hDlg = 500; @@ -82,7 +83,7 @@ public class VAssignDamage { private final FButton btnReset = new FButton("Reset"); private final FButton btnAuto = new FButton("Auto"); - + private static class DamageTarget { public final CardView card; public final JLabel label; @@ -145,7 +146,9 @@ public class VAssignDamage { * @param overrideOrder override combatant order */ - public VAssignDamage(final CardView attacker, final List blockers, final int damage0, final GameEntityView defender0, boolean overrideOrder) { + public VAssignDamage(final CMatchUI matchUI, final CardView attacker, final List blockers, final int damage0, final GameEntityView defender0, boolean overrideOrder) { + this.matchUI = matchUI; + dlg.setTitle("Assign damage dealt by " + attacker); // Set damage storage vars @@ -162,7 +165,7 @@ public class VAssignDamage { pnlMain.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); // Attacker area - final CardPanel pnlAttacker = new CardPanel(attacker); + final CardPanel pnlAttacker = new CardPanel(matchUI, attacker); pnlAttacker.setOpaque(false); pnlAttacker.setCardBounds(0, 0, 105, 150); @@ -183,23 +186,22 @@ public class VAssignDamage { // Top row of cards... for (final CardView c : blockers) { - DamageTarget dt = new DamageTarget(c, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build()); + final DamageTarget dt = new DamageTarget(c, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build()); damage.put(c, dt); defenders.add(dt); addPanelForDefender(pnlDefenders, c); } if (attackerHasTrample) { - DamageTarget dt = new DamageTarget(null, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build()); + final DamageTarget dt = new DamageTarget(null, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build()); damage.put(null, dt); defenders.add(dt); CardView fakeCard = null; if (defender instanceof CardView) { fakeCard = (CardView)defender; - } - else if (defender instanceof PlayerView) { + } else if (defender instanceof PlayerView) { final PlayerView p = (PlayerView)defender; - fakeCard = new CardView(-1, null, defender.toString(), p, CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayerName())); + fakeCard = new CardView(-1, null, defender.toString(), p, matchUI.avatarImages.get(p.getLobbyPlayerName())); } addPanelForDefender(pnlDefenders, fakeCard); } @@ -208,7 +210,7 @@ public class VAssignDamage { // If trample allowed, make card placeholder // ... bottom row of labels. - for (DamageTarget l : defenders) { + for (final DamageTarget l : defenders) { pnlDefenders.add(l.label, "w 145px!, h 30px!, gap 5px 5px 0 5px"); } @@ -226,7 +228,7 @@ public class VAssignDamage { pnlMain.add(scrDefenders, "w 96%!, gap 2% 0 0 0, pushy, growy, ax center, span 2"); pnlMain.add(lblAssignRemaining, "w 96%!, gap 2% 0 0 0, ax center, span 2"); - JPanel pnlButtons = new JPanel(new MigLayout("insets 0, gap 0, ax center")); + final JPanel pnlButtons = new JPanel(new MigLayout("insets 0, gap 0, ax center")); pnlButtons.setOpaque(false); pnlButtons.add(btnAuto, "w 110px!, h 30px!, gap 0 10px 0 0"); pnlButtons.add(btnOK, "w 110px!, h 30px!, gap 0 10px 0 0"); @@ -260,7 +262,7 @@ public class VAssignDamage { * @param defender */ private void addPanelForDefender(final JPanel pnlDefenders, final CardView defender) { - final CardPanel cp = new CardPanel(defender); + final CardPanel cp = new CardPanel(matchUI, defender); cp.setCardBounds(0, 0, 105, 150); cp.setOpaque(true); pnlDefenders.add(cp, "w 145px!, h 170px!, gap 5px 5px 3px 3px, ax center"); @@ -436,7 +438,7 @@ public class VAssignDamage { if (card == null) { if (defender instanceof PlayerView) { final PlayerView p = (PlayerView)defender; - lethalDamage = attackerHasInfect ? MatchUtil.getGameView().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife(); + lethalDamage = attackerHasInfect ? matchUI.getGameView().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife(); } else if (defender instanceof CardView) { // planeswalker final CardView pw = (CardView)defender; diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VAutoYields.java b/forge-gui-desktop/src/main/java/forge/screens/match/VAutoYields.java index 13ee72ffdeb..d52f2881f1b 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VAutoYields.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VAutoYields.java @@ -10,7 +10,6 @@ import javax.swing.event.ChangeListener; import forge.Singletons; import forge.UiCommand; -import forge.player.PlayerControllerHuman; import forge.toolbox.FButton; import forge.toolbox.FCheckBox; import forge.toolbox.FList; @@ -31,12 +30,12 @@ public class VAutoYields extends FDialog { private final FCheckBox chkDisableAll; private final List autoYields; - public VAutoYields(final PlayerControllerHuman humanController) { + public VAutoYields(final CMatchUI matchUI) { super(); setTitle("Auto-Yields"); autoYields = new ArrayList(); - for (final String autoYield : humanController.getAutoYields()) { + for (final String autoYield : matchUI.getAutoYields()) { autoYields.add(autoYield); } lstAutoYields = new FList(new AutoYieldsListModel()); @@ -48,11 +47,11 @@ public class VAutoYields extends FDialog { listScroller = new FScrollPane(lstAutoYields, true); - chkDisableAll = new FCheckBox("Disable All Auto Yields", humanController.getDisableAutoYields()); + chkDisableAll = new FCheckBox("Disable All Auto Yields", matchUI.getDisableAutoYields()); chkDisableAll.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { - humanController.setDisableAutoYields(chkDisableAll.isSelected()); + matchUI.setDisableAutoYields(chkDisableAll.isSelected()); } }); @@ -71,7 +70,7 @@ public class VAutoYields extends FDialog { if (selected != null) { autoYields.remove(selected); btnRemove.setEnabled(autoYields.size() > 0); - humanController.setShouldAutoYield(selected, false); + matchUI.setShouldAutoYield(selected, false); VAutoYields.this.revalidate(); lstAutoYields.repaint(); } @@ -115,8 +114,7 @@ public class VAutoYields extends FDialog { if (lstAutoYields.getCount() > 0) { setVisible(true); dispose(); - } - else { + } else { FOptionPane.showMessageDialog("There are no active auto-yields.", "No Auto-Yields", FOptionPane.INFORMATION_ICON); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/VMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/VMatchUI.java index f2812c93bc7..3acbdc012c4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/VMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/VMatchUI.java @@ -1,20 +1,28 @@ package forge.screens.match; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import forge.Singletons; import forge.game.GameView; -import forge.gui.framework.*; -import forge.match.MatchUtil; +import forge.gui.framework.DragCell; +import forge.gui.framework.EDocID; +import forge.gui.framework.FScreen; +import forge.gui.framework.IVTopLevelUI; +import forge.gui.framework.SRearrangingUtil; +import forge.gui.framework.VEmptyDoc; import forge.properties.ForgePreferences; -import forge.screens.match.views.*; +import forge.screens.match.views.VCommand; +import forge.screens.match.views.VDev; +import forge.screens.match.views.VField; +import forge.screens.match.views.VHand; import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; import forge.toolbox.FButton; import forge.view.FView; -import javax.swing.*; - -import java.util.ArrayList; -import java.util.List; - /** * Top level view class for match UI drag layout.
* Has access methods for all draggable documents.
@@ -22,26 +30,16 @@ import java.util.List; * *

(V at beginning of class name denotes a view class.) */ -public enum VMatchUI implements IVTopLevelUI { - SINGLETON_INSTANCE; - +public class VMatchUI implements IVTopLevelUI { private List lstCommands = new ArrayList(); private List lstFields = new ArrayList(); private List lstHands = new ArrayList(); // Other instantiations - private boolean wasClosed; - private final CMatchUI control = null; + private final CMatchUI control; - private VMatchUI() { - createEmptyDocs(); - } - - private void createEmptyDocs() { - // Create empty docs for all slots - for (int i = 0; i < 8; i++) EDocID.Fields[i].setDoc(new VEmptyDoc(EDocID.Fields[i])); - for (int i = 0; i < 8; i++) EDocID.Commands[i].setDoc(new VEmptyDoc(EDocID.Commands[i])); - for (int i = 0; i < 8; i++) EDocID.Hands[i].setDoc(new VEmptyDoc(EDocID.Hands[i])); + VMatchUI(final CMatchUI control) { + this.control = control; } @Override @@ -51,36 +49,28 @@ public enum VMatchUI implements IVTopLevelUI { @Override public void populate() { // Dev mode disabled? Remove from parent cell if exists. + final VDev vDev = getControl().getCDev().getView(); if (!ForgePreferences.DEV_MODE) { - if (VDev.SINGLETON_INSTANCE.getParentCell() != null) { - final DragCell parent = VDev.SINGLETON_INSTANCE.getParentCell(); - parent.removeDoc(VDev.SINGLETON_INSTANCE); - VDev.SINGLETON_INSTANCE.setParentCell(null); + if (vDev.getParentCell() != null) { + final DragCell parent = vDev.getParentCell(); + parent.removeDoc(vDev); + vDev.setParentCell(null); // If dev mode was first tab, the new first tab needs re-selecting. if (parent.getDocs().size() > 0) { parent.setSelected(parent.getDocs().get(0)); } } - } - // Dev mode enabled? May already by added, or put in message cell by default. - else { - if (VDev.SINGLETON_INSTANCE.getParentCell() == null) { - VPrompt.SINGLETON_INSTANCE.getParentCell().addDoc(VDev.SINGLETON_INSTANCE); - } + } else if (vDev.getParentCell() == null) { + // Dev mode enabled? May already by added, or put in message cell by default. + getControl().getCPrompt().getView().getParentCell().addDoc(vDev); } - //Clear previous match views if screen was previously closed - if (wasClosed) { - wasClosed = false; - } - else { //focus first enabled Prompt button if returning to match screen - if (getBtnOK().isEnabled()) { - getBtnOK().requestFocusInWindow(); - } - else if (getBtnCancel().isEnabled()) { - getBtnCancel().requestFocusInWindow(); - } + //focus first enabled Prompt button if returning to match screen + if (getBtnOK().isEnabled()) { + getBtnOK().requestFocusInWindow(); + } else if (getBtnCancel().isEnabled()) { + getBtnCancel().requestFocusInWindow(); } // Add extra players alternatively to existing user/AI field panels. @@ -150,18 +140,18 @@ public enum VMatchUI implements IVTopLevelUI { } public FButton getBtnCancel() { - return VPrompt.SINGLETON_INSTANCE.getBtnCancel(); + return getControl().getCPrompt().getView().getBtnCancel(); } public FButton getBtnOK() { - return VPrompt.SINGLETON_INSTANCE.getBtnOK(); + return getControl().getCPrompt().getView().getBtnOK(); } public List getCommandViews() { return lstCommands; } - public void setCommandViews(List lstCommands0) { + public void setCommandViews(final List lstCommands0) { this.lstCommands = lstCommands0; } @@ -170,22 +160,25 @@ public enum VMatchUI implements IVTopLevelUI { } @Override - public boolean onSwitching(FScreen fromScreen, FScreen toScreen) { + public boolean onSwitching(final FScreen fromScreen, final FScreen toScreen) { return true; } @Override - public boolean onClosing(FScreen screen) { - final GameView gameView = MatchUtil.getGameView(); + public boolean onClosing(final FScreen screen) { + if (!Singletons.getControl().getCurrentScreen().equals(screen)) { + Singletons.getControl().setCurrentScreen(screen); + } + + final GameView gameView = control.getGameView(); if (gameView != null && !gameView.isGameOver()) { - MatchUtil.concede(); + control.concede(); return false; //delay hiding tab even if concede successful } //switch back to menus music when closing screen SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); - wasClosed = true; return true; } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java index 32207631af5..1fb45875d8a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/ViewWinLose.java @@ -40,6 +40,8 @@ import forge.toolbox.FSkin.SkinnedPanel; import forge.toolbox.FTextArea; public class ViewWinLose implements IWinLoseView { + private final ControlWinLose control; + private final FButton btnContinue, btnRestart, btnQuit; private final SkinnedPanel pnlCustom; @@ -55,9 +57,9 @@ public class ViewWinLose implements IWinLoseView { private static final String CONSTRAINTS_CARDS_LARGE = "w 95%!, h 600px!, gap 0 0 0 20px"; private final GameView game; - + @SuppressWarnings("serial") - public ViewWinLose(final GameView game0) { + public ViewWinLose(final GameView game0, final CMatchUI matchUI) { this.game = game0; final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel(); @@ -76,27 +78,28 @@ public class ViewWinLose implements IWinLoseView { ControlWinLose control = null; switch (game0.getGameType()) { case Quest: - control = new QuestWinLose(this, game0); + control = new QuestWinLose(this, game0, matchUI); break; case QuestDraft: - control = new QuestDraftWinLose(this, game0); + control = new QuestDraftWinLose(this, game0, matchUI); break; case Draft: if (!FModel.getGauntletMini().isGauntletDraft()) { break; } case Sealed: - control = new LimitedWinLose(this, game0); + control = new LimitedWinLose(this, game0, matchUI); break; case Gauntlet: - control = new GauntletWinLose(this, game0); + control = new GauntletWinLose(this, game0, matchUI); break; default: // will catch it after switch break; } if (null == control) { - control = new ControlWinLose(this, game0); + control = new ControlWinLose(this, game0, matchUI); } + this.control = control; pnlLeft.setOpaque(false); pnlRight.setOpaque(false); @@ -180,6 +183,8 @@ public class ViewWinLose implements IWinLoseView { pnlLog.add(btnCopyLog, "center, w pref+16, h pref+8"); pnlLeft.add(pnlLog, "w 100%!"); + lblTitle.setText(composeTitle(game0)); + SwingUtilities.invokeLater(new Runnable() { @Override public void run() { @@ -194,11 +199,12 @@ public class ViewWinLose implements IWinLoseView { } }); - lblTitle.setText(composeTitle(game0)); - showGameOutcomeSummary(); showPlayerScores(); + } + public final ControlWinLose getControl() { + return control; } private String composeTitle(final GameView game) { @@ -234,8 +240,9 @@ public class ViewWinLose implements IWinLoseView { } private void showGameOutcomeSummary() { - for (final GameLogEntry o : game.getGameLog().getLogEntriesExact(GameLogEntryType.GAME_OUTCOME)) + for (final GameLogEntry o : game.getGameLog().getLogEntriesExact(GameLogEntryType.GAME_OUTCOME)) { pnlOutcomes.add(new FLabel.Builder().text(o.message).fontSize(14).build(), "h 20!"); + } } private void showPlayerScores() { diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java b/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java index 8ede399b362..f9c5a690fbc 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/ZoneAction.java @@ -14,6 +14,7 @@ import forge.view.arcane.FloatingCardArea; */ public class ZoneAction extends ForgeAction { private static final long serialVersionUID = -5822976087772388839L; + private final CMatchUI matchUI; private final PlayerView player; private final ZoneType zone; @@ -22,14 +23,15 @@ public class ZoneAction extends ForgeAction { * the "zones" of a player field: hand, graveyard, etc. The library * "zone" is an exception to the rule; it's handled in DeckListAction. */ - public ZoneAction(final PlayerView player0, final ZoneType zone0, final MatchConstants property) { + public ZoneAction(final CMatchUI matchUI, final PlayerView player0, final ZoneType zone0, final MatchConstants property) { super(property); + this.matchUI = matchUI; player = player0; zone = zone0; } @Override public void actionPerformed(final ActionEvent e) { - FloatingCardArea.show(player, zone); + FloatingCardArea.show(matchUI, player, zone); } } \ No newline at end of file diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java index ea0ff65e818..245de2cd6fc 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CAntes.java @@ -2,6 +2,7 @@ package forge.screens.match.controllers; import forge.UiCommand; import forge.gui.framework.ICDoc; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VAntes; /** @@ -10,9 +11,13 @@ import forge.screens.match.views.VAntes; *

(C at beginning of class name denotes a control class.) * */ -public enum CAntes implements ICDoc { - /** */ - SINGLETON_INSTANCE; +public class CAntes implements ICDoc { + private final CMatchUI matchUI; + private final VAntes view; + public CAntes(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VAntes(this); + } /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -22,6 +27,10 @@ public enum CAntes implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -34,6 +43,14 @@ public enum CAntes implements ICDoc { */ @Override public void update() { - VAntes.SINGLETON_INSTANCE.update(); + view.update(); + } + + public CMatchUI getMatchUI() { + return matchUI; + } + + public VAntes getView() { + return view; } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java index 987d4cf0d53..312f0444ae7 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java @@ -21,11 +21,17 @@ import forge.util.Lang; *

(C at beginning of class name denotes a control class.) * */ -public enum CCombat implements ICDoc { - /** */ - SINGLETON_INSTANCE; - +public class CCombat implements ICDoc { + private CombatView combat; + private final VCombat view; + public CCombat() { + view = new VCombat(this); + } + + public VCombat getView() { + return view; + } /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -35,6 +41,10 @@ public enum CCombat implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -49,9 +59,9 @@ public enum CCombat implements ICDoc { public void update() { final CombatView localCombat = this.combat; // noone will re-assign this from other thread. if (localCombat != null) { - VCombat.SINGLETON_INSTANCE.updateCombat(localCombat.getNumAttackers(), getCombatDescription(localCombat)); + view.updateCombat(localCombat.getNumAttackers(), getCombatDescription(localCombat)); } else { - VCombat.SINGLETON_INSTANCE.updateCombat(0, ""); + view.updateCombat(0, ""); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java index db60803aac2..873bfaf4bfe 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCommand.java @@ -40,6 +40,10 @@ public class CCommand implements ICDoc { this.view = v0; } + @Override + public void register() { + } + @Override public void initialize() { } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java index 8e22890c3b7..0657549b94b 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetail.java @@ -22,10 +22,8 @@ import java.awt.event.MouseEvent; import forge.UiCommand; import forge.game.card.CardView; import forge.gui.framework.ICDoc; -import forge.item.IPaperCard; import forge.item.InventoryItem; import forge.item.InventoryItemFromSet; -import forge.match.MatchUtil; import forge.screens.match.views.VDetail; import forge.toolbox.FMouseAdapter; @@ -34,37 +32,43 @@ import forge.toolbox.FMouseAdapter; * *

(C at beginning of class name denotes a control class.) */ -public enum CDetail implements ICDoc { - SINGLETON_INSTANCE; +public class CDetail implements ICDoc { + private final VDetail view; + CDetail(final CDetailPicture controller) { + this.view = new VDetail(this); - private VDetail view = VDetail.SINGLETON_INSTANCE; + this.view.getPnlDetail().addMouseListener(new FMouseAdapter() { + @Override + public void onLeftClick(final MouseEvent e) { + controller.flip(); + } + }); + } + + public VDetail getView() { + return view; + } /** * Shows card details and/or picture in sidebar cardview tabber. * * @param c   {@link CardView} object + * @param isInAltState whether to draw the flip side of the card. */ - public void showCard(final CardView c) { - this.showCard(c, false); - } - - public void showCard(final CardView c, final boolean isInAltState) { - view.getLblFlipcard().setVisible(c != null && MatchUtil.canCardBeFlipped(c)); - view.getPnlDetail().setCard(c, isInAltState); + void showCard(final CardView c, final boolean isInAltState, final boolean mayView, final boolean mayFlip) { + final CardView toShow = mayView ? c : null; + view.getLblFlipcard().setVisible(toShow != null && mayFlip); + view.getPnlDetail().setCard(toShow, isInAltState); if (view.getParentCell() != null) { view.getParentCell().repaintSelf(); } } - public void showCard(final InventoryItem item) { - if (item instanceof IPaperCard) { - showCard(CardView.getCardForUi((IPaperCard)item)); - } else if (item instanceof InventoryItemFromSet) { + void showItem(final InventoryItem item) { + if (item instanceof InventoryItemFromSet) { view.getLblFlipcard().setVisible(false); view.getPnlDetail().setItem((InventoryItemFromSet)item); view.getParentCell().repaintSelf(); - } else { - showCard((CardView)null); } } @@ -73,14 +77,13 @@ public enum CDetail implements ICDoc { return null; } + @Override + public void register() { + } + @Override public void initialize() { - view.getPnlDetail().addMouseListener(new FMouseAdapter() { - @Override - public void onLeftClick(final MouseEvent e) { - CPicture.SINGLETON_INSTANCE.flipCard(); - } - }); + } @Override diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java new file mode 100644 index 00000000000..42d83ed7584 --- /dev/null +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDetailPicture.java @@ -0,0 +1,98 @@ +package forge.screens.match.controllers; + +import forge.game.card.Card; +import forge.game.card.CardView; +import forge.interfaces.IMayViewCards; +import forge.item.IPaperCard; +import forge.item.InventoryItem; + +/** + * Class that controls and links a {@link CDetail} and a {@link CPicture}. + */ +public class CDetailPicture { + + private final CDetail cDetail; + private final CPicture cPicture; + private final IMayViewCards mayView; + + private CardView currentView = null; + private boolean isDisplayAlt = false, alwaysDisplayAlt = false; + + public CDetailPicture() { + this(IMayViewCards.ALL); + } + public CDetailPicture(final IMayViewCards mayView) { + this.mayView = mayView; + this.cDetail = new CDetail(this); + this.cPicture = new CPicture(this); + } + + CardView getCurrentCard() { + return currentView; + } + public CDetail getCDetail() { + return cDetail; + } + public CPicture getCPicture() { + return cPicture; + } + + public void showCard(final CardView c, final boolean showAlt) { + currentView = c; + final boolean mayView = mayView(), mayFlip = mayView && mayFlip(); + isDisplayAlt = mayFlip && showAlt; + alwaysDisplayAlt = mayView && mayFlip && c.isFaceDown(); + + update(); + } + + /** + * Displays image associated with either a {@code Card} + * or {@code InventoryItem} instance. + */ + public void showItem(final InventoryItem item) { + if (item instanceof IPaperCard) { + final IPaperCard paperCard = ((IPaperCard)item); + final CardView c = CardView.getCardForUi(paperCard); + if (paperCard.isFoil() && c.getCurrentState().getFoilIndex() == 0) { + // FIXME should assign a random foil here in all cases + // (currently assigns 1 for the deck editors where foils "flicker" otherwise) + if (item instanceof Card) { + c.getCurrentState().setFoilIndexOverride(-1); //-1 to choose random + } else if (item instanceof IPaperCard) { + c.getCurrentState().setFoilIndexOverride(1); + } + } + showCard(c, false); + } else { + currentView = null; + isDisplayAlt = false; + alwaysDisplayAlt = false; + + cDetail.showItem(item); + cPicture.showItem(item); + } + } + + void flip() { + if (mayFlip()) { + isDisplayAlt = !isDisplayAlt; + update(); + } + } + + private void update() { + final boolean mayView = mayView(), mayFlip = mayFlip(); + cDetail.showCard(currentView, isDisplayAlt, mayView, mayFlip); + cPicture.showCard(currentView, isDisplayAlt, mayView, mayFlip || alwaysDisplayAlt); + } + + private boolean mayView() { + return mayView.mayView(currentView); + } + + private boolean mayFlip() { + return mayView.mayFlip(currentView); + } + +} diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java index 8d65f9db1d0..80b1f403e80 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDev.java @@ -6,7 +6,8 @@ import java.awt.event.MouseListener; import forge.UiCommand; import forge.gui.framework.ICDoc; -import forge.match.MatchUtil; +import forge.interfaces.IGameController; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VDev; /** @@ -15,8 +16,36 @@ import forge.screens.match.views.VDev; *

(C at beginning of class name denotes a control class.) * */ -public enum CDev implements ICDoc { - SINGLETON_INSTANCE; +public class CDev implements ICDoc { + + private final CMatchUI matchUI; + private final VDev view; + public CDev(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VDev(this); + + view.getLblUnlimitedLands().addMouseListener(madUnlimited); + view.getLblViewAll().addMouseListener(madViewAll); + view.getLblGenerateMana().addMouseListener(madMana); + view.getLblSetupGame().addMouseListener(madSetup); + view.getLblDumpGame().addMouseListener(madDump); + view.getLblTutor().addMouseListener(madTutor); + view.getLblCardToHand().addMouseListener(madCardToHand); + view.getLblCounterPermanent().addMouseListener(madCounter); + view.getLblTapPermanent().addMouseListener(madTap); + view.getLblUntapPermanent().addMouseListener(madUntap); + view.getLblSetLife().addMouseListener(madLife); + view.getLblWinGame().addMouseListener(madWinGame); + view.getLblCardToBattlefield().addMouseListener(madCardToBattlefield); + view.getLblRiggedRoll().addMouseListener(madRiggedRoll); + view.getLblWalkTo().addMouseListener(madWalkToPlane); + } + public final IGameController getController() { + return matchUI.getGameController(); + } + public final VDev getView() { + return view; + } private final MouseListener madUnlimited = new MouseAdapter() { @Override @@ -25,9 +54,9 @@ public enum CDev implements ICDoc { } }; public void togglePlayManyLandsPerTurn() { - boolean newValue = !VDev.SINGLETON_INSTANCE.getLblUnlimitedLands().getToggled(); - VDev.SINGLETON_INSTANCE.getLblUnlimitedLands().setToggled(newValue); - MatchUtil.getHumanController().cheat().setCanPlayUnlimitedLands(newValue); + final boolean newValue = !view.getLblUnlimitedLands().getToggled(); + view.getLblUnlimitedLands().setToggled(newValue); + getController().cheat().setCanPlayUnlimitedLands(newValue); } private final MouseListener madViewAll = new MouseAdapter() { @@ -37,9 +66,9 @@ public enum CDev implements ICDoc { } }; public void toggleViewAllCards() { - boolean newValue = !VDev.SINGLETON_INSTANCE.getLblViewAll().getToggled(); - VDev.SINGLETON_INSTANCE.getLblViewAll().setToggled(newValue); - MatchUtil.getHumanController().cheat().setViewAllCards(newValue); + final boolean newValue = !view.getLblViewAll().getToggled(); + view.getLblViewAll().setToggled(newValue); + getController().cheat().setViewAllCards(newValue); } private final MouseListener madMana = new MouseAdapter() { @@ -49,7 +78,7 @@ public enum CDev implements ICDoc { } }; public void generateMana() { - MatchUtil.getHumanController().cheat().generateMana(); + getController().cheat().generateMana(); } private final MouseListener madSetup = new MouseAdapter() { @@ -59,7 +88,7 @@ public enum CDev implements ICDoc { } }; public void setupGameState() { - MatchUtil.getHumanController().cheat().setupGameState(); + getController().cheat().setupGameState(); } private final MouseListener madDump = new MouseAdapter() { @@ -69,7 +98,7 @@ public enum CDev implements ICDoc { } }; public void dumpGameState() { - MatchUtil.getHumanController().cheat().dumpGameState(); + getController().cheat().dumpGameState(); } private final MouseListener madTutor = new MouseAdapter() { @@ -79,7 +108,7 @@ public enum CDev implements ICDoc { } }; public void tutorForCard() { - MatchUtil.getHumanController().cheat().tutorForCard(); + getController().cheat().tutorForCard(); } private final MouseListener madCardToHand = new MouseAdapter() { @@ -89,7 +118,7 @@ public enum CDev implements ICDoc { } }; public void addCardToHand() { - MatchUtil.getHumanController().cheat().addCardToHand(); + getController().cheat().addCardToHand(); } private final MouseListener madCounter = new MouseAdapter() { @@ -99,7 +128,7 @@ public enum CDev implements ICDoc { } }; public void addCounterToPermanent() { - MatchUtil.getHumanController().cheat().addCountersToPermanent(); + getController().cheat().addCountersToPermanent(); } private final MouseListener madTap = new MouseAdapter() { @@ -109,7 +138,7 @@ public enum CDev implements ICDoc { } }; public void tapPermanent() { - MatchUtil.getHumanController().cheat().tapPermanents(); + getController().cheat().tapPermanents(); } private final MouseListener madUntap = new MouseAdapter() { @@ -119,7 +148,7 @@ public enum CDev implements ICDoc { } }; public void untapPermanent() { - MatchUtil.getHumanController().cheat().untapPermanents(); + getController().cheat().untapPermanents(); } private final MouseListener madLife = new MouseAdapter() { @@ -129,7 +158,7 @@ public enum CDev implements ICDoc { } }; public void setPlayerLife() { - MatchUtil.getHumanController().cheat().setPlayerLife(); + getController().cheat().setPlayerLife(); } private final MouseListener madWinGame = new MouseAdapter() { @@ -139,7 +168,7 @@ public enum CDev implements ICDoc { } }; public void winGame() { - MatchUtil.getHumanController().cheat().winGame(); + getController().cheat().winGame(); } private final MouseListener madCardToBattlefield = new MouseAdapter() { @@ -149,7 +178,7 @@ public enum CDev implements ICDoc { } }; public void addCardToBattlefield() { - MatchUtil.getHumanController().cheat().addCardToBattlefield(); + getController().cheat().addCardToBattlefield(); } private final MouseListener madRiggedRoll = new MouseAdapter() { @@ -159,7 +188,7 @@ public enum CDev implements ICDoc { } }; public void riggedPlanerRoll() { - MatchUtil.getHumanController().cheat().riggedPlanarRoll(); + getController().cheat().riggedPlanarRoll(); } private final MouseListener madWalkToPlane = new MouseAdapter() { @@ -169,7 +198,7 @@ public enum CDev implements ICDoc { } }; public void planeswalkTo() { - MatchUtil.getHumanController().cheat().planeswalkTo(); + getController().cheat().planeswalkTo(); } //========== End mouse listener inits @@ -182,26 +211,15 @@ public enum CDev implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @Override public void initialize() { - VDev.SINGLETON_INSTANCE.getLblUnlimitedLands().addMouseListener(madUnlimited); - VDev.SINGLETON_INSTANCE.getLblViewAll().addMouseListener(madViewAll); - VDev.SINGLETON_INSTANCE.getLblGenerateMana().addMouseListener(madMana); - VDev.SINGLETON_INSTANCE.getLblSetupGame().addMouseListener(madSetup); - VDev.SINGLETON_INSTANCE.getLblDumpGame().addMouseListener(madDump); - VDev.SINGLETON_INSTANCE.getLblTutor().addMouseListener(madTutor); - VDev.SINGLETON_INSTANCE.getLblCardToHand().addMouseListener(madCardToHand); - VDev.SINGLETON_INSTANCE.getLblCounterPermanent().addMouseListener(madCounter); - VDev.SINGLETON_INSTANCE.getLblTapPermanent().addMouseListener(madTap); - VDev.SINGLETON_INSTANCE.getLblUntapPermanent().addMouseListener(madUntap); - VDev.SINGLETON_INSTANCE.getLblSetLife().addMouseListener(madLife); - VDev.SINGLETON_INSTANCE.getLblWinGame().addMouseListener(madWinGame); - VDev.SINGLETON_INSTANCE.getLblCardToBattlefield().addMouseListener(madCardToBattlefield); - VDev.SINGLETON_INSTANCE.getLblRiggedRoll().addMouseListener(madRiggedRoll); - VDev.SINGLETON_INSTANCE.getLblWalkTo().addMouseListener(madWalkToPlane); } /* (non-Javadoc) @@ -209,7 +227,9 @@ public enum CDev implements ICDoc { */ @Override public void update() { - VDev.SINGLETON_INSTANCE.getLblUnlimitedLands().setToggled(MatchUtil.getHumanController().canPlayUnlimitedLands()); - VDev.SINGLETON_INSTANCE.getLblViewAll().setToggled(MatchUtil.getHumanController().mayLookAtAllCards()); + if (getController() != null) { + view.getLblUnlimitedLands().setToggled(!getController().canPlayUnlimitedLands()); + view.getLblViewAll().setToggled(!getController().mayLookAtAllCards()); + } } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java index 988fa373dfe..0f3120d3194 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CDock.java @@ -17,101 +17,50 @@ */ package forge.screens.match.controllers; -import java.io.File; +import java.util.Iterator; + +import com.google.common.collect.Iterators; -import forge.FThreads; import forge.Singletons; import forge.UiCommand; import forge.assets.FSkinProp; -import forge.deck.Deck; -import forge.deckchooser.FDeckViewer; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; import forge.gui.framework.SLayoutIO; -import forge.match.MatchUtil; import forge.model.FModel; -import forge.player.GamePlayerUtil; -import forge.properties.FileLocation; import forge.properties.ForgePreferences.FPref; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VDock; import forge.toolbox.FSkin; -import forge.toolbox.SaveOpenDialog; -import forge.toolbox.SaveOpenDialog.Filetypes; -import forge.view.FView; /** * Controls the dock panel in the match UI. * *

(C at beginning of class name denotes a control class.) */ -public enum CDock implements ICDoc { - /** */ - SINGLETON_INSTANCE; +public class CDock implements ICDoc { - private int arcState; + private ArcState arcState; + private final Iterator arcStateIterator = Iterators.cycle(ArcState.values()); + + private final CMatchUI matchUI; + private final VDock view; + public CDock(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VDock(this); + } + + public enum ArcState { OFF, MOUSEOVER, ON; } + + public VDock getView() { + return view; + } /** * End turn. */ public void endTurn() { - CPrompt.SINGLETON_INSTANCE.passPriorityUntilEndOfTurn(); - } - - public void revertLayout() { - SOverlayUtils.genericOverlay(); - FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); - - FThreads.invokeInEdtLater(new Runnable(){ - @Override public void run() { - SLayoutIO.loadLayout(null); - SOverlayUtils.hideOverlay(); - } - }); - } - - public void saveLayout() { - final SaveOpenDialog dlgSave = new SaveOpenDialog(); - final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile(); - final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null; - final File saveFile = dlgSave.SaveDialog(defFile, Filetypes.LAYOUT); - if (saveFile != null) { - SLayoutIO.saveLayout(saveFile); - } - } - - public void openLayout() { - SOverlayUtils.genericOverlay(); - - final SaveOpenDialog dlgOpen = new SaveOpenDialog(); - final FileLocation layoutFile = Singletons.getControl().getCurrentScreen().getLayoutFile(); - final File defFile = layoutFile != null ? new File(layoutFile.userPrefLoc) : null; - final File loadFile = dlgOpen.OpenDialog(defFile, Filetypes.LAYOUT); - - if (loadFile != null) { - FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); - // let it redraw everything first - - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - if (loadFile != null) { - SLayoutIO.loadLayout(loadFile); - SLayoutIO.saveLayout(null); - } - SOverlayUtils.hideOverlay(); - } - }); - } - } - - /** - * View deck list. - */ - public void viewDeckList() { - final Deck deck = MatchUtil.getGameView().getDeck(GamePlayerUtil.getGuiPlayer()); - if (deck != null) { - FDeckViewer.show(deck); - } + matchUI.getCPrompt().passPriorityUntilEndOfTurn(); } /** @@ -120,46 +69,45 @@ public enum CDock implements ICDoc { * 1 = draw on card mouseover
* 2 = always draw */ - public int getArcState() { + public ArcState getArcState() { return arcState; } /** @param state0 int */ private void refreshArcStateDisplay() { switch (arcState) { - case 0: - VDock.SINGLETON_INSTANCE.getBtnTargeting().setToolTipText("Targeting arcs: Off"); - VDock.SINGLETON_INSTANCE.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSOFF)); - VDock.SINGLETON_INSTANCE.getBtnTargeting().repaintSelf(); + case OFF: + view.getBtnTargeting().setToolTipText("Targeting arcs: Off"); + view.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSOFF)); + view.getBtnTargeting().repaintSelf(); break; - case 1: - VDock.SINGLETON_INSTANCE.getBtnTargeting().setToolTipText("Targeting arcs: Card mouseover"); - VDock.SINGLETON_INSTANCE.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSHOVER)); - VDock.SINGLETON_INSTANCE.getBtnTargeting().repaintSelf(); + case MOUSEOVER: + view.getBtnTargeting().setToolTipText("Targeting arcs: Card mouseover"); + view.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSHOVER)); + view.getBtnTargeting().repaintSelf(); break; - default: - VDock.SINGLETON_INSTANCE.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSON)); - VDock.SINGLETON_INSTANCE.getBtnTargeting().setToolTipText("Targeting arcs: Always on"); - VDock.SINGLETON_INSTANCE.getBtnTargeting().repaintSelf(); + case ON: + view.getBtnTargeting().setToolTipText("Targeting arcs: Always on"); + view.getBtnTargeting().setIcon(FSkin.getIcon(FSkinProp.ICO_ARCSON)); + view.getBtnTargeting().repaintSelf(); break; } - FModel.getPreferences().setPref(FPref.UI_TARGETING_OVERLAY, String.valueOf(arcState)); - //FModel.SINGLETON_INSTANCE.getPreferences().save(); + FModel.getPreferences().setPref(FPref.UI_TARGETING_OVERLAY, String.valueOf(arcState.ordinal())); + FModel.getPreferences().save(); } /** Toggle targeting overlay painting. */ public void toggleTargeting() { - arcState++; - - if (arcState == 3) { arcState = 0; } + arcState = arcStateIterator.next(); refreshArcStateDisplay(); - FView.SINGLETON_INSTANCE.getFrame().repaint(); // repaint the match UI + Singletons.getView().getFrame().repaint(); // repaint the match UI } - public void setArcState(int state) { + public void setArcState(final ArcState state) { arcState = state; + while (arcStateIterator.next() != arcState) { /* Put the iterator to the correct value */ }; } /* (non-Javadoc) @@ -170,6 +118,10 @@ public enum CDock implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -178,68 +130,58 @@ public enum CDock implements ICDoc { public void initialize() { final String temp = FModel.getPreferences() .getPref(FPref.UI_TARGETING_OVERLAY); - - // Old preference used boolean; new preference needs 0-1-2 - // (none, mouseover, solid). Can remove this conditional - // statement after a while...Doublestrike 17-10-12 - if (temp.equals("0") || temp.equals("1")) { - arcState = Integer.valueOf(temp); - } - else { - arcState = 2; - } - + setArcState(ArcState.values()[Integer.valueOf(temp)]); refreshArcStateDisplay(); - VDock.SINGLETON_INSTANCE.getBtnConcede().setCommand(new UiCommand() { + view.getBtnConcede().setCommand(new UiCommand() { @Override public void run() { - MatchUtil.concede(); + matchUI.concede(); } }); - VDock.SINGLETON_INSTANCE.getBtnSettings().setCommand(new UiCommand() { + view.getBtnSettings().setCommand(new UiCommand() { @Override public void run() { SOverlayUtils.showOverlay(); } }); - VDock.SINGLETON_INSTANCE.getBtnEndTurn().setCommand(new UiCommand() { + view.getBtnEndTurn().setCommand(new UiCommand() { @Override public void run() { endTurn(); } }); - VDock.SINGLETON_INSTANCE.getBtnViewDeckList().setCommand(new UiCommand() { + view.getBtnViewDeckList().setCommand(new UiCommand() { @Override public void run() { - viewDeckList(); + matchUI.viewDeckList(); } }); - VDock.SINGLETON_INSTANCE.getBtnRevertLayout().setCommand(new UiCommand() { + view.getBtnRevertLayout().setCommand(new UiCommand() { @Override public void run() { - revertLayout(); + SLayoutIO.revertLayout(); } }); - VDock.SINGLETON_INSTANCE.getBtnOpenLayout().setCommand(new UiCommand() { + view.getBtnOpenLayout().setCommand(new UiCommand() { @Override public void run() { - openLayout(); + SLayoutIO.openLayout(); } }); - VDock.SINGLETON_INSTANCE.getBtnSaveLayout().setCommand(new UiCommand() { + view.getBtnSaveLayout().setCommand(new UiCommand() { @Override public void run() { - saveLayout(); + SLayoutIO.saveLayout(); } }); - VDock.SINGLETON_INSTANCE.getBtnAlphaStrike().setCommand(new UiCommand() { + view.getBtnAlphaStrike().setCommand(new UiCommand() { @Override public void run() { - MatchUtil.getHumanController().alphaStrike(); + matchUI.getGameController().alphaStrike(); } }); - VDock.SINGLETON_INSTANCE.getBtnTargeting().setCommand(new UiCommand() { + view.getBtnTargeting().setCommand(new UiCommand() { @Override public void run() { toggleTargeting(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java index 5a5a008177f..c3d8510e053 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CField.java @@ -29,7 +29,7 @@ import forge.game.player.PlayerView; import forge.game.zone.ZoneType; import forge.gui.framework.ICDoc; import forge.match.MatchConstants; -import forge.match.MatchUtil; +import forge.screens.match.CMatchUI; import forge.screens.match.ZoneAction; import forge.screens.match.views.VField; import forge.toolbox.MouseTriggerEvent; @@ -38,6 +38,7 @@ import forge.toolbox.MouseTriggerEvent; * Controls Swing components of a player's field instance. */ public class CField implements ICDoc { + private final CMatchUI matchUI; // The one who owns cards on this side of table private final PlayerView player; private final VField view; @@ -46,7 +47,7 @@ public class CField implements ICDoc { private final MouseListener madAvatar = new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { - CPrompt.SINGLETON_INSTANCE.selectPlayer(player, new MouseTriggerEvent(e)); + matchUI.getCPrompt().selectPlayer(player, new MouseTriggerEvent(e)); } }; @@ -57,20 +58,21 @@ public class CField implements ICDoc { * @param v0   {@link forge.screens.match.views.VField} * @param playerViewer */ - public CField(final PlayerView player0, final VField v0) { + public CField(final CMatchUI matchUI, final PlayerView player0, final VField v0) { + this.matchUI = matchUI; this.player = player0; this.view = v0; - final ZoneAction handAction = new ZoneAction(player, ZoneType.Hand, MatchConstants.HUMANHAND); - final ZoneAction libraryAction = new ZoneAction(player, ZoneType.Library, MatchConstants.HUMANLIBRARY); - final ZoneAction exileAction = new ZoneAction(player, ZoneType.Exile, MatchConstants.HUMANEXILED); - final ZoneAction graveAction = new ZoneAction(player, ZoneType.Graveyard, MatchConstants.HUMANGRAVEYARD); - final ZoneAction flashBackAction = new ZoneAction(player, ZoneType.Flashback, MatchConstants.HUMANFLASHBACK); + final ZoneAction handAction = new ZoneAction(matchUI, player, ZoneType.Hand, MatchConstants.HUMANHAND); + final ZoneAction libraryAction = new ZoneAction(matchUI, player, ZoneType.Library, MatchConstants.HUMANLIBRARY); + final ZoneAction exileAction = new ZoneAction(matchUI, player, ZoneType.Exile, MatchConstants.HUMANEXILED); + final ZoneAction graveAction = new ZoneAction(matchUI, player, ZoneType.Graveyard, MatchConstants.HUMANGRAVEYARD); + final ZoneAction flashBackAction = new ZoneAction(matchUI, player, ZoneType.Flashback, MatchConstants.HUMANFLASHBACK); - Function manaAction = new Function() { + final Function manaAction = new Function() { public Boolean apply(Byte colorCode) { if (CField.this.player.isLobbyPlayer(Singletons.getControl().getGuiPlayer())) { - return MatchUtil.getHumanController().useMana(colorCode.byteValue()); + return matchUI.getGameController().useMana(colorCode.byteValue()); } return false; } @@ -79,6 +81,14 @@ public class CField implements ICDoc { view.getDetailsPanel().setupMouseActions(handAction, libraryAction, exileAction, graveAction, flashBackAction, manaAction); } + public final CMatchUI getMatchUI() { + return matchUI; + } + + @Override + public void register() { + } + @Override public void initialize() { if (initializedAlready) { return; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CHand.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CHand.java index ce5e59fd392..e8b35258ef3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CHand.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CHand.java @@ -35,7 +35,6 @@ import forge.Singletons; import forge.UiCommand; import forge.game.card.CardView; import forge.game.player.PlayerView; -import forge.gui.framework.FScreen; import forge.gui.framework.ICDoc; import forge.screens.match.CMatchUI; import forge.screens.match.views.VField; @@ -49,6 +48,7 @@ import forge.view.arcane.util.CardPanelMouseAdapter; * Controls Swing components of a player's hand instance. */ public class CHand implements ICDoc { + private final CMatchUI matchUI; private final PlayerView player; private final VHand view; private final List ordering = Lists.newArrayList(); @@ -59,7 +59,8 @@ public class CHand implements ICDoc { * @param p0   {@link forge.game.player.Player} * @param v0   {@link forge.screens.match.views.VHand} */ - public CHand(final PlayerView p0, final VHand v0) { + public CHand(final CMatchUI matchUI, final PlayerView p0, final VHand v0) { + this.matchUI = matchUI; this.player = p0; this.view = v0; v0.getHandArea().addCardPanelMouseListener(new CardPanelMouseAdapter() { @@ -75,6 +76,10 @@ public class CHand implements ICDoc { }); } + @Override + public void register() { + } + @Override public void initialize() { } @@ -92,7 +97,7 @@ public class CHand implements ICDoc { final HandArea p = view.getHandArea(); - VField vf = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player); + final VField vf = matchUI.getFieldViewFor(player); if (vf == null) { return; } @@ -105,15 +110,18 @@ public class CHand implements ICDoc { } // Don't perform animations if the user's in another tab. - if (!FScreen.MATCH_SCREEN.equals(Singletons.getControl().getCurrentScreen())) { + if (!matchUI.isCurrentScreen()) { return; } //update card panels in hand area - final List cards; - synchronized (player) { - cards = ImmutableList.copyOf(player.getHand()); + if (player.getHand() == null) { + cards = ImmutableList.of(); + } else { + synchronized (player) { + cards = ImmutableList.copyOf(player.getHand()); + } } synchronized (ordering) { @@ -133,7 +141,7 @@ public class CHand implements ICDoc { for (final CardView card : ordering) { CardPanel cardPanel = p.getCardPanel(card.getId()); if (cardPanel == null) { //create placeholders for new cards - cardPanel = new CardPanel(card); + cardPanel = new CardPanel(matchUI, card); cardPanel.setDisplayEnabled(false); placeholders.add(cardPanel); } @@ -164,7 +172,7 @@ public class CHand implements ICDoc { endY = toPos.y; if (Singletons.getView().getFrame().isShowing()) { - final CardPanel animationPanel = new CardPanel(placeholder.getCard()); + final CardPanel animationPanel = new CardPanel(matchUI, placeholder.getCard()); Animation.moveCard(startX, startY, startWidth, endX, endY, endWidth, animationPanel, placeholder, layeredPane, 500); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CLog.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CLog.java index 21620d81b40..6e9ec0bbb8a 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CLog.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CLog.java @@ -3,7 +3,9 @@ package forge.screens.match.controllers; import forge.UiCommand; import forge.FThreads; import forge.gui.framework.ICDoc; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VLog; + import java.util.Observable; import java.util.Observer; @@ -13,9 +15,21 @@ import java.util.Observer; *

(C at beginning of class name denotes a control class.) * */ -public enum CLog implements ICDoc, Observer { - /** */ - SINGLETON_INSTANCE; +public class CLog implements ICDoc, Observer { + + private final CMatchUI matchUI; + private final VLog view; + public CLog(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VLog(this); + } + + public final CMatchUI getMatchUI() { + return matchUI; + } + public final VLog getView() { + return view; + } /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -25,6 +39,10 @@ public enum CLog implements ICDoc, Observer { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -36,7 +54,7 @@ public enum CLog implements ICDoc, Observer { private final Runnable r = new Runnable() { @Override public void run() { - VLog.SINGLETON_INSTANCE.updateConsole(); + view.updateConsole(); } }; 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 f34e1e4fc15..6c030cd080f 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 @@ -24,13 +24,11 @@ import java.awt.event.MouseWheelListener; import javax.swing.JLabel; import forge.UiCommand; -import forge.game.card.Card; import forge.game.card.CardView; +import forge.game.card.CardView.CardStateView; import forge.gui.CardPicturePanel; import forge.gui.framework.ICDoc; -import forge.item.IPaperCard; import forge.item.InventoryItem; -import forge.match.MatchUtil; import forge.screens.match.views.VPicture; import forge.toolbox.FMouseAdapter; import forge.toolbox.special.CardZoomer; @@ -38,73 +36,46 @@ import forge.toolbox.special.CardZoomer; /** * Singleton controller for VPicture. *

- * Can be used to display images associated with a {@code Card} or - * {@code InventoryItem} in {@code CardPicturePanel}.
+ * Can be used to display images associated with a {@link Card} or + * {@link InventoryItem} in {@link CardPicturePanel}.
*
- * Can also be used to display details associated with a {@code Card}. - * - * @version: $Id:$ - * + * Can also be used to display details associated with a {@link Card}. */ -public enum CPicture implements ICDoc { - SINGLETON_INSTANCE; +public class CPicture implements ICDoc { + private final CDetailPicture controller; + private final VPicture view; + CPicture(final CDetailPicture controller) { + this.controller = controller; + this.view = new VPicture(this); + picturePanel = this.view.getPnlPicture(); + flipIndicator = this.view.getLblFlipcard(); + + setMouseWheelListener(); + setMouseButtonListener(); + } + + public VPicture getView() { + return view; + } // For brevity, local shortcuts to singletons & child controls... - private final VPicture view = VPicture.SINGLETON_INSTANCE; - private final CardPicturePanel picturePanel = this.view.getPnlPicture(); - private final JLabel flipIndicator = this.view.getLblFlipcard(); + private final CardPicturePanel picturePanel; + private final JLabel flipIndicator; private final CardZoomer zoomer = CardZoomer.SINGLETON_INSTANCE; - private CardView currentView = null; - private boolean isDisplayAlt = false, alwaysDisplayAlt = false; - /** * Shows card details and/or picture in sidebar cardview tabber. * */ - public void showCard(final CardView c, boolean showAlt) { - if (c == null) { - return; - } - - boolean canFlip = MatchUtil.canCardBeFlipped(c); - - currentView = c; - isDisplayAlt = showAlt; - alwaysDisplayAlt = canFlip && c.isFaceDown(); - flipIndicator.setVisible(canFlip); - picturePanel.setCard(c.getState(isDisplayAlt || alwaysDisplayAlt)); - if (showAlt && canFlip) { - flipCard(); - } + void showCard(final CardView c, final boolean isInAltState, final boolean mayView, final boolean mayFlip) { + final CardStateView toShow = c != null && mayView ? c.getState(isInAltState) : null; + flipIndicator.setVisible(toShow != null && mayFlip); + picturePanel.setCard(toShow); } - /** - * Displays image associated with either a {@code Card} - * or {@code InventoryItem} instance. - */ - public void showImage(final InventoryItem item) { - if (item instanceof IPaperCard) { - final IPaperCard paperCard = ((IPaperCard)item); - final CardView c = CardView.getCardForUi(paperCard); - if (paperCard.isFoil() && c.getCurrentState().getFoilIndex() == 0) { - // FIXME should assign a random foil here in all cases - // (currently assigns 1 for the deck editors where foils "flicker" otherwise) - if (item instanceof Card) { - c.getCurrentState().setFoilIndexOverride(-1); //-1 to choose random - } - else if (item instanceof IPaperCard) { - c.getCurrentState().setFoilIndexOverride(1); - } - } - showCard(c, false); - } else { - currentView = null; - isDisplayAlt = false; - alwaysDisplayAlt = false; - flipIndicator.setVisible(false); - picturePanel.setCard(item); - } + void showItem(final InventoryItem item) { + flipIndicator.setVisible(false); + picturePanel.setCard(item); } @Override @@ -112,10 +83,12 @@ public enum CPicture implements ICDoc { return null; } + @Override + public void register() { + } + @Override public void initialize() { - setMouseWheelListener(); - setMouseButtonListener(); } /** @@ -128,21 +101,21 @@ public enum CPicture implements ICDoc { private void setMouseButtonListener() { this.picturePanel.addMouseListener(new FMouseAdapter() { @Override - public void onLeftClick(MouseEvent e) { - flipCard(); + public void onLeftClick(final MouseEvent e) { + controller.flip(); } @Override - public void onMiddleMouseDown(MouseEvent e) { + public void onMiddleMouseDown(final MouseEvent e) { if (isCardDisplayed()) { - CardZoomer.SINGLETON_INSTANCE.doMouseButtonZoom(currentView); + zoomer.doMouseButtonZoom(controller.getCurrentCard()); } } @Override - public void onMiddleMouseUp(MouseEvent e) { + public void onMiddleMouseUp(final MouseEvent e) { if (isCardDisplayed()) { - CardZoomer.SINGLETON_INSTANCE.closeZoomer(); + zoomer.closeZoomer(); } } }); @@ -157,10 +130,10 @@ public enum CPicture implements ICDoc { private void setMouseWheelListener() { picturePanel.addMouseWheelListener(new MouseWheelListener() { @Override - public void mouseWheelMoved(MouseWheelEvent arg0) { + public void mouseWheelMoved(final MouseWheelEvent arg0) { if (isCardDisplayed()) { if (arg0.getWheelRotation() < 0) { - zoomer.doMouseWheelZoom(currentView); + zoomer.doMouseWheelZoom(controller.getCurrentCard()); } } } @@ -168,18 +141,11 @@ public enum CPicture implements ICDoc { } private boolean isCardDisplayed() { - return (currentView != null); + return controller.getCurrentCard() != null; } @Override public void update() { } - public void flipCard() { - if (MatchUtil.canCardBeFlipped(currentView)) { - isDisplayAlt = !isDisplayAlt; - picturePanel.setCard(currentView.getState(isDisplayAlt || alwaysDisplayAlt)); - CDetail.SINGLETON_INSTANCE.showCard(currentView, isDisplayAlt); - } - } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPlayers.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPlayers.java index b5f36c75ba9..6dddffd9fbd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPlayers.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPlayers.java @@ -2,6 +2,7 @@ package forge.screens.match.controllers; import forge.UiCommand; import forge.gui.framework.ICDoc; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VPlayers; /** @@ -10,9 +11,21 @@ import forge.screens.match.views.VPlayers; *

(C at beginning of class name denotes a control class.) * */ -public enum CPlayers implements ICDoc { - /** */ - SINGLETON_INSTANCE; +public class CPlayers implements ICDoc { + + private final CMatchUI matchUI; + private final VPlayers view; + public CPlayers(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VPlayers(this); + } + + public final CMatchUI getMatchUI() { + return matchUI; + } + public final VPlayers getView() { + return view; + } /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -22,6 +35,10 @@ public enum CPlayers implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -34,6 +51,6 @@ public enum CPlayers implements ICDoc { */ @Override public void update() { - VPlayers.SINGLETON_INSTANCE.update(); + view.update(); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java index d06b54670eb..179cbd2cb59 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CPrompt.java @@ -35,7 +35,7 @@ import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; import forge.gui.framework.ICDoc; import forge.gui.framework.SDisplayUtil; -import forge.match.MatchUtil; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VPrompt; import forge.toolbox.FSkin; import forge.util.ITriggerEvent; @@ -45,11 +45,19 @@ import forge.util.ITriggerEvent; * *

(C at beginning of class name denotes a control class.) */ -public enum CPrompt implements ICDoc { - SINGLETON_INSTANCE; +public class CPrompt implements ICDoc { + private final CMatchUI matchUI; + private final VPrompt view; + public CPrompt(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VPrompt(this); + } + + public final VPrompt getView() { + return view; + } private Component lastFocusedButton = null; - private final VPrompt view = VPrompt.SINGLETON_INSTANCE; private final ActionListener actCancel = new ActionListener() { @Override @@ -89,31 +97,31 @@ public enum CPrompt implements ICDoc { } public void selectButtonOk() { - MatchUtil.getHumanController().selectButtonOk(); + matchUI.getGameController().selectButtonOk(); } public void selectButtonCancel() { - MatchUtil.getHumanController().selectButtonCancel(); + matchUI.getGameController().selectButtonCancel(); } public boolean passPriority() { - return MatchUtil.getHumanController().passPriority(); + return matchUI.getGameController().passPriority(); } public boolean passPriorityUntilEndOfTurn() { - return MatchUtil.getHumanController().passPriorityUntilEndOfTurn(); + return matchUI.getGameController().passPriorityUntilEndOfTurn(); } public void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) { - MatchUtil.getHumanController().selectPlayer(playerView, triggerEvent); + matchUI.getGameController().selectPlayer(playerView, triggerEvent); } public boolean selectCard(final CardView cardView, final List otherCardViewsToSelect, final ITriggerEvent triggerEvent) { - return MatchUtil.getHumanController().selectCard(cardView, otherCardViewsToSelect, triggerEvent); + return matchUI.getGameController().selectCard(cardView, otherCardViewsToSelect, triggerEvent); } public void selectAbility(final SpellAbility sa) { - MatchUtil.getHumanController().selectAbility(sa); + matchUI.getGameController().selectAbility(sa); } public void setMessage(String s0) { @@ -130,6 +138,10 @@ public enum CPrompt implements ICDoc { return null; } + @Override + public void register() { + } + @Override public void update() { // set focus back to button that last had it @@ -140,7 +152,10 @@ public enum CPrompt implements ICDoc { public void updateText() { FThreads.assertExecutedByEdt(true); - final GameView game = MatchUtil.getGameView(); + final GameView game = matchUI.getGameView(); + if (game == null) { + return; + } final String text = String.format("T:%d G:%d/%d [%s]", game.getTurn(), game.getNumPlayedGamesInMatch() + 1, game.getNumGamesInMatch(), game.getGameType()); view.getLblGames().setText(text); view.getLblGames().setToolTipText(String.format("%s: Game #%d of %d, turn %d", game.getGameType(), game.getNumPlayedGamesInMatch() + 1, game.getNumGamesInMatch(), game.getTurn())); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CStack.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CStack.java index 421527ead53..b356061a323 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CStack.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CStack.java @@ -4,6 +4,7 @@ import forge.UiCommand; import forge.gui.framework.EDocID; import forge.gui.framework.ICDoc; import forge.gui.framework.SDisplayUtil; +import forge.screens.match.CMatchUI; import forge.screens.match.views.VStack; /** @@ -12,9 +13,21 @@ import forge.screens.match.views.VStack; *

(C at beginning of class name denotes a control class.) * */ -public enum CStack implements ICDoc { - /** */ - SINGLETON_INSTANCE; +public class CStack implements ICDoc { + + private final CMatchUI matchUI; + private final VStack view; + public CStack(final CMatchUI matchUI) { + this.matchUI = matchUI; + this.view = new VStack(this); + } + + public final CMatchUI getMatchUI() { + return matchUI; + } + public final VStack getView() { + return view; + } /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -24,6 +37,10 @@ public enum CStack implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ @@ -34,6 +51,6 @@ public enum CStack implements ICDoc { @Override public void update() { SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); - VStack.SINGLETON_INSTANCE.updateStack(); + view.updateStack(); } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/menus/CMatchUIMenus.java b/forge-gui-desktop/src/main/java/forge/screens/match/menus/CMatchUIMenus.java index 99e0c16ec35..8f0ebf650b8 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/menus/CMatchUIMenus.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/menus/CMatchUIMenus.java @@ -1,11 +1,14 @@ package forge.screens.match.menus; -import forge.properties.ForgePreferences; -import javax.swing.*; - import java.util.ArrayList; import java.util.List; +import javax.swing.JMenu; + +import forge.properties.ForgePreferences; +import forge.screens.match.CMatchUI; +import forge.screens.match.controllers.CDev; + /** * Gets the menus associated with the Game screen. * @@ -14,11 +17,16 @@ public class CMatchUIMenus { private final boolean SHOW_ICONS = false; - public List getMenus() { - List menus = new ArrayList(); - menus.add(GameMenu.getMenu(SHOW_ICONS)); + private final CMatchUI matchUI; + public CMatchUIMenus(final CMatchUI matchUI) { + this.matchUI = matchUI; + } + + public List getMenus(final CDev devController) { + final List menus = new ArrayList(); + menus.add(new GameMenu(matchUI).getMenu(SHOW_ICONS)); if (ForgePreferences.DEV_MODE) { - menus.add(DevModeMenu.getMenu()); + menus.add(new DevModeMenu(devController).getMenu()); } return menus; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/menus/CardOverlaysMenu.java b/forge-gui-desktop/src/main/java/forge/screens/match/menus/CardOverlaysMenu.java index c668c5f49c9..799c5dc2c00 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/menus/CardOverlaysMenu.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/menus/CardOverlaysMenu.java @@ -14,12 +14,15 @@ import java.awt.event.ActionListener; import java.awt.event.KeyEvent; public final class CardOverlaysMenu { - private CardOverlaysMenu() { } + private final CMatchUI matchUI; + public CardOverlaysMenu(final CMatchUI matchUI) { + this.matchUI = matchUI; + } private static ForgePreferences prefs = FModel.getPreferences(); private static boolean showOverlays = prefs.getPrefBoolean(FPref.UI_SHOW_CARD_OVERLAYS); - public static JMenu getMenu(boolean showMenuIcons) { + public JMenu getMenu(final boolean showMenuIcons) { JMenu menu = new JMenu("Card Overlays"); menu.add(getMenuItem_ShowOverlays()); menu.addSeparator(); @@ -30,7 +33,7 @@ public final class CardOverlaysMenu { return menu; } - private static JMenuItem getMenuItem_CardOverlay(String menuCaption, FPref pref) { + private JMenuItem getMenuItem_CardOverlay(String menuCaption, FPref pref) { JCheckBoxMenuItem menu = new JCheckBoxMenuItem(menuCaption); menu.setState(prefs.getPrefBoolean(pref)); menu.setEnabled(showOverlays); @@ -38,7 +41,7 @@ public final class CardOverlaysMenu { return menu; } - private static JMenuItem getMenuItem_ShowOverlays() { + private JMenuItem getMenuItem_ShowOverlays() { JCheckBoxMenuItem menu = new JCheckBoxMenuItem("Show"); menu.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_O)); menu.setState(prefs.getPrefBoolean(FPref.UI_SHOW_CARD_OVERLAYS)); @@ -46,7 +49,7 @@ public final class CardOverlaysMenu { return menu; } - private static ActionListener getShowOverlaysAction() { + private ActionListener getShowOverlaysAction() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -55,7 +58,7 @@ public final class CardOverlaysMenu { }; } - private static void toggleCardOverlayDisplay(JMenuItem showMenu) { + private void toggleCardOverlayDisplay(JMenuItem showMenu) { toggleShowOverlaySetting(); repaintCardOverlays(); // Enable/disable overlay menu items based on state of "Show" menu. @@ -75,7 +78,7 @@ public final class CardOverlaysMenu { prefs.save(); } - private static ActionListener getCardOverlaysAction(final FPref overlaySetting) { + private ActionListener getCardOverlaysAction(final FPref overlaySetting) { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -92,11 +95,11 @@ public final class CardOverlaysMenu { prefs.save(); } - private static void repaintCardOverlays() { + private void repaintCardOverlays() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - CMatchUI.SINGLETON_INSTANCE.repaintCardOverlays(); + matchUI.repaintCardOverlays(); } }); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/menus/DevModeMenu.java b/forge-gui-desktop/src/main/java/forge/screens/match/menus/DevModeMenu.java index 5fc90c267c3..dcc74cdd159 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/menus/DevModeMenu.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/menus/DevModeMenu.java @@ -1,24 +1,27 @@ package forge.screens.match.menus; -import forge.match.MatchUtil; -import forge.menus.MenuUtil; -import forge.screens.match.controllers.CDev; - -import javax.swing.*; - import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuItem; + +import forge.menus.MenuUtil; +import forge.screens.match.controllers.CDev; + /** * Gets a menu that replicates all the DevMode options. *

* Simply calls the associated method in CDev. */ public class DevModeMenu implements ActionListener { - private DevModeMenu() { }; - private static DevModeMenu devMenu = new DevModeMenu(); + private CDev controller; + public DevModeMenu(final CDev controller) { + this.controller = controller; + }; // Using an enum to avoid having to create multiple // ActionListeners each calling a single method. @@ -41,21 +44,21 @@ public class DevModeMenu implements ActionListener { DEV_CORNER("Developer's Corner"); protected String caption; - private DevMenuItem(String value) { + private DevMenuItem(final String value) { this.caption = value; } - protected static DevMenuItem getValue(String s) { - for (DevMenuItem t : DevMenuItem.values()) { - if (t.caption == s) + protected static DevMenuItem getValue(final String s) { + for (final DevMenuItem t : DevMenuItem.values()) { + if (t.caption == s) { return t; + } } return null; } }; - private static CDev controller = CDev.SINGLETON_INSTANCE; - - public static JMenu getMenu() { + public JMenu getMenu() { + final boolean hasController = controller.getController() != null; JMenu menu = new JMenu("Dev"); menu.setMnemonic(KeyEvent.VK_D); menu.add(getMenuItem(DevMenuItem.GENERATE_MANA)); @@ -70,8 +73,8 @@ public class DevModeMenu implements ActionListener { menu.add(getMenuItem(DevMenuItem.SETUP_GAME_STATE)); menu.add(getMenuItem(DevMenuItem.DUMP_GAME_STATE)); menu.addSeparator(); - menu.add(getCheckboxMenuItem(DevMenuItem.PLAY_UNLIMITED_LANDS, MatchUtil.getHumanController().canPlayUnlimitedLands())); - menu.add(getCheckboxMenuItem(DevMenuItem.VIEW_ALL, MatchUtil.getHumanController().mayLookAtAllCards())); + menu.add(getCheckboxMenuItem(DevMenuItem.PLAY_UNLIMITED_LANDS, hasController && controller.getController().canPlayUnlimitedLands())); + menu.add(getCheckboxMenuItem(DevMenuItem.VIEW_ALL, hasController && controller.getController().mayLookAtAllCards())); menu.add(getMenuItem(DevMenuItem.ADD_COUNTER)); menu.addSeparator(); menu.add(getMenuItem(DevMenuItem.TAP_PERMANENT)); @@ -84,16 +87,16 @@ public class DevModeMenu implements ActionListener { return menu; } - private static JMenuItem getMenuItem(DevMenuItem m) { + private JMenuItem getMenuItem(final DevMenuItem m) { JMenuItem menuItem = new JMenuItem(m.caption); - menuItem.addActionListener(devMenu); + menuItem.addActionListener(this); return menuItem; } - private static JCheckBoxMenuItem getCheckboxMenuItem(DevMenuItem m, boolean isSelected) { + private JCheckBoxMenuItem getCheckboxMenuItem(final DevMenuItem m, final boolean isSelected) { JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(m.caption); menuItem.setState(isSelected); - menuItem.addActionListener(devMenu); + menuItem.addActionListener(this); return menuItem; } @@ -101,24 +104,24 @@ public class DevModeMenu implements ActionListener { * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(final ActionEvent e) { switch (DevMenuItem.getValue(e.getActionCommand())) { - case GENERATE_MANA: { controller.generateMana(); break; } - case TUTOR_FOR_CARD: { controller.tutorForCard(); break; } - case ADD_CARD_TO_HAND: { controller.addCardToHand(); break; } - case ADD_CARD_TO_PLAY: { controller.addCardToBattlefield(); break; } - case SET_PLAYER_LIFE: { controller.setPlayerLife(); break; } - case WIN_GAME: { controller.winGame(); break; } - case SETUP_GAME_STATE: { controller.setupGameState(); break; } - case DUMP_GAME_STATE: { controller.dumpGameState(); break; } - case PLAY_UNLIMITED_LANDS: { controller.togglePlayManyLandsPerTurn(); break; } - case VIEW_ALL: { controller.toggleViewAllCards(); break; } - case ADD_COUNTER: { controller.addCounterToPermanent(); break; } - case TAP_PERMANENT: { controller.tapPermanent(); break; } - case UNTAP_PERMANENT: { controller.untapPermanent(); break; } - case RIGGED_PLANAR_ROLL:{ controller.riggedPlanerRoll(); break; } - case PLANESWALK_TO: { controller.planeswalkTo(); break; } - case DEV_CORNER: { openDevForumInBrowser(); break; } + case GENERATE_MANA: { controller.generateMana(); break; } + case TUTOR_FOR_CARD: { controller.tutorForCard(); break; } + case ADD_CARD_TO_HAND: { controller.addCardToHand(); break; } + case ADD_CARD_TO_PLAY: { controller.addCardToBattlefield(); break; } + case SET_PLAYER_LIFE: { controller.setPlayerLife(); break; } + case WIN_GAME: { controller.winGame(); break; } + case SETUP_GAME_STATE: { controller.setupGameState(); break; } + case DUMP_GAME_STATE: { controller.dumpGameState(); break; } + case PLAY_UNLIMITED_LANDS: { controller.togglePlayManyLandsPerTurn(); break; } + case VIEW_ALL: { controller.toggleViewAllCards(); break; } + case ADD_COUNTER: { controller.addCounterToPermanent(); break; } + case TAP_PERMANENT: { controller.tapPermanent(); break; } + case UNTAP_PERMANENT: { controller.untapPermanent(); break; } + case RIGGED_PLANAR_ROLL: { controller.riggedPlanerRoll(); break; } + case PLANESWALK_TO: { controller.planeswalkTo(); break; } + case DEV_CORNER: { openDevForumInBrowser(); break; } default: break; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/menus/GameMenu.java b/forge-gui-desktop/src/main/java/forge/screens/match/menus/GameMenu.java index 0f5f2fa743c..d3ceb179c4f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/menus/GameMenu.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/menus/GameMenu.java @@ -9,13 +9,13 @@ import javax.swing.JMenu; import javax.swing.JPopupMenu; import forge.assets.FSkinProp; -import forge.match.MatchUtil; import forge.menus.MenuUtil; import forge.model.FModel; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; +import forge.screens.match.CMatchUI; import forge.screens.match.VAutoYields; -import forge.screens.match.controllers.CDock; +import forge.screens.match.controllers.CDock.ArcState; import forge.toolbox.FSkin.SkinIcon; import forge.toolbox.FSkin.SkinnedCheckBoxMenuItem; import forge.toolbox.FSkin.SkinnedMenu; @@ -28,13 +28,15 @@ import forge.toolbox.FSkin.SkinnedRadioButtonMenuItem; * Replicates options available in Dock tab. */ public final class GameMenu { - private GameMenu() { } + private final CMatchUI matchUI; + public GameMenu(final CMatchUI matchUI) { + this.matchUI = matchUI; + } - private static CDock controller = CDock.SINGLETON_INSTANCE; private static ForgePreferences prefs = FModel.getPreferences(); private static boolean showIcons; - public static JMenu getMenu(boolean showMenuIcons) { + public JMenu getMenu(final boolean showMenuIcons) { JMenu menu = new JMenu("Game"); menu.setMnemonic(KeyEvent.VK_G); menu.add(getMenuItem_Undo()); @@ -43,7 +45,7 @@ public final class GameMenu { menu.add(getMenuItem_AlphaStrike()); menu.addSeparator(); menu.add(getMenuItem_TargetingArcs()); - menu.add(CardOverlaysMenu.getMenu(showMenuIcons)); + menu.add(new CardOverlaysMenu(matchUI).getMenu(showMenuIcons)); menu.add(getMenuItem_AutoYields()); menu.addSeparator(); menu.add(getMenuItem_ViewDeckList()); @@ -61,34 +63,34 @@ public final class GameMenu { private static ActionListener getSoundEffectsAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent arg0) { + public void actionPerformed(final ActionEvent e) { toggleGameSoundEffects(); } }; } private static void toggleGameSoundEffects() { - boolean isSoundEffectsEnabled = !prefs.getPrefBoolean(FPref.UI_ENABLE_SOUNDS); + final boolean isSoundEffectsEnabled = !prefs.getPrefBoolean(FPref.UI_ENABLE_SOUNDS); prefs.setPref(FPref.UI_ENABLE_SOUNDS, isSoundEffectsEnabled); prefs.save(); } - private static SkinnedMenuItem getMenuItem_Undo() { - SkinnedMenuItem menuItem = new SkinnedMenuItem("Undo"); + private SkinnedMenuItem getMenuItem_Undo() { + final SkinnedMenuItem menuItem = new SkinnedMenuItem("Undo"); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_Z)); menuItem.addActionListener(getUndoAction()); return menuItem; } - private static ActionListener getUndoAction() { + private ActionListener getUndoAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - MatchUtil.getHumanController().tryUndoLastAction(); + public void actionPerformed(final ActionEvent e) { + matchUI.getGameController().tryUndoLastAction(); } }; } - private static SkinnedMenuItem getMenuItem_Concede() { + private SkinnedMenuItem getMenuItem_Concede() { SkinnedMenuItem menuItem = new SkinnedMenuItem("Concede"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_CONCEDE) : null)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_Q)); @@ -96,65 +98,65 @@ public final class GameMenu { return menuItem; } - private static ActionListener getConcedeAction() { + private ActionListener getConcedeAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - MatchUtil.concede(); + public void actionPerformed(final ActionEvent e) { + matchUI.concede(); } }; } - private static SkinnedMenuItem getMenuItem_AlphaStrike() { - SkinnedMenuItem menuItem = new SkinnedMenuItem("Alpha Strike"); + private SkinnedMenuItem getMenuItem_AlphaStrike() { + final SkinnedMenuItem menuItem = new SkinnedMenuItem("Alpha Strike"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_ALPHASTRIKE) : null)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_A)); menuItem.addActionListener(getAlphaStrikeAction()); return menuItem; } - private static ActionListener getAlphaStrikeAction() { + private ActionListener getAlphaStrikeAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - MatchUtil.alphaStrike(); + public void actionPerformed(final ActionEvent e) { + matchUI.getGameController().alphaStrike(); } }; } - private static SkinnedMenuItem getMenuItem_EndTurn() { - SkinnedMenuItem menuItem = new SkinnedMenuItem("End Turn"); + private SkinnedMenuItem getMenuItem_EndTurn() { + final SkinnedMenuItem menuItem = new SkinnedMenuItem("End Turn"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_ENDTURN) : null)); menuItem.setAccelerator(MenuUtil.getAcceleratorKey(KeyEvent.VK_E)); menuItem.addActionListener(getEndTurnAction()); return menuItem; } - private static ActionListener getEndTurnAction() { + private ActionListener getEndTurnAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - controller.endTurn(); + public void actionPerformed(final ActionEvent e) { + matchUI.getGameController().passPriorityUntilEndOfTurn(); } }; } - private static SkinnedMenu getMenuItem_TargetingArcs() { - SkinnedMenu menu = new SkinnedMenu("Targeting Arcs"); - ButtonGroup group = new ButtonGroup(); + private SkinnedMenu getMenuItem_TargetingArcs() { + final SkinnedMenu menu = new SkinnedMenu("Targeting Arcs"); + final ButtonGroup group = new ButtonGroup(); SkinIcon menuIcon = MenuUtil.getMenuIcon(FSkinProp.ICO_ARCSOFF); SkinnedRadioButtonMenuItem menuItem; - menuItem = getTargetingArcRadioButton("Off", FSkinProp.ICO_ARCSOFF, 0); + menuItem = getTargetingArcRadioButton("Off", FSkinProp.ICO_ARCSOFF, ArcState.OFF); if (menuItem.isSelected()) { menuIcon = MenuUtil.getMenuIcon(FSkinProp.ICO_ARCSOFF); } group.add(menuItem); menu.add(menuItem); - menuItem = getTargetingArcRadioButton("Card mouseover", FSkinProp.ICO_ARCSHOVER, 1); + menuItem = getTargetingArcRadioButton("Card mouseover", FSkinProp.ICO_ARCSHOVER, ArcState.MOUSEOVER); if (menuItem.isSelected()) { menuIcon = MenuUtil.getMenuIcon(FSkinProp.ICO_ARCSHOVER); } group.add(menuItem); menu.add(menuItem); - menuItem = getTargetingArcRadioButton("Always On", FSkinProp.ICO_ARCSON, 2); + menuItem = getTargetingArcRadioButton("Always On", FSkinProp.ICO_ARCSON, ArcState.ON); if (menuItem.isSelected()) { menuIcon = MenuUtil.getMenuIcon(FSkinProp.ICO_ARCSON); } group.add(menuItem); @@ -164,61 +166,61 @@ public final class GameMenu { return menu; } - private static SkinnedRadioButtonMenuItem getTargetingArcRadioButton(String caption, FSkinProp icon, final int arcState) { + private SkinnedRadioButtonMenuItem getTargetingArcRadioButton(final String caption, final FSkinProp icon, final ArcState arcState) { final SkinnedRadioButtonMenuItem menuItem = new SkinnedRadioButtonMenuItem(caption); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(icon) : null)); - menuItem.setSelected(arcState == controller.getArcState()); + menuItem.setSelected(arcState == matchUI.getCDock().getArcState()); menuItem.addActionListener(getTargetingRadioButtonAction(arcState)); return menuItem; } - private static ActionListener getTargetingRadioButtonAction(final int arcState) { + private ActionListener getTargetingRadioButtonAction(final ArcState arcState) { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - prefs.setPref(FPref.UI_TARGETING_OVERLAY, String.valueOf(arcState)); + public void actionPerformed(final ActionEvent e) { + prefs.setPref(FPref.UI_TARGETING_OVERLAY, String.valueOf(arcState.ordinal())); prefs.save(); - controller.setArcState(arcState); + matchUI.getCDock().setArcState(arcState); setTargetingArcMenuIcon((SkinnedRadioButtonMenuItem)e.getSource()); } }; } private static void setTargetingArcMenuIcon(SkinnedRadioButtonMenuItem item) { - JPopupMenu pop = (JPopupMenu)item.getParent(); - JMenu menu = (JMenu)pop.getInvoker(); + final JPopupMenu pop = (JPopupMenu)item.getParent(); + final JMenu menu = (JMenu)pop.getInvoker(); menu.setIcon(item.getIcon()); } - private static SkinnedMenuItem getMenuItem_AutoYields() { - SkinnedMenuItem menuItem = new SkinnedMenuItem("Auto-Yields"); + private SkinnedMenuItem getMenuItem_AutoYields() { + final SkinnedMenuItem menuItem = new SkinnedMenuItem("Auto-Yields"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_WARNING) : null)); menuItem.addActionListener(getAutoYieldsAction()); return menuItem; } - private static ActionListener getAutoYieldsAction() { + private ActionListener getAutoYieldsAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - final VAutoYields autoYields = new VAutoYields(MatchUtil.getHumanController()); + public void actionPerformed(final ActionEvent e) { + final VAutoYields autoYields = new VAutoYields(matchUI); autoYields.showAutoYields(); } }; } - private static SkinnedMenuItem getMenuItem_ViewDeckList() { - SkinnedMenuItem menuItem = new SkinnedMenuItem("Deck List"); + private SkinnedMenuItem getMenuItem_ViewDeckList() { + final SkinnedMenuItem menuItem = new SkinnedMenuItem("Deck List"); menuItem.setIcon((showIcons ? MenuUtil.getMenuIcon(FSkinProp.ICO_DECKLIST) : null)); menuItem.addActionListener(getViewDeckListAction()); return menuItem; } - private static ActionListener getViewDeckListAction() { + private ActionListener getViewDeckListAction() { return new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - controller.viewDeckList(); + public void actionPerformed(final ActionEvent e) { + matchUI.viewDeckList(); } }; } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VAntes.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VAntes.java index 527850c6817..15e11e90a93 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VAntes.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VAntes.java @@ -25,6 +25,7 @@ import javax.swing.JPanel; import javax.swing.SwingConstants; import net.miginfocom.swing.MigLayout; +import forge.game.GameView; import forge.game.card.CardView; import forge.game.player.PlayerView; import forge.gui.CardPicturePanel; @@ -33,7 +34,6 @@ import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.MatchUtil; import forge.screens.match.controllers.CAntes; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; @@ -43,9 +43,8 @@ import forge.toolbox.FScrollPane; * *

(V at beginning of class name denotes a view class.) */ -public enum VAntes implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VAntes implements IVDoc { + private final CAntes controller; // Fields used with interface IVDoc private DragCell parentCell; @@ -56,7 +55,8 @@ public enum VAntes implements IVDoc { private final SortedSet allAntes = new TreeSet(); //========== Constructor - private VAntes() { + public VAntes(final CAntes controller) { + this.controller = controller; pnl.setLayout(new WrapLayout()); pnl.setOpaque(false); } @@ -113,15 +113,19 @@ public enum VAntes implements IVDoc { */ @Override public CAntes getLayoutControl() { - return CAntes.SINGLETON_INSTANCE; + return controller; } public void update() { allAntes.clear(); pnl.removeAll(); + final GameView gameView = controller.getMatchUI().getGameView(); + if (gameView == null) { + return; + } - for (final PlayerView p : MatchUtil.getGameView().getPlayers()) { - Iterable ante = p.getAnte(); + for (final PlayerView p : gameView.getPlayers()) { + final Iterable ante = p.getAnte(); if (ante != null) { for (final CardView c : ante) { final AntePanel pnlTemp = new AntePanel(c); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VCombat.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VCombat.java index fd8cca3a350..0b4a21b510c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VCombat.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VCombat.java @@ -31,17 +31,17 @@ import net.miginfocom.swing.MigLayout; * *

(V at beginning of class name denotes a view class.) */ -public enum VCombat implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VCombat implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; private final DragTab tab = new DragTab("Combat"); - - final SkinnedTextArea tar = new SkinnedTextArea(); - private VCombat() { + private final SkinnedTextArea tar = new SkinnedTextArea(); + + private final CCombat controller; + public VCombat(final CCombat controller) { + this.controller = controller; tar.setOpaque(false); tar.setBorder(new FSkin.MatteSkinBorder(0, 0, 0, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); tar.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); @@ -98,7 +98,7 @@ public enum VCombat implements IVDoc { */ @Override public CCombat getLayoutControl() { - return CCombat.SINGLETON_INSTANCE; + return controller; } //========= Observer update methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VCommand.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VCommand.java index 1868c7e53ce..762ac52ff84 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VCommand.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VCommand.java @@ -26,6 +26,7 @@ import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; +import forge.screens.match.CMatchUI; import forge.screens.match.controllers.CCommand; import forge.toolbox.FScrollPane; import forge.toolbox.FSkin; @@ -57,9 +58,8 @@ public class VCommand implements IVDoc { * @param p   {@link forge.game.player.Player} * @param id0   {@link forge.gui.framework.EDocID} */ - public VCommand(final EDocID id0, final PlayerView p) { + public VCommand(final CMatchUI matchUI, final EDocID id0, final PlayerView p) { this.docID = id0; - id0.setDoc(this); this.player = p; if (p != null) { tab.setText(p.getName() + " Command"); } @@ -67,7 +67,7 @@ public class VCommand implements IVDoc { // TODO player is hard-coded into tabletop...should be dynamic // (haven't looked into it too deeply). Doublestrike 12-04-12 - tabletop = new PlayArea(scroller, id0 == EDocID.COMMAND_0, player, ZoneType.Command); + tabletop = new PlayArea(matchUI, scroller, id0 == EDocID.COMMAND_0, player, ZoneType.Command); control = new CCommand(player, this); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDetail.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDetail.java index e3c31cb2887..2df679b7e25 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDetail.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDetail.java @@ -35,9 +35,7 @@ import javax.swing.*; * *

(V at beginning of class name denotes a view class.) */ -public enum VDetail implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VDetail implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -47,8 +45,11 @@ public enum VDetail implements IVDoc { private final CardDetailPanel pnlDetail = new CardDetailPanel(); private final SkinnedLabel lblFlipcard = new SkinnedLabel(); + private final CDetail controller; + //========= Constructor - private VDetail() { + public VDetail(final CDetail controller) { + this.controller = controller; lblFlipcard.setIcon(FSkin.getIcon(FSkinProp.ICO_FLIPCARD)); lblFlipcard.setVisible(false); } @@ -101,7 +102,7 @@ public enum VDetail implements IVDoc { */ @Override public CDetail getLayoutControl() { - return CDetail.SINGLETON_INSTANCE; + return controller; } //========= Retrieval methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java index 6ad51109fbb..bbf81053d85 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDev.java @@ -41,9 +41,7 @@ import forge.toolbox.FSkin.SkinnedLabel; * *

(V at beginning of class name denotes a view class.) */ -public enum VDev implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VDev implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -72,9 +70,13 @@ public enum VDev implements IVDoc { private final DevLabel lblRiggedRoll = new DevLabel("Rigged Planar Roll"); private final DevLabel lblWalkTo = new DevLabel("Planeswalk to"); + private final CDev controller; + //========= Constructor - private VDev() { + public VDev(final CDev controller) { + this.controller = controller; + final String constraints = "w 95%!, gap 0 0 4px 0"; final String halfConstraints = "w 47%!, gap 0 0 4px 0"; final String halfConstraintsLeft = halfConstraints + ", split 2"; @@ -144,7 +146,7 @@ public enum VDev implements IVDoc { */ @Override public CDev getLayoutControl() { - return CDev.SINGLETON_INSTANCE; + return controller; } //========= Retrieval methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDock.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDock.java index e7b93657e37..6015cb082a7 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VDock.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VDock.java @@ -38,9 +38,7 @@ import java.awt.event.MouseEvent; * *

(V at beginning of class name denotes a view class.) */ -public enum VDock implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VDock implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -58,7 +56,11 @@ public enum VDock implements IVDoc { private final FLabel btnTargeting = new FLabel.Builder().icon(FSkin.getIcon(FSkinProp.ICO_ARCSOFF)) .hoverable(true).iconInBackground(true).iconScaleFactor(1.0).build(); - private VDock() { + private final CDock controller; + + public VDock(final CDock controller) { + this.controller = controller; + btnTargeting.setPreferredSize(new Dimension(30, 30)); btnTargeting.setMinimumSize(new Dimension(30, 30)); btnTargeting.setMaximumSize(new Dimension(30, 30)); @@ -124,7 +126,7 @@ public enum VDock implements IVDoc { */ @Override public CDock getLayoutControl() { - return CDock.SINGLETON_INSTANCE; + return controller; } //========= Retrieval methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java index 3675184f170..e6ecfb4c1ac 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VField.java @@ -34,7 +34,7 @@ import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.MatchUtil; +import forge.screens.match.CMatchUI; import forge.screens.match.controllers.CField; import forge.toolbox.FLabel; import forge.toolbox.FScrollPane; @@ -83,9 +83,8 @@ public class VField implements IVDoc { * @param p   {@link forge.game.player.Player} * @param id0   {@link forge.gui.framework.EDocID} */ - public VField(final EDocID id0, final PlayerView p) { + public VField(final CMatchUI matchUI, final EDocID id0, final PlayerView p) { this.docID = id0; - id0.setDoc(this); this.player = p; if (p != null) { tab.setText(p.getName() + " Field"); } @@ -95,9 +94,9 @@ public class VField implements IVDoc { // TODO player is hard-coded into tabletop...should be dynamic // (haven't looked into it too deeply). Doublestrike 12-04-12 - tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1, player, ZoneType.Battlefield); + tabletop = new PlayArea(matchUI, scroller, false, player, ZoneType.Battlefield); - control = new CField(player, this); + control = new CField(matchUI, player, this); lblAvatar.setFocusable(false); lblLife.setFocusable(false); @@ -200,10 +199,11 @@ public class VField implements IVDoc { } public boolean isHighlighted() { - return MatchUtil.isHighlighted(player); + return control.getMatchUI().isHighlighted(player); } public void updateDetails() { + control.getMatchUI().getCPlayers().update(); detailsPanel.updateDetails(); this.getLblLife().setText("" + player.getLife()); diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VHand.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VHand.java index 58adfbdc3e6..9194c938540 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VHand.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VHand.java @@ -25,6 +25,7 @@ import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; +import forge.screens.match.CMatchUI; import forge.screens.match.controllers.CHand; import forge.toolbox.FScrollPane; import forge.view.arcane.HandArea; @@ -43,7 +44,7 @@ public class VHand implements IVDoc { // Top-level containers private final FScrollPane scroller = new FScrollPane(false); - private final HandArea hand = new HandArea(scroller); + private final HandArea hand; //========= Constructor /** @@ -52,7 +53,8 @@ public class VHand implements IVDoc { * @param id0   {@link forge.gui.framework.EDocID} * @param p   {@link forge.game.player.Player} */ - public VHand(final EDocID id0, final PlayerView p) { + public VHand(final CMatchUI matchUI, final EDocID id0, final PlayerView p) { + this.hand = new HandArea(matchUI, scroller); docID = id0; id0.setDoc(this); @@ -66,7 +68,7 @@ public class VHand implements IVDoc { hand.setOpaque(false); - control = new CHand(p, this); + control = new CHand(matchUI, p, this); } //========= Overridden methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VLog.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VLog.java index 2d654d2d495..8a166b945a4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VLog.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VLog.java @@ -17,8 +17,8 @@ */ package forge.screens.match.views; -import java.util.List; import java.util.ArrayList; +import java.util.List; import javax.swing.JPanel; @@ -33,7 +33,6 @@ import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.screens.match.GameLogPanel; @@ -46,9 +45,7 @@ import forge.toolbox.FSkin.SkinFont; * *

(V at beginning of class name denotes a view class.) */ -public enum VLog implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VLog implements IVDoc { // Keeps a record of log entries currently displayed so we can // easily identify new entries to be added to the game log. @@ -65,8 +62,11 @@ public enum VLog implements IVDoc { private GameLogPanel gameLog; private JPanel p = null; + private final CLog controller; + //========== Constructor - private VLog() { + public VLog(final CLog controller) { + this.controller = controller; gameLog = new GameLogPanel(); } @@ -116,7 +116,7 @@ public enum VLog implements IVDoc { */ @Override public CLog getLayoutControl() { - return CLog.SINGLETON_INSTANCE; + return controller; } /** @@ -127,8 +127,8 @@ public enum VLog implements IVDoc { * @param model contains list of log entries. */ public void updateConsole() { - if (isGameLogConsoleVisible()) { - GameView model = MatchUtil.getGameView(); + final GameView model = controller.getMatchUI().getGameView(); + if (isGameLogConsoleVisible() && model != null) { resetDisplayIfNewGame(model); displayNewGameLogEntries(model); // Important : refreshLayout() needs to be called every update. diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPicture.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPicture.java index a007aa8ddb1..ebf760aaffb 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPicture.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPicture.java @@ -35,9 +35,7 @@ import javax.swing.*; * *

(V at beginning of class name denotes a view class.) */ -public enum VPicture implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VPicture implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -47,8 +45,11 @@ public enum VPicture implements IVDoc { private final CardPicturePanel pnlPicture = new CardPicturePanel(); private final SkinnedLabel lblFlipcard = new SkinnedLabel(); + private final CPicture controller; + //========= Constructor - private VPicture() { + public VPicture(final CPicture controller) { + this.controller = controller; lblFlipcard.setIcon(FSkin.getIcon(FSkinProp.ICO_FLIPCARD)); pnlPicture.setOpaque(false); lblFlipcard.setVisible(false); @@ -103,7 +104,7 @@ public enum VPicture implements IVDoc { */ @Override public CPicture getLayoutControl() { - return CPicture.SINGLETON_INSTANCE; + return controller; } //========== Retrieval methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPlayers.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPlayers.java index 87c84850ea6..0ccf115cc3f 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPlayers.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPlayers.java @@ -25,17 +25,16 @@ import java.util.Map.Entry; import javax.swing.JLabel; import javax.swing.ScrollPaneConstants; +import net.miginfocom.swing.MigLayout; + import com.google.common.collect.Lists; -import net.miginfocom.swing.MigLayout; -import forge.game.card.CardFactoryUtil; import forge.game.card.CardView; import forge.game.player.PlayerView; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.screens.match.controllers.CPlayers; @@ -48,9 +47,7 @@ import forge.toolbox.FSkin.SkinnedLabel; * *

(V at beginning of class name denotes a view class.) */ -public enum VPlayers implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VPlayers implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -62,6 +59,12 @@ public enum VPlayers implements IVDoc { // Other fields private Map infoLBLs; + private final CPlayers controller; + + public VPlayers(final CPlayers controller) { + this.controller = controller; + } + //========= Overridden methods /* (non-Javadoc) @@ -137,7 +140,7 @@ public enum VPlayers implements IVDoc { */ @Override public CPlayers getLayoutControl() { - return CPlayers.SINGLETON_INSTANCE; + return controller; } //========== Observer update methods @@ -146,7 +149,7 @@ public enum VPlayers implements IVDoc { public void update() { // No need to update if this panel isn't showing if (parentCell == null || !this.equals(parentCell.getSelected())) { return; } - boolean isCommander = MatchUtil.getGameView().isCommander(); + boolean isCommander = controller.getMatchUI().getGameView().isCommander(); for(final Entry rr : infoLBLs.entrySet()) { PlayerView p0 = rr.getKey(); @@ -180,7 +183,7 @@ public enum VPlayers implements IVDoc { temp[6].setText(sb.toString()); } if (isCommander) { - temp[7].setText(CardFactoryUtil.getCommanderInfo(p0)); + temp[7].setText(p0.getCommanderInfo()); } } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPrompt.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPrompt.java index cb7c73756b8..aaeff350882 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VPrompt.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VPrompt.java @@ -39,9 +39,7 @@ import java.awt.event.KeyEvent; * *

(V at beginning of class name denotes a view class.) */ -public enum VPrompt implements IVDoc { - /** */ - SINGLETON_INSTANCE; +public class VPrompt implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -66,8 +64,12 @@ public enum VPrompt implements IVDoc { } }; + private final CPrompt controller; + //========= Constructor - private VPrompt() { + public VPrompt(final CPrompt controller) { + this.controller = controller; + lblGames = new FLabel.Builder() .fontSize(12) .fontStyle(Font.PLAIN) @@ -142,7 +144,7 @@ public enum VPrompt implements IVDoc { */ @Override public CPrompt getLayoutControl() { - return CPrompt.SINGLETON_INSTANCE; + return controller; } /* (non-Javadoc) diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java index 68716224b72..cc460499162 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java @@ -39,31 +39,24 @@ import forge.ImageCache; import forge.card.CardDetailUtil; import forge.card.CardDetailUtil.DetailColors; import forge.game.GameView; -import forge.game.player.PlayerView; import forge.game.spellability.StackItemView; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; -import forge.match.MatchUtil; -import forge.player.PlayerControllerHuman; -import forge.screens.match.CMatchUI; -import forge.screens.match.controllers.CPrompt; import forge.screens.match.controllers.CStack; import forge.toolbox.FMouseAdapter; import forge.toolbox.FScrollPanel; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedTextArea; import forge.util.FCollectionView; -import forge.view.arcane.CardPanel; /** * Assembles Swing components of stack report. * *

(V at beginning of class name denotes a view class.) */ -public enum VStack implements IVDoc { - SINGLETON_INSTANCE; +public class VStack implements IVDoc { // Fields used with interface IVDoc private DragCell parentCell; @@ -74,7 +67,7 @@ public enum VStack implements IVDoc { ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); // Other fields - private static AbilityMenu abilityMenu = new AbilityMenu(); + private final AbilityMenu abilityMenu = new AbilityMenu(); private static StackInstanceTextArea hoveredItem; @@ -82,7 +75,9 @@ public enum VStack implements IVDoc { return hoveredItem; } - private VStack() { + private final CStack controller; + public VStack(final CStack controller) { + this.controller = controller; } @Override @@ -113,11 +108,11 @@ public enum VStack implements IVDoc { @Override public CStack getLayoutControl() { - return CStack.SINGLETON_INSTANCE; + return controller; } public void updateStack() { - final GameView model = MatchUtil.getGameView(); + final GameView model = controller.getMatchUI().getGameView(); if (model == null) { return; @@ -141,7 +136,7 @@ public enum VStack implements IVDoc { //update the Card Picture/Detail when the spell is added to the stack if (isFirst) { isFirst = false; - CMatchUI.SINGLETON_INSTANCE.setCard(item.getSourceCard()); + controller.getMatchUI().setCard(item.getSourceCard()); } } @@ -157,10 +152,10 @@ public enum VStack implements IVDoc { } @SuppressWarnings("serial") - public static class StackInstanceTextArea extends SkinnedTextArea { + public class StackInstanceTextArea extends SkinnedTextArea { public static final int PADDING = 3; public static final int CARD_WIDTH = 50; - public static final int CARD_HEIGHT = Math.round((float)CARD_WIDTH * CardPanel.ASPECT_RATIO); + public static final int CARD_HEIGHT = 70;//Math.round((float)CARD_WIDTH * CardPanel.ASPECT_RATIO); private final StackItemView item; @@ -185,8 +180,7 @@ public enum VStack implements IVDoc { public StackInstanceTextArea(final GameView gameView, final StackItemView item0) { item = item0; - final PlayerView localPlayer = PlayerView.get(MatchUtil.getCurrentPlayer()); - final String txt = (item.isOptionalTrigger() && item.getActivatingPlayer().equals(localPlayer) + final String txt = (item.isOptionalTrigger() && controller.getMatchUI().isLocalPlayer(item.getActivatingPlayer()) ? "(OPTIONAL) " : "") + item.getText(); setText(txt); @@ -204,7 +198,7 @@ public enum VStack implements IVDoc { public void mouseEntered(final MouseEvent e) { hoveredItem = StackInstanceTextArea.this; if (!txt.startsWith("Morph ")) { - CMatchUI.SINGLETON_INSTANCE.setCard(item.getSourceCard()); + controller.getMatchUI().setCard(item.getSourceCard()); } } @@ -216,7 +210,7 @@ public enum VStack implements IVDoc { } }); - if (item.isAbility() && localPlayer != null) { + if (item.isAbility()) { addMouseListener(new FMouseAdapter() { @Override public void onLeftClick(MouseEvent e) { @@ -227,7 +221,7 @@ public enum VStack implements IVDoc { onClick(e); } private void onClick(MouseEvent e) { - abilityMenu.setStackInstance(MatchUtil.getHumanController(), item, localPlayer); + abilityMenu.setStackInstance(item); abilityMenu.show(e.getComponent(), e.getX(), e.getY()); } }); @@ -245,7 +239,7 @@ public enum VStack implements IVDoc { final Graphics2D g2d = (Graphics2D) g; //draw image for source card - final BufferedImage img = ImageCache.getImage(item.getSourceCard(), CARD_WIDTH, CARD_HEIGHT); + final BufferedImage img = ImageCache.getImage(item.getSourceCard(), controller.getMatchUI().getCurrentPlayer(), CARD_WIDTH, CARD_HEIGHT); if (img != null) { g2d.drawImage(img, null, PADDING, PADDING); } @@ -254,12 +248,11 @@ public enum VStack implements IVDoc { //========= Custom class handling - private final static class AbilityMenu extends JPopupMenu { + private final class AbilityMenu extends JPopupMenu { private static final long serialVersionUID = 1548494191627807962L; private final JCheckBoxMenuItem jmiAutoYield; private final JCheckBoxMenuItem jmiAlwaysYes; private final JCheckBoxMenuItem jmiAlwaysNo; - private PlayerControllerHuman humanController; private StackItemView item; private Integer triggerID = 0; @@ -270,11 +263,11 @@ public enum VStack implements IVDoc { @Override public void actionPerformed(ActionEvent arg0) { final String key = item.getKey(); - final boolean autoYield = humanController.shouldAutoYield(key); - humanController.setShouldAutoYield(key, !autoYield); - if (!autoYield && MatchUtil.getGameView().peekStack() == item) { + final boolean autoYield = controller.getMatchUI().shouldAutoYield(key); + controller.getMatchUI().setShouldAutoYield(key, !autoYield); + if (!autoYield && controller.getMatchUI().getGameView().peekStack() == item) { //auto-pass priority if ability is on top of stack - CPrompt.SINGLETON_INSTANCE.passPriority(); + controller.getMatchUI().getCPrompt().passPriority(); } } }); @@ -284,14 +277,14 @@ public enum VStack implements IVDoc { jmiAlwaysYes.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - if (humanController.shouldAlwaysAcceptTrigger(triggerID)) { - humanController.setShouldAlwaysAskTrigger(triggerID); + if (controller.getMatchUI().shouldAlwaysAcceptTrigger(triggerID)) { + controller.getMatchUI().setShouldAlwaysAskTrigger(triggerID); } else { - humanController.setShouldAlwaysAcceptTrigger(triggerID); - if (MatchUtil.getGameView().peekStack() == item) { + controller.getMatchUI().setShouldAlwaysAcceptTrigger(triggerID); + if (controller.getMatchUI().getGameView().peekStack() == item) { //auto-yes if ability is on top of stack - humanController.confirm(); + controller.getMatchUI().getGameController().selectButtonOk(); } } } @@ -302,14 +295,14 @@ public enum VStack implements IVDoc { jmiAlwaysNo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - if (humanController.shouldAlwaysDeclineTrigger(triggerID)) { - humanController.setShouldAlwaysAskTrigger(triggerID); + if (controller.getMatchUI().shouldAlwaysDeclineTrigger(triggerID)) { + controller.getMatchUI().setShouldAlwaysAskTrigger(triggerID); } else { - humanController.setShouldAlwaysDeclineTrigger(triggerID); - if (MatchUtil.getGameView().peekStack() == item) { + controller.getMatchUI().setShouldAlwaysDeclineTrigger(triggerID); + if (controller.getMatchUI().getGameView().peekStack() == item) { //auto-no if ability is on top of stack - humanController.confirm(); + controller.getMatchUI().getGameController().selectButtonCancel(); } } } @@ -317,20 +310,18 @@ public enum VStack implements IVDoc { add(jmiAlwaysNo); } - public void setStackInstance(final PlayerControllerHuman humanController0, final StackItemView item0, final PlayerView localPlayer0) { - humanController = humanController0; + public void setStackInstance(final StackItemView item0) { item = item0; triggerID = Integer.valueOf(item.getSourceTrigger()); - jmiAutoYield.setSelected(humanController.shouldAutoYield(item.getKey())); + jmiAutoYield.setSelected(controller.getMatchUI().shouldAutoYield(item.getKey())); - if (item.isOptionalTrigger() && item.getActivatingPlayer().equals(localPlayer0)) { - jmiAlwaysYes.setSelected(humanController.shouldAlwaysAcceptTrigger(triggerID)); - jmiAlwaysNo.setSelected(humanController.shouldAlwaysDeclineTrigger(triggerID)); + if (item.isOptionalTrigger() && controller.getMatchUI().isLocalPlayer(item.getActivatingPlayer())) { + jmiAlwaysYes.setSelected(controller.getMatchUI().shouldAlwaysAcceptTrigger(triggerID)); + jmiAlwaysNo.setSelected(controller.getMatchUI().shouldAlwaysDeclineTrigger(triggerID)); jmiAlwaysYes.setVisible(true); jmiAlwaysNo.setVisible(true); - } - else { + } else { jmiAlwaysYes.setVisible(false); jmiAlwaysNo.setVisible(false); } diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/CWorkshopUI.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/CWorkshopUI.java index c19faccb07e..a0ea2c8fbb8 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/CWorkshopUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/CWorkshopUI.java @@ -17,15 +17,18 @@ */ package forge.screens.workshop; -import forge.UiCommand; +import java.util.List; + +import javax.swing.JMenu; + import forge.Singletons; +import forge.UiCommand; +import forge.gui.framework.EDocID; import forge.gui.framework.ICDoc; import forge.menus.IMenuProvider; +import forge.screens.match.controllers.CDetailPicture; import forge.screens.workshop.menus.CWorkshopUIMenus; - -import javax.swing.*; - -import java.util.List; +import forge.screens.workshop.views.VWorkshopCatalog; /** * Constructs instance of workshop UI controller, used as a single point of @@ -58,6 +61,13 @@ public enum CWorkshopUI implements ICDoc, IMenuProvider { return null; } + @Override + public void register() { + final CDetailPicture cDetailPicture = VWorkshopCatalog.SINGLETON_INSTANCE.getCDetailPicture(); + EDocID.CARD_PICTURE.setDoc(cDetailPicture.getCPicture().getView()); + EDocID.CARD_DETAIL.setDoc(cDetailPicture.getCDetail().getView()); + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardDesigner.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardDesigner.java index 786f8bebf4e..d32b91cc431 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardDesigner.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardDesigner.java @@ -34,6 +34,10 @@ public enum CCardDesigner implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardScript.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardScript.java index a0b2adaa5c9..e97dedd6faf 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardScript.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CCardScript.java @@ -1,29 +1,33 @@ package forge.screens.workshop.controllers; -import forge.UiCommand; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.util.Arrays; +import java.util.Map.Entry; + +import javax.swing.JTextPane; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.Style; +import javax.swing.text.StyledDocument; + import forge.Singletons; +import forge.UiCommand; import forge.card.CardDb; import forge.card.CardRules; import forge.card.CardScriptInfo; +import forge.card.CardScriptParser; import forge.game.card.Card; import forge.gui.framework.FScreen; import forge.gui.framework.ICDoc; import forge.item.PaperCard; import forge.model.FModel; -import forge.screens.match.controllers.CDetail; -import forge.screens.match.controllers.CPicture; +import forge.properties.ForgePreferences.FPref; import forge.screens.workshop.menus.WorkshopFileMenu; import forge.screens.workshop.views.VCardDesigner; import forge.screens.workshop.views.VCardScript; import forge.screens.workshop.views.VWorkshopCatalog; import forge.toolbox.FOptionPane; -import forge.toolbox.FTextEditor; - -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import java.util.Arrays; - /** * Controls the "card script" panel in the workshop UI. @@ -41,22 +45,29 @@ public enum CCardScript implements ICDoc { private boolean switchInProgress; private CCardScript() { - VCardScript.SINGLETON_INSTANCE.getTxtScript().addDocumentListener(new DocumentListener() { + VCardScript.SINGLETON_INSTANCE.getTxtScript().getDocument().addDocumentListener(new DocumentListener() { @Override - public void removeUpdate(DocumentEvent arg0) { + public void removeUpdate(final DocumentEvent arg0) { updateDirtyFlag(); } - @Override - public void insertUpdate(DocumentEvent arg0) { + public void insertUpdate(final DocumentEvent arg0) { updateDirtyFlag(); } - @Override - public void changedUpdate(DocumentEvent arg0) { + public void changedUpdate(final DocumentEvent arg0) { //Plain text components do not fire these events } }); + VCardScript.SINGLETON_INSTANCE.getTxtScript().addFocusListener(new FocusListener() { + @Override + public void focusLost(final FocusEvent e) { + refresh(); + } + @Override + public void focusGained(final FocusEvent e) { + } + }); } private void updateDirtyFlag() { @@ -86,10 +97,18 @@ public enum CCardScript implements ICDoc { } public void refresh() { - FTextEditor txtScript = VCardScript.SINGLETON_INSTANCE.getTxtScript(); + final JTextPane txtScript = VCardScript.SINGLETON_INSTANCE.getTxtScript(); txtScript.setText(currentScriptInfo != null ? currentScriptInfo.getText() : ""); txtScript.setEditable(currentScriptInfo != null ? currentScriptInfo.canEdit() : false); txtScript.setCaretPosition(0); //keep scrolled to top + + final StyledDocument doc = VCardScript.SINGLETON_INSTANCE.getDoc(); + final Style error = VCardScript.SINGLETON_INSTANCE.getErrorStyle(); + if (FModel.getPreferences().getPrefBoolean(FPref.DEV_WORKSHOP_SYNTAX) && currentScriptInfo != null) { + for (final Entry region : new CardScriptParser(currentScriptInfo.getText()).getErrorRegions().entrySet()) { + doc.setCharacterAttributes(region.getKey(), region.getValue(), error, true); + } + } } public boolean hasChanges() { @@ -144,8 +163,8 @@ public enum CCardScript implements ICDoc { } VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().repaint(); - CDetail.SINGLETON_INSTANCE.showCard(currentCard); - CPicture.SINGLETON_INSTANCE.showImage(currentCard); + VWorkshopCatalog.SINGLETON_INSTANCE.getCDetailPicture().showItem(currentCard); + refresh(); return true; } @@ -159,6 +178,10 @@ public enum CCardScript implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CWorkshopCatalog.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CWorkshopCatalog.java index 874e183e69f..6c24ba0f4de 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CWorkshopCatalog.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/controllers/CWorkshopCatalog.java @@ -28,6 +28,10 @@ public enum CWorkshopCatalog implements ICDoc { return null; } + @Override + public void register() { + } + /* (non-Javadoc) * @see forge.gui.framework.ICDoc#initialize() */ diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VCardScript.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VCardScript.java index 7f2122eae0a..e6e3987faff 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VCardScript.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VCardScript.java @@ -1,14 +1,21 @@ package forge.screens.workshop.views; +import java.awt.Color; + +import javax.swing.JPanel; +import javax.swing.JTextPane; +import javax.swing.text.DefaultStyledDocument; +import javax.swing.text.Style; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; + +import net.miginfocom.swing.MigLayout; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; import forge.screens.workshop.controllers.CCardScript; -import forge.toolbox.FTextEditor; -import net.miginfocom.swing.MigLayout; - -import javax.swing.*; +import forge.toolbox.FTextPane; /** * Assembles Swing components of workshop card script tab. @@ -23,14 +30,31 @@ public enum VCardScript implements IVDoc { private DragCell parentCell; private final DragTab tab = new DragTab("Card Script"); - private final FTextEditor txtScript = new FTextEditor(); + private final FTextPane txtScript = new FTextPane(); + private final StyledDocument doc; + private final Style error; //========== Constructor private VCardScript() { + txtScript.setEditable(true); + txtScript.setFocusable(true); + doc = new DefaultStyledDocument(); + txtScript.setDocument(doc); + error = doc.addStyle("error", null); + error.addAttribute(StyleConstants.Background, Color.red); + error.addAttribute(StyleConstants.Bold, new Boolean(true)); } - - public FTextEditor getTxtScript() { - return txtScript; + + public JTextPane getTxtScript() { + return txtScript; + } + + public StyledDocument getDoc() { + return doc; + } + + public Style getErrorStyle() { + return error; } //========== Overridden methods diff --git a/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VWorkshopCatalog.java b/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VWorkshopCatalog.java index fef6c9f0de8..2197a9c6b10 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VWorkshopCatalog.java +++ b/forge-gui-desktop/src/main/java/forge/screens/workshop/views/VWorkshopCatalog.java @@ -1,5 +1,11 @@ package forge.screens.workshop.views; +import javax.swing.JPanel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import net.miginfocom.swing.MigLayout; + import com.google.common.collect.Iterables; import forge.gui.framework.DragCell; @@ -10,16 +16,10 @@ import forge.item.PaperCard; import forge.itemmanager.CardManager; import forge.itemmanager.ItemManagerContainer; import forge.model.FModel; -import forge.screens.match.controllers.CDetail; -import forge.screens.match.controllers.CPicture; +import forge.screens.match.controllers.CDetailPicture; import forge.screens.workshop.controllers.CCardScript; import forge.screens.workshop.controllers.CWorkshopCatalog; import forge.util.ItemPool; -import net.miginfocom.swing.MigLayout; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; /** * Assembles Swing components of card catalog in workshop. @@ -38,22 +38,22 @@ public enum VWorkshopCatalog implements IVDoc { private final DragTab tab = new DragTab("Card Catalog"); private final ItemManagerContainer cardManagerContainer = new ItemManagerContainer(); private final CardManager cardManager; + private final CDetailPicture cDetailPicture = new CDetailPicture(); //========== Constructor /** */ private VWorkshopCatalog() { - this.cardManager = new CardManager(true); + this.cardManager = new CardManager(cDetailPicture, true); this.cardManager.setCaption("Catalog"); - Iterable allCards = Iterables.concat(FModel.getMagicDb().getCommonCards(), FModel.getMagicDb().getVariantCards()); + final Iterable allCards = Iterables.concat(FModel.getMagicDb().getCommonCards(), FModel.getMagicDb().getVariantCards()); this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true); this.cardManagerContainer.setItemManager(this.cardManager); this.cardManager.addSelectionListener(new ListSelectionListener() { @Override - public void valueChanged(ListSelectionEvent e) { - PaperCard card = cardManager.getSelectedItem(); - CDetail.SINGLETON_INSTANCE.showCard(card); - CPicture.SINGLETON_INSTANCE.showImage(card); + public void valueChanged(final ListSelectionEvent e) { + final PaperCard card = cardManager.getSelectedItem(); + cDetailPicture.showItem(card); CCardScript.SINGLETON_INSTANCE.showCard(card); } }); @@ -88,7 +88,7 @@ public enum VWorkshopCatalog implements IVDoc { @Override public void populate() { - JPanel parentBody = parentCell.getBody(); + final JPanel parentBody = parentCell.getBody(); parentBody.setLayout(new MigLayout("insets 5, gap 0, wrap, hidemode 3")); parentBody.add(cardManagerContainer, "push, grow"); } @@ -96,4 +96,8 @@ public enum VWorkshopCatalog implements IVDoc { public CardManager getCardManager() { return cardManager; } + + public CDetailPicture getCDetailPicture() { + return cDetailPicture; + } } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FUndoManager.java b/forge-gui-desktop/src/main/java/forge/toolbox/FUndoManager.java index a34d6b90218..010fb366fed 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FUndoManager.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FUndoManager.java @@ -1,17 +1,23 @@ package forge.toolbox; -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.UndoableEditEvent; -import javax.swing.event.UndoableEditListener; -import javax.swing.text.AbstractDocument; -import javax.swing.text.JTextComponent; -import javax.swing.undo.*; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.KeyStroke; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.UndoableEditEvent; +import javax.swing.text.AbstractDocument; +import javax.swing.text.JTextComponent; +import javax.swing.undo.CannotRedoException; +import javax.swing.undo.CannotUndoException; +import javax.swing.undo.CompoundEdit; +import javax.swing.undo.UndoManager; +import javax.swing.undo.UndoableEdit; + /* ** This class will merge individual edits into a single larger edit. ** That is, characters entered sequentially will be grouped together and @@ -19,9 +25,7 @@ import java.awt.event.KeyEvent; ** of the group and will therefore be undone when the group is undone. */ @SuppressWarnings("serial") -public class FUndoManager extends UndoManager - implements UndoableEditListener, DocumentListener -{ +public class FUndoManager extends UndoManager implements DocumentListener { private UndoManager undoManager; private CompoundEdit compoundEdit; private JTextComponent textComponent; 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 11c62008290..2a81cc9bfb4 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 @@ -21,20 +21,20 @@ package forge.toolbox.imaging; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +import javax.imageio.ImageIO; import forge.ImageCache; import forge.ImageKeys; import forge.game.card.CardView.CardStateView; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences; import forge.toolbox.CardFaceSymbols; import forge.toolbox.FSkin.SkinIcon; import forge.util.ImageUtil; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import javax.imageio.ImageIO; /** * Common image-related routines specific to Forge images. @@ -55,7 +55,7 @@ public final class FImageUtil { * For flip cards, returns the un-flipped image. */ public static BufferedImage getImage(final CardStateView card) { - BufferedImage image = ImageCache.getOriginalImage(MatchUtil.getCardImageKey(card), true); + BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(null), true); final int foilIndex = card.getFoilIndex(); if (image != null && foilIndex > 0) { image = getImageWithFoilEffect(image, foilIndex); @@ -64,12 +64,12 @@ public final class FImageUtil { } public static BufferedImage getImageXlhq(final CardStateView state) { - String key = MatchUtil.getCardImageKey(state); + final String key = state.getImageKey(null); if (key.isEmpty() || key.length() < 3) { return null; } - String prefix = key.substring(0, 2); + final String prefix = key.substring(0, 2); if (!prefix.equals(ImageKeys.CARD_PREFIX) && !prefix.equals(ImageKeys.TOKEN_PREFIX)) { return null; diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/special/CardZoomer.java b/forge-gui-desktop/src/main/java/forge/toolbox/special/CardZoomer.java index a6fff218ffd..29e5efe3d8e 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/special/CardZoomer.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/special/CardZoomer.java @@ -27,6 +27,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.image.BufferedImage; + import javax.swing.JPanel; import javax.swing.Timer; @@ -35,7 +36,6 @@ import forge.assets.FSkinProp; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.gui.SOverlayUtils; -import forge.match.MatchUtil; import forge.toolbox.FOverlay; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedLabel; @@ -171,7 +171,7 @@ public enum CardZoomer { *

* This method should be called if the zoomer is activated by holding down * the middle mouse button or left and right mouse buttons simultaneously. - */ + */ public void doMouseButtonZoom(final CardView newCard) { // don't display zoom if already zoomed or just closed zoom // (handles mouse wheeling while middle clicking) @@ -179,8 +179,8 @@ public enum CardZoomer { return; } - isButtonMode = true; - displayCard(newCard); + isButtonMode = true; + displayCard(newCard); } public boolean isZoomerOpen() { @@ -201,7 +201,7 @@ public enum CardZoomer { * Displays a graphical indicator that shows whether the current card can be flipped or transformed. */ private void setFlipIndicator() { - if (MatchUtil.canCardBeFlipped(thisCard)) { + if (thisCard.hasAlternateState()) { imagePanel.setLayout(new MigLayout("insets 0, w 100%!, h 100%!")); imagePanel.add(lblFlipcard, "pos (100% - 100px) 0"); } @@ -279,7 +279,7 @@ public enum CardZoomer { * Toggles between primary and alternate image associated with card if applicable. */ private void toggleCardImage() { - if (MatchUtil.canCardBeFlipped(thisCard)) { + if (thisCard.hasAlternateState()) { toggleFlipCard(); } } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java index 81e167e224b..83aab0756f2 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/special/PlayerDetailsPanel.java @@ -21,7 +21,6 @@ import forge.assets.FSkinProp; import forge.card.MagicColor; import forge.game.player.PlayerView; import forge.gui.ForgeAction; -import forge.screens.match.controllers.CPlayers; import forge.toolbox.FLabel; import forge.toolbox.FMouseAdapter; import forge.toolbox.FSkin; @@ -29,17 +28,17 @@ import forge.toolbox.FSkin.SkinFont; import forge.toolbox.FSkin.SkinnedPanel; public class PlayerDetailsPanel extends JPanel { - private static final long serialVersionUID = 8444559244193214459L; - - private PlayerView player; - + private static final long serialVersionUID = -6531759554646891983L; + + private final PlayerView player; + // Info labels - private FLabel lblHand = new DetailLabel(FSkinProp.IMG_ZONE_HAND, "99", "Cards in hand"); - private FLabel lblGraveyard = new DetailLabel(FSkinProp.IMG_ZONE_GRAVEYARD, "99", "Cards in graveyard"); - private FLabel lblLibrary = new DetailLabel(FSkinProp.IMG_ZONE_LIBRARY, "99", "Cards in library"); - private FLabel lblExile = new DetailLabel(FSkinProp.IMG_ZONE_EXILE, "99", "Exiled cards"); - private FLabel lblFlashback = new DetailLabel(FSkinProp.IMG_ZONE_FLASHBACK, "99", "Flashback cards"); - private FLabel lblPoison = new DetailLabel(FSkinProp.IMG_ZONE_POISON, "99", "Poison counters"); + private final FLabel lblHand = new DetailLabel(FSkinProp.IMG_ZONE_HAND, "99", "Cards in hand"); + private final FLabel lblGraveyard = new DetailLabel(FSkinProp.IMG_ZONE_GRAVEYARD, "99", "Cards in graveyard"); + private final FLabel lblLibrary = new DetailLabel(FSkinProp.IMG_ZONE_LIBRARY, "99", "Cards in library"); + private final FLabel lblExile = new DetailLabel(FSkinProp.IMG_ZONE_EXILE, "99", "Exiled cards"); + private final FLabel lblFlashback = new DetailLabel(FSkinProp.IMG_ZONE_FLASHBACK, "99", "Flashback cards"); + private final FLabel lblPoison = new DetailLabel(FSkinProp.IMG_ZONE_POISON, "99", "Poison counters"); private final List> manaLabels = new ArrayList>(); public PlayerDetailsPanel(final PlayerView player0) { @@ -129,9 +128,6 @@ public class PlayerDetailsPanel extends JPanel { * @param p0   {@link forge.game.player.Player} */ public void updateDetails() { - // "Players" panel update - CPlayers.SINGLETON_INSTANCE.update(); - // Poison/life getLblPoison().setText("" + player.getPoisonCounters()); if (player.getPoisonCounters() < 8) { diff --git a/forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java b/forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java deleted file mode 100644 index 52f4f00181d..00000000000 --- a/forge-gui-desktop/src/main/java/forge/view/ButtonUtil.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.view; - -import forge.FThreads; -import forge.gui.SOverlayUtils; -import forge.screens.match.VMatchUI; - -import javax.swing.*; - -/** - * Manages match UI OK/Cancel button enabling and focus - */ -public class ButtonUtil { - public static void setButtonText(String okLabel, String cancelLabel) { - getOk().setText(okLabel); - getCancel().setText(cancelLabel); - } - - public static void reset() { - disableAll(); - getOk().setText("OK"); - getCancel().setText("Cancel"); - } - - public static void enableOnlyOk() { - getCancel().setEnabled(false); - enableAndFocus(getOk()); - } - - public static void enableOnlyCancel() { - getOk().setEnabled(false); - enableAndFocus(getCancel()); - } - - public static void disableAll() { - getOk().setEnabled(false); - getCancel().setEnabled(false); - } - - public static void enableAllFocusOk() { - enableAndFocus(getOk()); - getCancel().setEnabled(true); - } - - public static void enableAllFocusCancel() { - getOk().setEnabled(true); - enableAndFocus(getCancel()); - } - - private static void enableAndFocus(final JButton button) { - button.setEnabled(true); - - // ensure we don't steal focus from an overlay - if (!SOverlayUtils.overlayHasFocus()) { - FThreads.invokeInEdtLater(new Runnable() { @Override public void run() { button.requestFocusInWindow(); } }); - } - } - - private static JButton getOk() { - return VMatchUI.SINGLETON_INSTANCE.getBtnOK(); - } - - private static JButton getCancel() { - return VMatchUI.SINGLETON_INSTANCE.getBtnCancel(); - } -} diff --git a/forge-gui-desktop/src/main/java/forge/view/FDialog.java b/forge-gui-desktop/src/main/java/forge/view/FDialog.java index 031c47f8b50..20ef9f435fd 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FDialog.java +++ b/forge-gui-desktop/src/main/java/forge/view/FDialog.java @@ -1,8 +1,43 @@ package forge.view; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.GraphicsDevice.WindowTranslucency; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.RenderingHints; +import java.awt.Toolkit; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.geom.RoundRectangle2D; +import java.util.Stack; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JRootPane; +import javax.swing.SwingUtilities; + +import net.miginfocom.swing.MigLayout; import forge.Singletons; import forge.assets.FSkinProp; -import forge.match.input.InputBase; import forge.toolbox.FMouseAdapter; import forge.toolbox.FPanel; import forge.toolbox.FSkin; @@ -12,15 +47,6 @@ import forge.toolbox.FSkin.LineSkinBorder; import forge.toolbox.FSkin.SkinColor; import forge.toolbox.FSkin.SkinnedDialog; import forge.util.OperatingSystem; -import net.miginfocom.swing.MigLayout; - -import javax.swing.*; - -import java.awt.*; -import java.awt.GraphicsDevice.WindowTranslucency; -import java.awt.event.*; -import java.awt.geom.RoundRectangle2D; -import java.util.Stack; @SuppressWarnings("serial") public class FDialog extends SkinnedDialog implements ITitleBarOwner, KeyEventDispatcher { @@ -146,7 +172,6 @@ public class FDialog extends SkinnedDialog implements ITitleBarOwner, KeyEventDi if (visible) { FMouseAdapter.forceMouseUp(); //ensure mouse up handled if dialog shown between mouse down and mouse up - InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." prompt doesn't appear while dialog awaiting input if (openModals.isEmpty()) { setLocationRelativeTo(JOptionPane.getRootFrame()); diff --git a/forge-gui-desktop/src/main/java/forge/view/FFrame.java b/forge-gui-desktop/src/main/java/forge/view/FFrame.java index 5eaabe35b51..3ea30af8634 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FFrame.java +++ b/forge-gui-desktop/src/main/java/forge/view/FFrame.java @@ -1,8 +1,26 @@ package forge.view; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; + +import javax.swing.BorderFactory; +import javax.swing.JRootPane; +import javax.swing.SwingUtilities; +import javax.swing.border.Border; + import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SResizingUtil; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; @@ -12,12 +30,6 @@ import forge.toolbox.FSkin.CompoundSkinBorder; import forge.toolbox.FSkin.LineSkinBorder; import forge.toolbox.FSkin.SkinnedFrame; -import javax.swing.*; -import javax.swing.border.Border; - -import java.awt.*; -import java.awt.event.*; - @SuppressWarnings("serial") public class FFrame extends SkinnedFrame implements ITitleBarOwner { private static final int borderThickness = 3; @@ -78,14 +90,14 @@ public class FFrame extends SkinnedFrame implements ITitleBarOwner { private void pause() { if (paused || !isMainFrame) { return; } - MatchUtil.pause(); + //HostedMatch.pause(); paused = true; } private void resume() { if (!paused || !isMainFrame) { return; } - MatchUtil.resume(); + //HostedMatch.resume(); paused = false; } diff --git a/forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java b/forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java index a41ef03ccff..7596cd2a853 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java +++ b/forge-gui-desktop/src/main/java/forge/view/FNavigationBar.java @@ -1,5 +1,30 @@ package forge.view; +import java.awt.BasicStroke; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.MouseInfo; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.border.EmptyBorder; + +import com.google.common.collect.Lists; + import forge.Singletons; import forge.gui.framework.FScreen; import forge.gui.framework.ILocalRepaint; @@ -13,16 +38,6 @@ import forge.toolbox.FSkin.SkinColor; import forge.toolbox.FSkin.SkinnedLabel; import forge.util.ReflectionUtil; -import javax.swing.*; -import javax.swing.border.EmptyBorder; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; - @SuppressWarnings("serial") public class FNavigationBar extends FTitleBarBase { @@ -32,7 +47,7 @@ public class FNavigationBar extends FTitleBarBase { private static final int initialHideDelay = 500; private final FButton btnForge = new FButton("Forge"); - private final ArrayList tabs = new ArrayList(); + private final List tabs = Lists.newArrayList(); private final FDigitalClock clock = new FDigitalClock(); private final JPanel pnlReveal = new JPanel(); private NavigationTab selectedTab; @@ -91,14 +106,13 @@ public class FNavigationBar extends FTitleBarBase { updateClockVisibility(); } - private NavigationTab addNavigationTab(FScreen screen) { - NavigationTab tab = new NavigationTab(screen); + private NavigationTab addNavigationTab(final FScreen screen) { + final NavigationTab tab = new NavigationTab(screen); if (tabs.size() == 0) { tab.setSelected(true); selectedTab = tab; layout.putConstraint(SpringLayout.WEST, tab, 1, SpringLayout.EAST, btnForge); - } - else { + } else { layout.putConstraint(SpringLayout.WEST, tab, 1, SpringLayout.EAST, tabs.get(tabs.size() - 1)); } layout.putConstraint(SpringLayout.SOUTH, tab, 0, SpringLayout.SOUTH, this); @@ -107,8 +121,8 @@ public class FNavigationBar extends FTitleBarBase { return tab; } - private NavigationTab getTab(FScreen screen) { - for (NavigationTab tab : tabs) { + private NavigationTab getTab(final FScreen screen) { + for (final NavigationTab tab : tabs) { if (tab.screen == screen) { return tab; } @@ -121,12 +135,13 @@ public class FNavigationBar extends FTitleBarBase { } public void updateSelectedTab() { - FScreen screen = Singletons.getControl().getCurrentScreen(); + final FScreen screen = Singletons.getControl().getCurrentScreen(); NavigationTab tab = getTab(screen); if (tab == null) { tab = addNavigationTab(screen); //if tab not found, add and select it + } else if (tab == selectedTab) { + return; } - else if (tab == selectedTab) { return; } if (selectedTab != null) { selectedTab.setSelected(false); @@ -341,6 +356,14 @@ public class FNavigationBar extends FTitleBarBase { public void setIconImage(Image image) { } + public void updateTitle(final FScreen screen) { + for (final NavigationTab tab : tabs) { + if (tab.screen == screen) { + tab.updateTitle(); + } + } + } + private final class NavigationTab extends SkinnedLabel implements ILocalRepaint { private static final int fontSize = 14; private static final int unhoveredAlpha = 150; @@ -459,6 +482,10 @@ public class FNavigationBar extends FTitleBarBase { super.paintComponent(g); } + private void updateTitle() { + setText(screen.getTabCaption()); + } + private class CloseButton extends JLabel implements ILocalRepaint { private boolean pressed, hovered; diff --git a/forge-gui-desktop/src/main/java/forge/view/FView.java b/forge-gui-desktop/src/main/java/forge/view/FView.java index 8234d2cf256..2b8d4c1a221 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FView.java +++ b/forge-gui-desktop/src/main/java/forge/view/FView.java @@ -1,5 +1,33 @@ package forge.view; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.swing.JLayeredPane; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; + +import net.miginfocom.swing.MigLayout; + +import org.apache.commons.lang3.StringUtils; + import com.google.common.collect.Lists; import forge.Singletons; @@ -8,32 +36,30 @@ import forge.control.RestartUtil; import forge.gui.FNetOverlay; import forge.gui.ImportDialog; import forge.gui.SOverlayUtils; -import forge.gui.framework.*; +import forge.gui.framework.DragCell; +import forge.gui.framework.EDocID; +import forge.gui.framework.FScreen; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.framework.SLayoutConstants; +import forge.gui.framework.SLayoutIO; import forge.properties.ForgeConstants; import forge.screens.bazaar.VBazaarUI; import forge.screens.deckeditor.VDeckEditorUI; import forge.screens.home.VHomeUI; -import forge.screens.match.TargetingOverlay; -import forge.screens.match.VMatchUI; import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; -import forge.toolbox.*; +import forge.toolbox.CardFaceSymbols; +import forge.toolbox.FAbsolutePositioner; +import forge.toolbox.FButton; +import forge.toolbox.FLabel; +import forge.toolbox.FOverlay; +import forge.toolbox.FPanel; +import forge.toolbox.FProgressBar; +import forge.toolbox.FScrollPane; +import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedLayeredPane; import forge.util.BuildInfo; -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import javax.swing.border.LineBorder; - -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.util.*; -import java.util.List; public enum FView { SINGLETON_INSTANCE; @@ -97,7 +123,6 @@ public enum FView { // Note: when adding new panels here, keep in mind that the layered pane // has a null layout, so new components will be W0 x H0 pixels - gotcha! // FControl has a method called "sizeComponents" which will fix this. - lpnDocument.add(TargetingOverlay.SINGLETON_INSTANCE.getPanel(), TARGETING_LAYER); lpnDocument.add(FNetOverlay.SINGLETON_INSTANCE.getPanel(), TARGETING_LAYER); pnlInsets.add(pnlContent, BorderLayout.CENTER); @@ -119,8 +144,11 @@ public enum FView { // Initialize actions on all drag tab components (which should // be realized / populated already). - for (EDocID doc : EDocID.values()) { - doc.getDoc().getLayoutControl().initialize(); + for (final EDocID doc : EDocID.values()) { + final IVDoc d = doc.getDoc(); + if (d != null) { + d.getLayoutControl().initialize(); + } } // All is ready to go - fire up home screen and discard splash frame. @@ -365,7 +393,6 @@ public enum FView { /** */ private void cacheUIStates() { - VMatchUI.SINGLETON_INSTANCE.instantiate(); VHomeUI.SINGLETON_INSTANCE.instantiate(); VDeckEditorUI.SINGLETON_INSTANCE.instantiate(); VBazaarUI.SINGLETON_INSTANCE.instantiate(); diff --git a/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java b/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java index de5bcda1aa2..b0611e1ab59 100644 --- a/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java +++ b/forge-gui-desktop/src/main/java/forge/view/SimulateMatch.java @@ -47,7 +47,7 @@ public class SimulateMatch { pp.add(new RegisteredPlayer(d1).setPlayer(GamePlayerUtil.createAiPlayer("Ai-" + d1.getName(), 0))); pp.add(new RegisteredPlayer(d2).setPlayer(GamePlayerUtil.createAiPlayer("Ai_" + d2.getName(), 1))); GameRules rules = new GameRules(GameType.Constructed); - Match mc = new Match(rules, pp); + Match mc = new Match(rules, pp, "Test"); for (int iGame = 0; iGame < nGames; iGame++) { simulateSingleMatch(mc, iGame); } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/CardArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/CardArea.java index 9d0bd2a51e6..62a899fda8d 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/CardArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/CardArea.java @@ -17,6 +17,7 @@ */ package forge.view.arcane; +import forge.screens.match.CMatchUI; import forge.toolbox.FScrollPane; import forge.view.arcane.util.Animation; import forge.view.arcane.util.CardPanelMouseListener; @@ -56,8 +57,8 @@ public class CardArea extends CardPanelContainer implements CardPanelMouseListen private boolean isVertical; private boolean hasScrollbars; - public CardArea(final FScrollPane scrollPane) { - super(scrollPane); + public CardArea(final CMatchUI matchUI, final FScrollPane scrollPane) { + super(matchUI, scrollPane); this.setBackground(Color.white); } @@ -254,7 +255,7 @@ public class CardArea extends CardPanelContainer implements CardPanelMouseListen this.mouseDragStartY = dragPanel.getCardY(); dragPanel.setDisplayEnabled(false); - CardPanel.setDragAnimationPanel(new CardPanel(dragPanel.getCard())); + CardPanel.setDragAnimationPanel(new CardPanel(dragPanel.getMatchUI(), dragPanel.getCard())); CardPanel.getDragAnimationPanel().setImage(dragPanel); final JFrame frame = (JFrame) SwingUtilities.windowForComponent(this); final JLayeredPane layeredPane = frame.getLayeredPane(); 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 50c93c16711..a528673b999 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 @@ -40,9 +40,9 @@ import forge.card.mana.ManaCost; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.gui.CardContainer; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; +import forge.screens.match.CMatchUI; import forge.toolbox.CardFaceSymbols; import forge.toolbox.FSkin.SkinnedPanel; import forge.toolbox.IDisposable; @@ -70,6 +70,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl private static final float ROT_CENTER_TO_TOP_CORNER = 1.0295630140987000315797369464196f; private static final float ROT_CENTER_TO_BOTTOM_CORNER = 0.7071067811865475244008443621048f; + private final CMatchUI matchUI; private CardView card; private CardPanel attachedToPanel; private List attachedPanels = new ArrayList(); @@ -88,7 +89,9 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl private int cardXOffset, cardYOffset, cardWidth, cardHeight; private boolean isSelected; - public CardPanel(final CardView card0) { + public CardPanel(final CMatchUI matchUI, final CardView card0) { + this.matchUI = matchUI; + setBackground(Color.black); setOpaque(false); @@ -100,6 +103,10 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl setCard(card0); } + public CMatchUI getMatchUI() { + return matchUI; + } + private void createScaleImagePanel() { imagePanel = new ScaledImagePanel(); add(imagePanel); @@ -152,7 +159,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl updateImage(false); } private void updateImage(boolean fromSetCard) { - final BufferedImage image = card == null ? null : ImageCache.getImage(card, imagePanel.getWidth(), imagePanel.getHeight()); + final BufferedImage image = card == null ? null : ImageCache.getImage(card, matchUI.getCurrentPlayer(), imagePanel.getWidth(), imagePanel.getHeight()); if (fromSetCard) { setImage(image); } @@ -239,7 +246,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl final int offset = isTapped() ? 1 : 0; // Magenta outline for when card was chosen to pay - if (MatchUtil.isUsedToPay(getCard())) { + if (matchUI.isUsedToPay(getCard())) { g2d.setColor(Color.magenta); final int n2 = Math.max(1, Math.round(2 * cardWidth * CardPanel.SELECTED_BORDER_SIZE)); g2d.fillRoundRect(cardXOffset - n2, (cardYOffset - n2) + offset, cardWidth + (n2 * 2), cardHeight + (n2 * 2), cornerSize + n2, cornerSize + n2); @@ -258,7 +265,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl g2d.fillRoundRect(cardXOffset - n, (cardYOffset - n) + offset, cardWidth + (n * 2), cardHeight + (n * 2), cornerSize + n , cornerSize + n); // White border if card is known to have it. - if (getCard() != null && MatchUtil.canCardBeShown(getCard())) { + if (getCard() != null && matchUI.mayView(getCard())) { final CardStateView state = getCard().getCurrentState(); final CardEdition ed = FModel.getMagicDb().getEditions().get(state.getSetCode()); boolean colorIsSet = false; @@ -292,7 +299,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl return; } - boolean canShow = MatchUtil.canCardBeShown(card); + boolean canShow = matchUI.mayView(card); displayIconOverlay(g, canShow); if (canShow) { drawFoilEffect(g, card, cardXOffset, cardYOffset, @@ -320,7 +327,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl imagePanel.setLocation(imgPos); imagePanel.setSize(imgSize); - boolean canShow = MatchUtil.canCardBeShown(card); + boolean canShow = matchUI.mayView(card); boolean showText = !imagePanel.hasImage() || !isAnimationPanel; displayCardNameOverlay(showText && canShow && showCardNameOverlay(), imgSize, imgPos); @@ -419,7 +426,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl CardFaceSymbols.drawSymbol("phasing", g, stateXSymbols, ySymbols); } - if (MatchUtil.isUsedToPay(card)) { + if (matchUI.isUsedToPay(card)) { CardFaceSymbols.drawSymbol("sacrifice", g, (cardXOffset + (cardWidth / 2)) - 20, (cardYOffset + (cardHeight / 2)) - 20); } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanelContainer.java b/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanelContainer.java index 35f50632720..c9116e91388 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanelContainer.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/CardPanelContainer.java @@ -49,7 +49,8 @@ public abstract class CardPanelContainer extends SkinnedPanel { private static final int DRAG_SMUDGE = 10; private final List cardPanels = new ArrayList(); - private FScrollPane scrollPane; + private final CMatchUI matchUI; + private final FScrollPane scrollPane; private int cardWidthMin = 50; private int cardWidthMax = 300; @@ -63,12 +64,17 @@ public abstract class CardPanelContainer extends SkinnedPanel { private int intialMouseDragX = -1, intialMouseDragY; private boolean dragEnabled; - public CardPanelContainer(final FScrollPane scrollPane) { + public CardPanelContainer(final CMatchUI matchUI, final FScrollPane scrollPane) { + this.matchUI = matchUI; this.scrollPane = scrollPane; this.setOpaque(true); setupMouseListeners(); } + protected final CMatchUI getMatchUI() { + return matchUI; + } + private void setupMouseListeners() { final MouseMotionListener mml = setupMotionMouseListener(); setupMouseListener(mml); @@ -213,7 +219,7 @@ public abstract class CardPanelContainer extends SkinnedPanel { } if (hitPanel != null) { - CMatchUI.SINGLETON_INSTANCE.setCard(hitPanel.getCard()); + matchUI.setCard(hitPanel.getCard()); hoveredPanel = hitPanel; hoveredPanel.setSelected(true); @@ -239,7 +245,7 @@ public abstract class CardPanelContainer extends SkinnedPanel { protected abstract CardPanel getCardPanel(int x, int y); public CardPanel addCard(final CardView card) { - final CardPanel placeholder = new CardPanel(card); + final CardPanel placeholder = new CardPanel(matchUI, card); placeholder.setDisplayEnabled(false); this.getCardPanels().add(placeholder); this.add(placeholder); diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java index f767fac2d2f..76721c2f04c 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java @@ -17,6 +17,19 @@ */ package forge.view.arcane; +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import javax.swing.ScrollPaneConstants; +import javax.swing.Timer; + import forge.Singletons; import forge.assets.FSkinProp; import forge.game.card.CardView; @@ -27,7 +40,6 @@ import forge.model.FModel; import forge.properties.ForgePreferences; import forge.properties.ForgePreferences.FPref; import forge.screens.match.CMatchUI; -import forge.screens.match.controllers.CPrompt; import forge.toolbox.FMouseAdapter; import forge.toolbox.FScrollPane; import forge.toolbox.FSkin; @@ -37,19 +49,6 @@ import forge.util.Lang; import forge.view.FDialog; import forge.view.FFrame; -import java.awt.Component; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import javax.swing.ScrollPaneConstants; -import javax.swing.Timer; - - public class FloatingCardArea extends CardArea { private static final long serialVersionUID = 1927906492186378596L; @@ -58,17 +57,16 @@ public class FloatingCardArea extends CardArea { private static final ForgePreferences prefs = FModel.getPreferences(); private static final HashMap floatingAreas = new HashMap(); - private static int getKey(PlayerView player, ZoneType zone) { + private static int getKey(final PlayerView player, final ZoneType zone) { return 40 * player.getId() + zone.hashCode(); } - public static void show(PlayerView player, ZoneType zone) { + public static void show(final CMatchUI matchUI, final PlayerView player, final ZoneType zone) { int key = getKey(player, zone); FloatingCardArea cardArea = floatingAreas.get(key); if (cardArea == null) { - cardArea = new FloatingCardArea(player, zone); + cardArea = new FloatingCardArea(matchUI, player, zone); floatingAreas.put(key, cardArea); - } - else { + } else { cardArea.setPlayer(player); //ensure player is updated if needed } cardArea.showWindow(); @@ -133,8 +131,8 @@ public class FloatingCardArea extends CardArea { } }; - private FloatingCardArea(PlayerView player0, ZoneType zone0) { - super(new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)); + private FloatingCardArea(final CMatchUI matchUI, final PlayerView player0, final ZoneType zone0) { + super(matchUI, new FScrollPane(false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)); window.add(getScrollPane(), "grow, push"); getScrollPane().setViewportView(this); setOpaque(false); @@ -264,7 +262,7 @@ public class FloatingCardArea extends CardArea { for (final CardView card : cards) { CardPanel cardPanel = getCardPanel(card.getId()); if (cardPanel == null) { - cardPanel = new CardPanel(card); + cardPanel = new CardPanel(getMatchUI(), card); cardPanel.setDisplayEnabled(true); } else { @@ -310,17 +308,17 @@ public class FloatingCardArea extends CardArea { @Override public final void mouseOver(final CardPanel panel, final MouseEvent evt) { - CMatchUI.SINGLETON_INSTANCE.setCard(panel.getCard(), evt.isShiftDown()); + getMatchUI().setCard(panel.getCard(), evt.isShiftDown()); super.mouseOver(panel, evt); } @Override public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) { - CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); + getMatchUI().getCPrompt().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); super.mouseLeftClicked(panel, evt); } @Override public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) { - CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); + getMatchUI().getCPrompt().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); super.mouseRightClicked(panel, evt); } } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/HandArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/HandArea.java index dfa38052cd7..416575452b7 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/HandArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/HandArea.java @@ -17,13 +17,11 @@ */ package forge.view.arcane; -import forge.screens.match.CMatchUI; -import forge.screens.match.controllers.CPrompt; -import forge.toolbox.FScrollPane; -import forge.toolbox.MouseTriggerEvent; - import java.awt.event.MouseEvent; +import forge.screens.match.CMatchUI; +import forge.toolbox.FScrollPane; +import forge.toolbox.MouseTriggerEvent; /** *

@@ -45,8 +43,8 @@ public class HandArea extends CardArea { * * @param scrollPane */ - public HandArea(final FScrollPane scrollPane) { - super(scrollPane); + public HandArea(final CMatchUI matchUI, final FScrollPane scrollPane) { + super(matchUI, scrollPane); this.setDragEnabled(true); this.setVertical(true); @@ -55,21 +53,21 @@ public class HandArea extends CardArea { /** {@inheritDoc} */ @Override public final void mouseOver(final CardPanel panel, final MouseEvent evt) { - CMatchUI.SINGLETON_INSTANCE.setCard(panel.getCard(), evt.isShiftDown()); + getMatchUI().setCard(panel.getCard(), evt.isShiftDown()); super.mouseOver(panel, evt); } /** {@inheritDoc} */ @Override public final void mouseLeftClicked(final CardPanel panel, final MouseEvent evt) { - CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); + getMatchUI().getCPrompt().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); super.mouseLeftClicked(panel, evt); } /** {@inheritDoc} */ @Override public final void mouseRightClicked(final CardPanel panel, final MouseEvent evt) { - CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); + getMatchUI().getCPrompt().selectCard(panel.getCard(), null, new MouseTriggerEvent(evt)); super.mouseRightClicked(panel, evt); } } diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java index 12a04913eca..8b278c1a438 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/PlayArea.java @@ -32,9 +32,7 @@ import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.screens.match.CMatchUI; -import forge.screens.match.controllers.CPrompt; import forge.toolbox.FScrollPane; import forge.toolbox.MouseTriggerEvent; import forge.view.arcane.util.Animation; @@ -75,8 +73,8 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen private final PlayerView model; private final ZoneType zone; - public PlayArea(final FScrollPane scrollPane, final boolean mirror, final PlayerView player, final ZoneType zone) { - super(scrollPane); + public PlayArea(final CMatchUI matchUI, final FScrollPane scrollPane, final boolean mirror, final PlayerView player, final ZoneType zone) { + super(matchUI, scrollPane); this.setBackground(Color.white); this.mirror = mirror; this.model = player; @@ -244,7 +242,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen @Override public final CardPanel addCard(final CardView card) { - final CardPanel placeholder = new CardPanel(card); + final CardPanel placeholder = new CardPanel(getMatchUI(), card); placeholder.setDisplayEnabled(false); this.getCardPanels().add(placeholder); this.add(placeholder); @@ -511,7 +509,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen @Override public final void mouseOver(final CardPanel panel, final MouseEvent evt) { - CMatchUI.SINGLETON_INSTANCE.setCard(panel.getCard(), evt.isShiftDown()); + getMatchUI().setCard(panel.getCard(), evt.isShiftDown()); super.mouseOver(panel, evt); } @@ -545,7 +543,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } } } - if (CPrompt.SINGLETON_INSTANCE.selectCard(panel.getCard(), otherCardViewsToSelect, triggerEvent)) { + if (getMatchUI().getCPrompt().selectCard(panel.getCard(), otherCardViewsToSelect, triggerEvent)) { return true; } //if panel can't do anything with card selection, try selecting previous panel in stack @@ -565,7 +563,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen } } } - MatchUtil.getController().flashIncorrectAction(); + getMatchUI().flashIncorrectAction(); return false; } @@ -617,7 +615,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen final List newPanels = new ArrayList(); for (final CardView card : toAdd) { - final CardPanel placeholder = new CardPanel(card); + final CardPanel placeholder = new CardPanel(getMatchUI(), card); placeholder.setDisplayEnabled(false); this.getCardPanels().add(placeholder); this.add(placeholder); diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/util/Animation.java b/forge-gui-desktop/src/main/java/forge/view/arcane/util/Animation.java index f2b7c6f0974..735c8b57878 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/util/Animation.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/util/Animation.java @@ -17,13 +17,14 @@ */ package forge.view.arcane.util; -import forge.view.arcane.CardPanel; - -import javax.swing.*; -import java.awt.*; +import java.awt.Container; +import java.awt.EventQueue; import java.util.Timer; import java.util.TimerTask; +import javax.swing.JLayeredPane; + +import forge.view.arcane.CardPanel; /** *

@@ -40,17 +41,6 @@ public abstract class Animation { /** Constant timer. */ private static Timer timer = new Timer("Animation", true); - /** Constant delayedCardPanel. */ - private static CardPanel delayedCardPanel; - /** Constant delayedTime=. */ - private static long delayedTime; - /** Constant enlargedCardPanel. */ - private static CardPanel enlargedCardPanel; - /** Constant enlargedAnimationPanel. */ - private static CardPanel enlargedAnimationPanel; - /** Constant enlargeLock. */ - private static Object enlargeLock = new Object(); - private TimerTask timerTask; private FrameTimer frameTimer; private long elapsed; @@ -419,190 +409,4 @@ public abstract class Animation { }); } - /** - *

- * shrinkCard. - *

- */ - public static void shrinkCard() { - CardPanel enlargedCardPanel, enlargedAnimationPanel; - synchronized (enlargeLock) { - delayedCardPanel = null; - delayedTime = 0; - enlargedCardPanel = Animation.enlargedCardPanel; - enlargedAnimationPanel = Animation.enlargedAnimationPanel; - if (enlargedAnimationPanel == null) { - return; - } - Animation.enlargedCardPanel = null; - Animation.enlargedAnimationPanel = null; - } - - final CardPanel overPanel = enlargedCardPanel, animationPanel = enlargedAnimationPanel; - - animationPanel.setAnimationPanel(true); - final JLayeredPane layeredPane = SwingUtilities.getRootPane(overPanel).getLayeredPane(); - layeredPane.setLayer(animationPanel, JLayeredPane.MODAL_LAYER); - - final int startWidth = animationPanel.getCardWidth(); - final int startHeight = Math.round(startWidth * CardPanel.ASPECT_RATIO); - final int endWidth = overPanel.getCardWidth(); - final int endHeight = Math.round(endWidth * CardPanel.ASPECT_RATIO); - - new Animation(200) { - @Override - protected void update(final float percentage) { - int currentWidth = startWidth + Math.round((endWidth - startWidth) * percentage); - int currentHeight = startHeight + Math.round((endHeight - startHeight) * percentage); - Point startPos = SwingUtilities.convertPoint(overPanel.getParent(), overPanel.getCardLocation(), - layeredPane); - int centerX = startPos.x + Math.round(endWidth / 2f); - int centerY = startPos.y + Math.round(endHeight / 2f); - int currentX = Math.max(0, centerX - Math.round(currentWidth / 2f)); - currentX = Math.min(currentX, layeredPane.getWidth() - currentWidth); - int currentY = Math.max(0, centerY - Math.round(currentHeight / 2f)); - currentY = Math.min(currentY, layeredPane.getHeight() - currentHeight); - animationPanel.setTappedAngle(overPanel.getTappedAngle() * percentage); - animationPanel.setCardBounds(currentX, currentY, currentWidth, currentHeight); - } - - @Override - protected void end() { - animationPanel.setVisible(false); - animationPanel.repaint(); - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - layeredPane.remove(animationPanel); - } - }); - } - }; - } - - /** - *

- * enlargeCard. - *

- * - * @param overPanel - * a {@link forge.view.arcane.CardPanel} object. - * @param clientFrame - * a {@link java.awt.Frame} object. - * @param delay - * a long. - */ - public static void enlargeCard(final CardPanel overPanel, final Frame clientFrame, final long delay) { - if (SwingUtilities.getRootPane(overPanel) == null) { - synchronized (enlargeLock) { - delayedCardPanel = null; - delayedTime = 0; - if (Animation.enlargedCardPanel != null) { - Animation.enlargedCardPanel = null; - } - if (enlargedAnimationPanel == null) { - return; - } - - Animation.enlargedAnimationPanel.setVisible(false); - Animation.enlargedAnimationPanel.repaint(); - Animation.enlargedAnimationPanel = null; - return; - } - } - final JLayeredPane layeredPane = SwingUtilities.getRootPane(overPanel).getLayeredPane(); - - final int startWidth = overPanel.getCardWidth(); - final int startHeight = Math.round(startWidth * CardPanel.ASPECT_RATIO); - final int endWidth = 300; - final int endHeight = Math.round(endWidth * CardPanel.ASPECT_RATIO); - if (startWidth >= endWidth) { - return; - } - - long delayedTime; - synchronized (enlargeLock) { - if (enlargedCardPanel == overPanel) { - return; // Already showing this card enlarged. - } - if (delay > 0 && delayedCardPanel == overPanel) { - return; // Already delayed this card. - } - delayedCardPanel = overPanel; - Animation.delayedTime = System.currentTimeMillis(); - delayedTime = Animation.delayedTime; - } - final long thisDelayedTime = delayedTime; - - final CardPanel animationPanel = new CardPanel(overPanel.getCard()); - animationPanel.setImage(overPanel); - - new Animation(200, delay) { - @Override - protected void start() { - synchronized (enlargeLock) { - // Cancel if the panel is no longer delayed or already - // shown. - if (delayedCardPanel != overPanel || thisDelayedTime != Animation.delayedTime - || enlargedCardPanel == overPanel) { - cancel(); - return; - } - shrinkCard(); - enlargedAnimationPanel = animationPanel; - enlargedCardPanel = overPanel; - Point startPos = overPanel.getCardLocation(); - animationPanel.setCardBounds(startPos.x, startPos.y, startWidth, startHeight); - } - // clientFrame.clearArrows(); - animationPanel.setTappedAngle(overPanel.getTappedAngle()); - try { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - layeredPane.add(animationPanel); - layeredPane.setLayer(animationPanel, JLayeredPane.DRAG_LAYER); - } - }); - } catch (Exception ex) { - throw new RuntimeException("Error invoking runnable in UI thread.", ex); - } - } - - @Override - protected void update(final float percentage) { - synchronized (enlargeLock) { - if (enlargedAnimationPanel != animationPanel) { - cancel(); - return; - } - } - int currentWidth = startWidth + Math.round((endWidth - startWidth) * percentage); - int currentHeight = startHeight + Math.round((endHeight - startHeight) * percentage); - Point startPos = SwingUtilities.convertPoint(overPanel.getParent(), overPanel.getCardLocation(), - layeredPane); - int centerX = startPos.x + Math.round(startWidth / 2f); - int centerY = startPos.y + Math.round(startHeight / 2f); - int currentX = Math.max(0, centerX - Math.round(currentWidth / 2f)); - currentX = Math.min(currentX, layeredPane.getWidth() - currentWidth); - int currentY = Math.max(0, centerY - Math.round(currentHeight / 2f)); - currentY = Math.min(currentY, layeredPane.getHeight() - currentHeight); - animationPanel.setTappedAngle(overPanel.getTappedAngle() * (1 - percentage)); - animationPanel.setCardBounds(currentX, currentY, currentWidth, currentHeight); - } - }; - } - - /** - *

- * isShowingEnlargedCard. - *

- * - * @return a boolean. - */ - public static boolean isShowingEnlargedCard() { - synchronized (enlargeLock) { - return enlargedAnimationPanel != null; - } - } } diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java index b592fef97a2..998a709578c 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java @@ -37,7 +37,7 @@ public class GameSimulatorTest extends TestCase { players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2", null))); players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p1", null))); GameRules rules = new GameRules(GameType.Constructed); - Match match = new Match(rules, players); + Match match = new Match(rules, players, "Test"); Game game = new Game(players, rules, match); game.setAge(GameStage.Play); diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/GameWrapper.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/GameWrapper.java index 0fa9d3b82c6..83eeef5e386 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/GameWrapper.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/GameWrapper.java @@ -62,7 +62,7 @@ public class GameWrapper { rules.setPlayForAnte(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE)); rules.setMatchAnteRarity(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY)); rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); - Match match = new Match(rules, registeredPlayers); + Match match = new Match(rules, registeredPlayers, "Test"); game = match.createGame(); //GameNew.newGame( game, false, false ) does a bit of internal setup, then prepares libraries etc diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index c5b3aa96057..89d7ca55c44 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -637,4 +637,9 @@ public class PlayerControllerForTests extends PlayerController { public void resetAtEndOfTurn() { // Not used by the controller for tests } + + @Override + public void autoPassCancel() { + // Not used by the controller for tests + } } diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index f5e3ab7e6f0..fd5a5e8ce7e 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -17,7 +17,7 @@ import forge.assets.ImageCache; import forge.error.BugReporter; import forge.error.ExceptionHandler; import forge.interfaces.IDeviceAdapter; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences; @@ -25,7 +25,6 @@ import forge.properties.ForgePreferences.FPref; import forge.screens.FScreen; import forge.screens.SplashScreen; import forge.screens.home.HomeScreen; -import forge.screens.match.MatchController; import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; import forge.toolbox.FContainer; @@ -51,6 +50,7 @@ public class Forge implements ApplicationListener { private static KeyInputAdapter keyInputAdapter; private static boolean exited; private static final Stack screens = new Stack(); + public static HostedMatch hostedMatch; public static ApplicationListener getApp(Clipboard clipboard0, IDeviceAdapter deviceAdapter0, String assetDir0) { if (GuiBase.getInterface() == null) { @@ -69,8 +69,6 @@ public class Forge implements ApplicationListener { //install our error handler ExceptionHandler.registerErrorHandling(); - MatchUtil.setController(MatchController.instance); - graphics = new Graphics(); splashScreen = new SplashScreen(); Gdx.input.setInputProcessor(new MainInputProcessor()); @@ -289,12 +287,16 @@ public class Forge implements ApplicationListener { @Override public void pause() { - MatchUtil.pause(); + if (hostedMatch != null) { + hostedMatch.pause(); + } } @Override public void resume() { - MatchUtil.resume(); + if (hostedMatch != null) { + hostedMatch.resume(); + } } @Override diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index a1e2a43dae6..9c2f16f999b 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -4,13 +4,10 @@ import java.io.File; import java.util.Collection; import java.util.List; -import org.apache.commons.lang3.StringUtils; - -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Application.ApplicationType; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.google.common.base.Function; -import com.google.common.collect.Iterables; import forge.animation.GuiTimer; import forge.assets.FBufferedImage; @@ -22,22 +19,15 @@ import forge.assets.FTextureImage; import forge.assets.ISkinImage; import forge.assets.ImageCache; import forge.card.CardRenderer; -import forge.card.GameEntityPicker; -import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.FDeckViewer; -import forge.deck.FSideboardDialog; import forge.download.GuiDownloadService; import forge.error.BugReportDialog; -import forge.game.GameEntity; -import forge.game.GameEntityView; -import forge.game.card.CardView; -import forge.game.player.DelayedReveal; -import forge.game.player.IHasIcon; import forge.interfaces.IGuiBase; +import forge.interfaces.IGuiGame; import forge.interfaces.IGuiTimer; import forge.item.PaperCard; -import forge.player.PlayerControllerHuman; +import forge.match.HostedMatch; import forge.properties.ForgeConstants; import forge.screens.match.MatchController; import forge.screens.quest.QuestMenu; @@ -49,13 +39,10 @@ import forge.sound.IAudioMusic; import forge.toolbox.FOptionPane; import forge.toolbox.GuiChoose; import forge.util.Callback; -import forge.util.FCollectionView; import forge.util.FileUtil; -import forge.util.MessageUtil; import forge.util.ThreadUtil; import forge.util.WaitCallback; import forge.util.WaitRunnable; -import forge.util.gui.SGuiChoose; public class GuiMobile implements IGuiBase { private final String assetsDir; @@ -172,16 +159,6 @@ public class GuiMobile implements IGuiBase { }.invokeAndWait(); } - @Override - public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { - return new WaitCallback() { - @Override - public void run() { - FOptionPane.showCardOptionDialog(card, message, title, icon == null ? null : FSkin.getImages().get(icon), options, defaultOption, this); - } - }.invokeAndWait(); - } - @Override public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { return new WaitCallback() { @@ -204,49 +181,11 @@ public class GuiMobile implements IGuiBase { @Override public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { + final List sourceChoices, final List destChoices) { return new WaitCallback>() { @Override public void run() { - GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, this); - } - }.invokeAndWait(); - } - - @Override - public List sideboard(final CardPool sideboard, final CardPool main) { - return new WaitCallback>() { - @Override - public void run() { - FSideboardDialog sideboardDialog = new FSideboardDialog(sideboard, main, this); - sideboardDialog.show(); - } - }.invokeAndWait(); - } - - @Override - public GameEntityView chooseSingleEntityForEffect(final String title, final FCollectionView optionList, final DelayedReveal delayedReveal, final boolean isOptional, final PlayerControllerHuman controller) { - controller.tempShow(optionList); - final List choiceList = GameEntityView.getEntityCollection(optionList); - - if (delayedReveal == null || Iterables.isEmpty(delayedReveal.getCards())) { - if (isOptional) { - return SGuiChoose.oneOrNone(title, choiceList); - } - return SGuiChoose.one(title, choiceList); - } - - controller.tempShow(delayedReveal.getCards()); - final List revealList = CardView.getCollection(delayedReveal.getCards()); - final String revealListCaption = StringUtils.capitalize(MessageUtil.formatMessage("{player's} " + delayedReveal.getZone().name(), controller.getPlayer(), delayedReveal.getOwner())); - final FImage revealListImage = MatchController.getView().getPlayerPanels().values().iterator().next().getZoneTab(delayedReveal.getZone()).getIcon(); - - //use special dialog for choosing card and offering ability to see all revealed cards at the same time - return new WaitCallback() { - @Override - public void run() { - GameEntityPicker picker = new GameEntityPicker(title, choiceList, revealList, revealListCaption, revealListImage, isOptional, this); - picker.show(); + GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, null, this); } }.invokeAndWait(); } @@ -279,11 +218,6 @@ public class GuiMobile implements IGuiBase { return 0; } - @Override - public void setCard(final CardView card) { - //doesn't need to do anything - } - @Override public String showFileDialog(String title, String defaultDir) { return ForgeConstants.USER_GAMES_DIR + "Test.fgs"; //TODO: Show dialog @@ -305,7 +239,7 @@ public class GuiMobile implements IGuiBase { } @Override - public void browseToUrl(String url) throws Exception { + public void browseToUrl(String url) { Gdx.net.openURI(url); } @@ -340,7 +274,12 @@ public class GuiMobile implements IGuiBase { } @Override - public void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi) { - MatchController.setPlayerAvatar(player, ImageCache.getIcon(ihi)); + public IGuiGame getNewGuiGame() { + return MatchController.instance; + } + + @Override + public HostedMatch hostMatch() { + return Forge.hostedMatch = new HostedMatch(); } } diff --git a/forge-gui-mobile/src/forge/assets/ImageCache.java b/forge-gui-mobile/src/forge/assets/ImageCache.java index 6aa7eb3fbe3..cca3b5cea07 100644 --- a/forge-gui-mobile/src/forge/assets/ImageCache.java +++ b/forge-gui-mobile/src/forge/assets/ImageCache.java @@ -28,8 +28,8 @@ import forge.game.card.CardView; import forge.game.player.IHasIcon; import forge.item.InventoryItem; import forge.item.PaperCard; -import forge.match.MatchUtil; import forge.properties.ForgeConstants; +import forge.screens.match.MatchController; import forge.util.ImageUtil; import org.apache.commons.lang3.StringUtils; @@ -81,8 +81,8 @@ public class ImageCache { missingIconKeys.clear(); } - public static Texture getImage(CardView card) { - final String key = MatchUtil.getCardImageKey(card.getCurrentState()); + public static Texture getImage(final CardView card) { + final String key = card.getCurrentState().getImageKey(MatchController.instance.getCurrentPlayer()); return getImage(key, true); } diff --git a/forge-gui-mobile/src/forge/card/CardImageRenderer.java b/forge-gui-mobile/src/forge/card/CardImageRenderer.java index d520194e947..11d9bfb476b 100644 --- a/forge-gui-mobile/src/forge/card/CardImageRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardImageRenderer.java @@ -23,8 +23,8 @@ import forge.card.mana.ManaCost; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.screens.FScreen; +import forge.screens.match.MatchController; import forge.util.Utils; public class CardImageRenderer { @@ -73,8 +73,8 @@ public class CardImageRenderer { w -= 2 * blackBorderThickness; h -= 2 * blackBorderThickness; - CardStateView state = altState ? card.getAlternateState() : card.getCurrentState(); - boolean canShow = MatchUtil.canCardBeShown(card); + final CardStateView state = card.getState(altState); + final boolean canShow = MatchController.instance.mayView(card); //determine colors for borders final List borderColors = CardDetailUtil.getBorderColors(state, canShow); @@ -329,7 +329,7 @@ public class CardImageRenderer { } public static void drawZoom(Graphics g, CardView card, boolean altState, float x, float y, float w, float h) { - final Texture image = ImageCache.getImage(MatchUtil.getCardImageKey(altState ? card.getAlternateState() : card.getCurrentState()), true); + final Texture image = ImageCache.getImage(card.getState(altState).getImageKey(MatchController.instance.getCurrentPlayer()), true); if (image == null) { //draw details if can't draw zoom drawDetails(g, card, altState, x, y, w, h); return; @@ -354,8 +354,8 @@ public class CardImageRenderer { w -= 2 * blackBorderThickness; h -= 2 * blackBorderThickness; - CardStateView state = altState ? card.getAlternateState() : card.getCurrentState(); - boolean canShow = MatchUtil.canCardBeShown(card); + final CardStateView state = card.getState(altState); + final boolean canShow = MatchController.instance.mayView(card); //determine colors for borders List borderColors = CardDetailUtil.getBorderColors(state, canShow); diff --git a/forge-gui-mobile/src/forge/card/CardRenderer.java b/forge-gui-mobile/src/forge/card/CardRenderer.java index d0522ce87c8..14e89b7fe2b 100644 --- a/forge-gui-mobile/src/forge/card/CardRenderer.java +++ b/forge-gui-mobile/src/forge/card/CardRenderer.java @@ -26,9 +26,9 @@ import forge.card.mana.ManaCost; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; import forge.item.IPaperCard; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; +import forge.screens.match.MatchController; import forge.toolbox.FList; import forge.util.Utils; @@ -298,7 +298,7 @@ public class CardRenderer { w -= 2 * padding; h -= 2 * padding; - boolean canShow = MatchUtil.canCardBeShown(card); + boolean canShow = MatchController.instance.mayView(card); CardStateView details = card.getCurrentState(); DetailColors borderColor = CardDetailUtil.getBorderColor(details, canShow); @@ -379,7 +379,7 @@ public class CardRenderer { CardFaceSymbols.drawSymbol("phasing", g, stateXSymbols, ySymbols, otherSymbolsSize, otherSymbolsSize); } - if (MatchUtil.isUsedToPay(card)) { + if (MatchController.instance.isUsedToPay(card)) { float sacSymbolSize = otherSymbolsSize * 1.2f; CardFaceSymbols.drawSymbol("sacrifice", g, (x + (w / 2)) - sacSymbolSize / 2, (y + (h / 2)) - sacSymbolSize / 2, otherSymbolsSize, otherSymbolsSize); } @@ -450,7 +450,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) && MatchUtil.canCardBeShown(card)) { + if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT) && MatchController.instance.mayView(card)) { int foil = card.getCurrentState().getFoilIndex(); if (foil > 0) { CardFaceSymbols.drawOther(g, String.format("foil%02d", foil), x, y, w, h); diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index 519c9b6f13c..6215887583b 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -16,8 +16,8 @@ import forge.assets.FSkinImage; import forge.game.card.CardView; import forge.item.IPaperCard; import forge.item.InventoryItem; -import forge.match.MatchUtil; import forge.screens.FScreen; +import forge.screens.match.MatchController; import forge.toolbox.FCardPanel; import forge.toolbox.FOptionPane; import forge.toolbox.FOverlay; @@ -96,10 +96,9 @@ public class CardZoom extends FOverlay { if (activateHandler != null) { currentActivateAction = activateHandler.getActivateAction(currentIndex); } - if (MatchUtil.canCardBeFlipped(currentCard)) { + if (MatchController.instance.mayFlip(currentCard)) { flipIconBounds = new Rectangle(); - } - else { + } else { flipIconBounds = null; } showAltState = false; diff --git a/forge-gui-mobile/src/forge/screens/LaunchScreen.java b/forge-gui-mobile/src/forge/screens/LaunchScreen.java index a9f97b28e98..a7845896d6d 100644 --- a/forge-gui-mobile/src/forge/screens/LaunchScreen.java +++ b/forge-gui-mobile/src/forge/screens/LaunchScreen.java @@ -1,19 +1,23 @@ package forge.screens; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import com.badlogic.gdx.Input.Keys; -import forge.match.MatchUtil; -import forge.menu.FPopupMenu; -import forge.screens.FScreen; import forge.Graphics; +import forge.GuiBase; import forge.assets.FSkinImage; import forge.game.GameType; import forge.game.player.RegisteredPlayer; +import forge.interfaces.IGuiGame; +import forge.match.HostedMatch; +import forge.menu.FPopupMenu; +import forge.screens.match.MatchController; import forge.toolbox.FDisplayObject; import forge.toolbox.FOptionPane; import forge.util.Utils; @@ -53,6 +57,7 @@ public abstract class LaunchScreen extends FScreen { public GameType gameType; public final List players = new ArrayList(); public final Set appliedVariants = new HashSet(); + public final Set humanPlayers = new HashSet(); } protected void startMatch() { @@ -62,7 +67,7 @@ public abstract class LaunchScreen extends FScreen { LoadingOverlay.show("Loading new game...", new Runnable() { @Override public void run() { - LaunchParams launchParams = new LaunchParams(); + final LaunchParams launchParams = new LaunchParams(); if (buildLaunchParams(launchParams)) { if (launchParams.gameType == null) { throw new RuntimeException("Must set launchParams.gameType"); @@ -71,7 +76,13 @@ public abstract class LaunchScreen extends FScreen { throw new RuntimeException("Must add at least one player to launchParams.players"); } - MatchUtil.startMatch(launchParams.gameType, launchParams.appliedVariants, launchParams.players); + final Map guiMap = new HashMap(); + for (final RegisteredPlayer human : launchParams.humanPlayers) { + guiMap.put(human, MatchController.instance); + } + + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(launchParams.gameType, launchParams.appliedVariants, launchParams.players, guiMap); } creatingMatch = false; } diff --git a/forge-gui-mobile/src/forge/screens/constructed/ConstructedScreen.java b/forge-gui-mobile/src/forge/screens/constructed/ConstructedScreen.java index 01baba64352..2154f5ca4c0 100644 --- a/forge-gui-mobile/src/forge/screens/constructed/ConstructedScreen.java +++ b/forge-gui-mobile/src/forge/screens/constructed/ConstructedScreen.java @@ -373,6 +373,9 @@ public class ConstructedScreen extends LaunchScreen { rp.setTeamNumber(getTeam(i)); launchParams.players.add(rp.setPlayer(lobbyPlayer)); } + if (!playerPanel.isPlayerAI()) { + launchParams.humanPlayers.add(rp); + } getDeckChooser(i).saveState(); } diff --git a/forge-gui-mobile/src/forge/screens/limited/LoadSealedScreen.java b/forge-gui-mobile/src/forge/screens/limited/LoadSealedScreen.java index c804b0e4961..9c6cf9b8167 100644 --- a/forge-gui-mobile/src/forge/screens/limited/LoadSealedScreen.java +++ b/forge-gui-mobile/src/forge/screens/limited/LoadSealedScreen.java @@ -83,7 +83,7 @@ public class LoadSealedScreen extends LaunchScreen { } } - int matches = FModel.getDecks().getSealed().get(human.getName()).getAiDecks().size(); + final int matches = FModel.getDecks().getSealed().get(human.getName()).getAiDecks().size(); FModel.getGauntletMini().launch(matches, human.getDeck(), GameType.Sealed); return false; //prevent launching via launch screen since gauntlet handles it } diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index b92e7929a06..640798b2a8a 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -6,28 +6,37 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; - import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; import forge.Forge; import forge.Graphics; +import forge.GuiBase; import forge.LobbyPlayer; import forge.assets.FImage; import forge.assets.FSkin; +import forge.assets.FSkinProp; import forge.assets.FTextureRegionImage; +import forge.assets.ImageCache; import forge.card.CardRenderer; +import forge.card.GameEntityPicker; +import forge.deck.CardPool; +import forge.deck.FSideboardDialog; +import forge.game.GameEntity; import forge.game.GameEntityView; import forge.game.GameView; -import forge.game.Match; import forge.game.card.CardView; import forge.game.phase.PhaseType; -import forge.game.player.Player; +import forge.game.player.DelayedReveal; +import forge.game.player.IHasIcon; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.interfaces.IButton; -import forge.match.IMatchController; -import forge.match.MatchUtil; +import forge.item.PaperCard; +import forge.match.AbstractGuiGame; import forge.model.FModel; import forge.player.PlayerControllerHuman; import forge.properties.ForgePreferences; @@ -41,11 +50,15 @@ import forge.screens.match.views.VPlayerPanel.InfoTab; import forge.screens.match.views.VPrompt; import forge.screens.match.winlose.ViewWinLose; import forge.toolbox.FDisplayObject; +import forge.toolbox.FOptionPane; +import forge.util.FCollectionView; import forge.util.ITriggerEvent; +import forge.util.MessageUtil; import forge.util.WaitCallback; import forge.util.gui.SGuiChoose; +import forge.util.gui.SOptionPane; -public class MatchController implements IMatchController { +public class MatchController extends AbstractGuiGame { private MatchController() { } public static final MatchController instance = new MatchController(); @@ -57,6 +70,15 @@ public class MatchController implements IMatchController { return view; } + @Override + protected void updateCurrentPlayer(final PlayerView player) { + for (final PlayerView other : getLocalPlayers()) { + if (!other.equals(player)) { + updatePromptForAwait(other); + } + } + } + public static FImage getPlayerAvatar(final PlayerView p) { String lp = p.getLobbyPlayerName(); FImage avatar = avatarImages.get(lp); @@ -71,10 +93,6 @@ public class MatchController implements IMatchController { return avatar; } - public static void setPlayerAvatar(final LobbyPlayer lp, final FImage avatarImage) { - avatarImages.put(lp.getName(), avatarImage); - } - public void refreshCardDetails(Iterable cards) { //ensure cards appear in the correct row of the field for (VPlayerPanel pnl : view.getPlayerPanels().values()) { @@ -82,28 +100,25 @@ public class MatchController implements IMatchController { } } - @Override - public void startNewMatch(Match match) { - MatchUtil.startGame(match); - } - @Override public boolean resetForNewGame() { CardAreaPanel.resetForNewGame(); //ensure card panels reset between games return true; } - @Override public boolean hotSeatMode() { return FModel.getPreferences().getPrefBoolean(FPref.MATCH_HOT_SEAT_MODE); } @Override - public void openView(List sortedPlayers) { - boolean noHumans = MatchUtil.getHumanCount() == 0; - List playerPanels = new ArrayList(); - for (Player p : sortedPlayers) { - playerPanels.add(new VPlayerPanel(PlayerView.get(p), noHumans || p.getController() instanceof PlayerControllerHuman)); + public void openView(final FCollectionView myPlayers) { + setLocalPlayers(myPlayers); + final boolean noHumans = !hasLocalPlayers(); + + final FCollectionView allPlayers = getGameView().getPlayers(); + final List playerPanels = new ArrayList(); + for (final PlayerView p : allPlayers) { + playerPanels.add(new VPlayerPanel(p, noHumans || isLocalPlayer(p))); } view = new MatchScreen(playerPanels); @@ -118,7 +133,7 @@ public class MatchController implements IMatchController { @Override public void buildTouchListeners(float screenX, float screenY, ArrayList listeners) { if (screenY < view.getHeight() - VPrompt.HEIGHT) { - MatchUtil.pause(); + Forge.hostedMatch.pause(); } } }); @@ -140,7 +155,7 @@ public class MatchController implements IMatchController { } @Override - public void showPromptMessage(final PlayerView player, String message) { + public void showPromptMessage(final PlayerView player, final String message) { view.getPrompt(player).setMessage(message); } @@ -156,11 +171,11 @@ public class MatchController implements IMatchController { @Override public void updatePhase() { - GameView gameView = MatchUtil.getGameView(); + final GameView gameView = getGameView(); final PlayerView p = gameView.getPlayerTurn(); final PhaseType ph = gameView.getPhase(); - PhaseLabel lbl = view.getPlayerPanel(p).getPhaseIndicator().getLabel(ph); + final PhaseLabel lbl = view.getPlayerPanel(p).getPhaseIndicator().getLabel(ph); view.resetAllPhaseButtons(); if (lbl != null) { @@ -175,12 +190,11 @@ public class MatchController implements IMatchController { @Override public void updatePlayerControl() { //show/hide hand for top player based on whether the opponent is controlled - if (MatchUtil.getHumanCount() == 1) { - PlayerView player = view.getTopPlayerPanel().getPlayer(); + if (getLocalPlayerCount() == 1) { + final PlayerView player = view.getTopPlayerPanel().getPlayer(); if (player.getMindSlaveMaster() != null) { view.getTopPlayerPanel().setSelectedZone(ZoneType.Hand); - } - else { + } else { view.getTopPlayerPanel().setSelectedTab(null); } } @@ -196,7 +210,9 @@ public class MatchController implements IMatchController { @Override public void finishGame() { - new ViewWinLose(MatchUtil.getGameView()).setVisible(true); + if (hasLocalPlayers() || getGameView().isMatchOver()) { + new ViewWinLose(getGameView()).setVisible(true); + } } @Override @@ -328,7 +344,7 @@ public class MatchController implements IMatchController { @Override public void afterGameEnd() { Forge.back(); - view = null; + //view = null; } private static void actuateMatchPreferences() { @@ -396,4 +412,103 @@ public class MatchController implements IMatchController { prefs.save(); } + + @Override + public void message(final String message, final String title) { + SOptionPane.showMessageDialog(message, title); + } + + @Override + public void showErrorDialog(final String message, final String title) { + SOptionPane.showErrorDialog(message, title); + } + + @Override + public boolean showConfirmDialog(final String message, final String title, final String yesButtonText, final String noButtonText, final boolean defaultYes) { + return SOptionPane.showConfirmDialog(message, title, yesButtonText, noButtonText, defaultYes); + } + + @Override + public int showOptionDialog(final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { + return SOptionPane.showOptionDialog(message, title, icon, options, defaultOption); + } + + @Override + public int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { + return FOptionPane.showCardOptionDialog(card, message, title, icon, options, defaultOption); + } + + @Override + public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput, final String[] inputOptions) { + return SOptionPane.showInputDialog(message, title, icon, initialInput, inputOptions); + } + + @Override + public boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) { + return FOptionPane.showCardOptionDialog(c, question, "", SOptionPane.INFORMATION_ICON, options, defaultIsYes ? 1 : 0) == 1; + } + + @Override + public List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display) { + return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display); + } + + @Override + public List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { + return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices); + } + + @Override + public List sideboard(final CardPool sideboard, final CardPool main) { + return new WaitCallback>() { + @Override + public void run() { + FSideboardDialog sideboardDialog = new FSideboardDialog(sideboard, main, this); + sideboardDialog.show(); + } + }.invokeAndWait(); + } + + @Override + public GameEntityView chooseSingleEntityForEffect(final String title, final FCollectionView optionList, final DelayedReveal delayedReveal, final boolean isOptional, final PlayerControllerHuman controller) { + controller.tempShow(optionList); + final List choiceList = GameEntityView.getEntityCollection(optionList); + + if (delayedReveal == null || Iterables.isEmpty(delayedReveal.getCards())) { + if (isOptional) { + return SGuiChoose.oneOrNone(title, choiceList); + } + return SGuiChoose.one(title, choiceList); + } + + controller.tempShow(delayedReveal.getCards()); + final List revealList = CardView.getCollection(delayedReveal.getCards()); + final String revealListCaption = StringUtils.capitalize(MessageUtil.formatMessage("{player's} " + delayedReveal.getZone().name(), controller.getPlayer(), delayedReveal.getOwner())); + final FImage revealListImage = MatchController.getView().getPlayerPanels().values().iterator().next().getZoneTab(delayedReveal.getZone()).getIcon(); + + //use special dialog for choosing card and offering ability to see all revealed cards at the same time + return new WaitCallback() { + @Override + public void run() { + GameEntityPicker picker = new GameEntityPicker(title, choiceList, revealList, revealListCaption, revealListImage, isOptional, this); + picker.show(); + } + }.invokeAndWait(); + } + + @Override + public void setCard(final CardView card) { + // doesn't need to do anything + } + + @Override + public void setPlayerAvatar(final LobbyPlayer player, final IHasIcon ihi) { + avatarImages.put(player.getName(), ImageCache.getIcon(ihi)); + } + + @Override + public boolean isUiSetToSkipPhase(final PlayerView playerTurn, final PhaseType phase) { + return !view.stopAtPhase(playerTurn, phase); + } + } diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 550fb1ccf0b..12db0b9ff85 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -26,7 +26,7 @@ import forge.game.combat.CombatView; import forge.game.phase.PhaseType; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; +import forge.interfaces.IGameController; import forge.menu.FDropDown; import forge.menu.FDropDownMenu; import forge.menu.FMenuBar; @@ -86,17 +86,17 @@ public class MatchScreen extends FScreen { new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().selectButtonOk(); + getGameController().selectButtonOk(); } }, new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().selectButtonCancel(); + getGameController().selectButtonCancel(); } })); - if (MatchUtil.getHumanCount() <= 1 || MatchUtil.getController().hotSeatMode()) { + if (MatchController.instance.getLocalPlayerCount() <= 1 || MatchController.instance.hotSeatMode()) { topPlayerPrompt = null; } else { //show top prompt if multiple human players and not playing in Hot Seat mode @@ -104,13 +104,13 @@ public class MatchScreen extends FScreen { new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().selectButtonOk(); + getGameController().selectButtonOk(); } }, new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().selectButtonCancel(); + getGameController().selectButtonCancel(); } })); topPlayerPrompt.setRotate180(true); @@ -151,6 +151,10 @@ public class MatchScreen extends FScreen { } } + private IGameController getGameController() { + return MatchController.instance.getGameController(); + } + private class HiddenMenuTab extends FMenuTab { private HiddenMenuTab(FDropDown dropDown0) { super(null, null, dropDown0, -1); @@ -230,7 +234,7 @@ public class MatchScreen extends FScreen { } public boolean isTopHumanPlayerActive() { - return topPlayerPrompt != null && topPlayerPanel.getPlayer() == MatchUtil.getCurrentPlayer().getView(); + return topPlayerPrompt != null && topPlayerPanel.getPlayer() == MatchController.instance.getCurrentPlayer(); } public VPrompt getActivePrompt() { @@ -299,7 +303,7 @@ public class MatchScreen extends FScreen { @Override protected void drawOverlay(Graphics g) { - GameView game = MatchUtil.getGameView(); + final GameView game = MatchController.instance.getGameView(); if (game == null) { return; } //draw arrows for paired cards @@ -361,25 +365,25 @@ public class MatchScreen extends FScreen { return true; //suppress Back button so it's not bumped when trying to press OK or Cancel buttons case Keys.A: //alpha strike on Ctrl+A if (KeyInputAdapter.isCtrlKeyDown()) { - MatchUtil.alphaStrike(); + getGameController().alphaStrike(); return true; } break; case Keys.E: //end turn on Ctrl+E if (KeyInputAdapter.isCtrlKeyDown()) { - MatchUtil.endCurrentTurn(); + getGameController().passPriorityUntilEndOfTurn(); return true; } break; case Keys.Q: //concede game on Ctrl+Q if (KeyInputAdapter.isCtrlKeyDown()) { - MatchUtil.concede(); + getGameController().concede(); return true; } break; case Keys.Z: //undo on Ctrl+Z if (KeyInputAdapter.isCtrlKeyDown()) { - MatchUtil.getHumanController().tryUndoLastAction(); + getGameController().tryUndoLastAction(); return true; } break; @@ -393,7 +397,7 @@ public class MatchScreen extends FScreen { } public boolean stopAtPhase(final PlayerView turn, final PhaseType phase) { - PhaseLabel label = getPlayerPanel(turn).getPhaseIndicator().getLabel(phase); + final PhaseLabel label = getPlayerPanel(turn).getPhaseIndicator().getLabel(phase); return label == null || label.getStopAtPhase(); } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VAssignDamage.java b/forge-gui-mobile/src/forge/screens/match/views/VAssignDamage.java index cf838473c49..9be0824eef9 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VAssignDamage.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VAssignDamage.java @@ -27,7 +27,6 @@ import forge.card.CardZoom; import forge.game.GameEntityView; import forge.game.card.CardView; import forge.game.player.PlayerView; -import forge.match.MatchUtil; import forge.screens.match.MatchController; import forge.toolbox.FButton; import forge.toolbox.FCardPanel; @@ -457,7 +456,7 @@ public class VAssignDamage extends FDialog { if (source == null) { if (defender instanceof PlayerView) { PlayerView p = (PlayerView)defender; - lethalDamage = attackerHasInfect ? MatchUtil.getGameView().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife(); + lethalDamage = attackerHasInfect ? MatchController.instance.getGameView().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife(); } else if (defender instanceof CardView) { // planeswalker CardView pw = (CardView)defender; diff --git a/forge-gui-mobile/src/forge/screens/match/views/VAutoYields.java b/forge-gui-mobile/src/forge/screens/match/views/VAutoYields.java index e8d431166cc..90109f7a070 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VAutoYields.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VAutoYields.java @@ -5,8 +5,7 @@ import java.util.List; import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds; -import forge.game.Game; -import forge.game.player.Player; +import forge.screens.match.MatchController; import forge.toolbox.FButton; import forge.toolbox.FCheckBox; import forge.toolbox.FChoiceList; @@ -21,10 +20,10 @@ public class VAutoYields extends FDialog { private final FChoiceList lstAutoYields; private final FCheckBox chkDisableAll; - public VAutoYields(final Game game, final Player player) { + public VAutoYields() { super("Auto-Yields"); List autoYields = new ArrayList(); - for (String autoYield : player.getController().getAutoYields()) { + for (String autoYield : MatchController.instance.getAutoYields()) { autoYields.add(autoYield); } lstAutoYields = add(new FChoiceList(autoYields) { @@ -38,11 +37,11 @@ public class VAutoYields extends FDialog { return true; } }); - chkDisableAll = add(new FCheckBox("Disable All Auto Yields", game.getDisableAutoYields())); + chkDisableAll = add(new FCheckBox("Disable All Auto Yields", MatchController.instance.getDisableAutoYields())); chkDisableAll.setCommand(new FEventHandler() { @Override public void handleEvent(FEvent e) { - game.setDisableAutoYields(chkDisableAll.isSelected()); + MatchController.instance.setDisableAutoYields(chkDisableAll.isSelected()); } }); btnOk = add(new FButton("OK", new FEventHandler() { @@ -57,7 +56,7 @@ public class VAutoYields extends FDialog { String selected = lstAutoYields.getSelectedItem(); if (selected != null) { lstAutoYields.removeItem(selected); - player.getController().setShouldAutoYield(selected, false); + MatchController.instance.setShouldAutoYield(selected, false); btnRemove.setEnabled(lstAutoYields.getCount() > 0); lstAutoYields.cleanUpSelections(); VAutoYields.this.revalidate(); diff --git a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java index 8fc63e7f8f4..e7b7d9ab211 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VAvatar.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.math.Vector2; import forge.Graphics; import forge.assets.FImage; import forge.game.player.PlayerView; -import forge.match.MatchUtil; import forge.screens.match.MatchController; import forge.toolbox.FDisplayObject; import forge.util.ThreadUtil; @@ -29,7 +28,7 @@ public class VAvatar extends FDisplayObject { ThreadUtil.invokeInGameThread(new Runnable() { //must invoke in game thread in case a dialog needs to be shown @Override public void run() { - MatchUtil.getHumanController().selectPlayer(player, null); + MatchController.instance.getGameController().selectPlayer(player, null); } }); return true; diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index 6093de7741b..f7fd0c575a5 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -13,7 +13,7 @@ import forge.card.CardZoom; import forge.card.CardRenderer.CardStackPosition; import forge.card.CardZoom.ActivateHandler; import forge.game.card.CardView; -import forge.match.MatchUtil; +import forge.screens.match.MatchController; import forge.toolbox.FCardPanel; import forge.toolbox.FDisplayObject; import forge.util.ThreadUtil; @@ -180,7 +180,7 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH @Override public String getActivateAction(int index) { - return MatchUtil.getHumanController().getInputProxy().getActivateAction(orderedCards.get(index)); + return MatchController.instance.getGameController().getActivateDescription(orderedCards.get(index)); } @Override @@ -359,7 +359,7 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH } public boolean selectCard(boolean selectEntireStack) { - if (MatchUtil.getHumanController().selectCard(getCard(), getOtherCardsToSelect(selectEntireStack), null)) { + if (MatchController.instance.getGameController().selectCard(getCard(), getOtherCardsToSelect(selectEntireStack), null)) { return true; } //if panel can't do anything with card selection, try selecting previous panel in stack diff --git a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java index dc5fd87cf5f..ef4c0622df8 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VDevMenu.java @@ -1,9 +1,9 @@ package forge.screens.match.views; -import forge.match.MatchUtil; import forge.menu.FCheckBoxMenuItem; import forge.menu.FDropDownMenu; import forge.menu.FMenuItem; +import forge.screens.match.MatchController; import forge.toolbox.FEvent; import forge.toolbox.FEvent.FEventHandler; import forge.util.ThreadUtil; @@ -17,7 +17,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { //must invoke all these in game thread since they may require synchronous user input @Override public void run() { - MatchUtil.getHumanController().cheat().generateMana(); + MatchController.instance.getGameController().cheat().generateMana(); } }); } @@ -28,7 +28,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().tutorForCard(); + MatchController.instance.getGameController().cheat().tutorForCard(); } }); } @@ -39,7 +39,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().addCardToHand(); + MatchController.instance.getGameController().cheat().addCardToHand(); } }); } @@ -50,7 +50,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().addCardToBattlefield(); + MatchController.instance.getGameController().cheat().addCardToBattlefield(); } }); } @@ -61,7 +61,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().setPlayerLife(); + MatchController.instance.getGameController().cheat().setPlayerLife(); } }); } @@ -72,7 +72,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().winGame(); + MatchController.instance.getGameController().cheat().winGame(); } }); } @@ -83,7 +83,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().setupGameState(); + MatchController.instance.getGameController().cheat().setupGameState(); } }); } @@ -94,26 +94,26 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().dumpGameState(); + MatchController.instance.getGameController().cheat().dumpGameState(); } }); } })); - final boolean unlimitedLands = MatchUtil.getHumanController().canPlayUnlimitedLands(); + final boolean unlimitedLands = MatchController.instance.getGameController().canPlayUnlimitedLands(); addItem(new FCheckBoxMenuItem("Play Unlimited Lands", unlimitedLands, new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().cheat().setCanPlayUnlimitedLands(!unlimitedLands); + MatchController.instance.getGameController().cheat().setCanPlayUnlimitedLands(!unlimitedLands); } })); - final boolean viewAll = MatchUtil.getHumanController().mayLookAtAllCards(); + final boolean viewAll = MatchController.instance.getGameController().mayLookAtAllCards(); addItem(new FCheckBoxMenuItem("View All Cards", viewAll, new FEventHandler() { @Override public void handleEvent(FEvent e) { - MatchUtil.getHumanController().cheat().setViewAllCards(!viewAll); + MatchController.instance.getGameController().cheat().setViewAllCards(!viewAll); } })); addItem(new FMenuItem("Add Counters to Permanent", new FEventHandler() { @@ -122,7 +122,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().addCountersToPermanent(); + MatchController.instance.getGameController().cheat().addCountersToPermanent(); } }); } @@ -133,7 +133,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().tapPermanents(); + MatchController.instance.getGameController().cheat().tapPermanents(); } }); } @@ -144,7 +144,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().untapPermanents(); + MatchController.instance.getGameController().cheat().untapPermanents(); } }); } @@ -155,7 +155,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().riggedPlanarRoll(); + MatchController.instance.getGameController().cheat().riggedPlanarRoll(); } }); } @@ -166,7 +166,7 @@ public class VDevMenu extends FDropDownMenu { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.getHumanController().cheat().planeswalkTo(); + MatchController.instance.getGameController().cheat().planeswalkTo(); } }); } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java b/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java index dad8cbdec7e..ae33085240d 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VGameMenu.java @@ -1,14 +1,12 @@ package forge.screens.match.views; +import forge.Forge; import forge.assets.FSkinImage; import forge.deck.Deck; import forge.deck.FDeckViewer; -import forge.game.Game; -import forge.game.player.Player; -import forge.game.spellability.SpellAbility; -import forge.match.MatchUtil; import forge.menu.FDropDownMenu; import forge.menu.FMenuItem; +import forge.screens.match.MatchController; import forge.screens.settings.SettingsScreen; import forge.toolbox.FEvent; import forge.toolbox.FEvent.FEventHandler; @@ -20,14 +18,14 @@ public class VGameMenu extends FDropDownMenu { @Override protected void buildMenu() { - final Game game = MatchUtil.getGame(); + addItem(new FMenuItem("Concede", FSkinImage.CONCEDE, new FEventHandler() { @Override public void handleEvent(FEvent e) { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - MatchUtil.concede(); + MatchController.instance.getGameController().concede(); } }); } @@ -48,7 +46,7 @@ public class VGameMenu extends FDropDownMenu { addItem(new FMenuItem("Deck List", FSkinImage.DECKLIST, new FEventHandler() { @Override public void handleEvent(FEvent e) { - final Deck deck = MatchUtil.getCurrentPlayer().getRegisteredPlayer().getDeck(); + final Deck deck = Forge.hostedMatch.getGame().getPhaseHandler().getPlayerTurn().getRegisteredPlayer().getDeck(); if (deck != null) { FDeckViewer.show(deck); } @@ -57,20 +55,20 @@ public class VGameMenu extends FDropDownMenu { addItem(new FMenuItem("Auto-Yields", FSkinImage.WARNING, new FEventHandler() { @Override public void handleEvent(FEvent e) { - final Player localPlayer = MatchUtil.getCurrentPlayer(); - if (localPlayer == null) { return; } - - final boolean autoYieldsDisabled = game.getDisableAutoYields(); - VAutoYields autoYields = new VAutoYields(game, localPlayer) { + final boolean autoYieldsDisabled = MatchController.instance.getDisableAutoYields(); + final VAutoYields autoYields = new VAutoYields() { @Override public void setVisible(boolean b0) { super.setVisible(b0); if (!b0) { - if (autoYieldsDisabled && !game.getDisableAutoYields()) { + if (autoYieldsDisabled && !MatchController.instance.getDisableAutoYields()) { //if re-enabling auto-yields, auto-yield to current ability on stack if applicable - SpellAbility ability = game.getStack().peekAbility(); - if (ability != null && ability.isAbility() && localPlayer.getController().shouldAutoYield(ability.toUnsuppressedString())) { - MatchUtil.getHumanController().passPriority(); + final String key = MatchController.instance.getGameView().peekStack().getKey(); + final boolean autoYield = MatchController.instance.shouldAutoYield(key); + MatchController.instance.setShouldAutoYield(key, !autoYield); + if (!autoYield && MatchController.instance.shouldAutoYield(key)) { + //auto-pass priority if ability is on top of stack + MatchController.instance.getGameController().passPriority(); } } } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VLog.java b/forge-gui-mobile/src/forge/screens/match/views/VLog.java index a6057c18469..8d375c9250a 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VLog.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VLog.java @@ -11,10 +11,10 @@ import forge.assets.TextRenderer; import forge.assets.FSkinColor.Colors; import forge.game.GameLogEntry; import forge.game.GameLogEntryType; -import forge.match.MatchUtil; import forge.menu.FDropDown; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; +import forge.screens.match.MatchController; import forge.toolbox.FDisplayObject; import forge.util.Utils; @@ -45,7 +45,7 @@ public class VLog extends FDropDown { clear(); GameLogEntryType logVerbosityFilter = GameLogEntryType.valueOf(FModel.getPreferences().getPref(FPref.DEV_LOG_ENTRY_TYPE)); - List logEntrys = MatchUtil.getGameView().getGameLog().getLogEntries(logVerbosityFilter); + List logEntrys = MatchController.instance.getGameView().getGameLog().getLogEntries(logVerbosityFilter); LogEntryDisplay logEntryDisplay; float width = maxWidth - getMenuTab().screenPos.x; //stretch from tab to edge of screen diff --git a/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java b/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java index 0f0b3d081e3..67edc0c3a86 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VManaPool.java @@ -12,8 +12,8 @@ import forge.assets.FSkinImage; import forge.assets.FSkinColor.Colors; import forge.card.MagicColor; import forge.game.player.PlayerView; -import forge.match.MatchUtil; import forge.player.GamePlayerUtil; +import forge.screens.match.MatchController; import forge.toolbox.FDisplayObject; public class VManaPool extends VDisplayArea { @@ -82,7 +82,7 @@ public class VManaPool extends VDisplayArea { @Override public boolean tap(float x, float y, int count) { if (player.isLobbyPlayer(GamePlayerUtil.getGuiPlayer())) { - MatchUtil.getHumanController().useMana(colorCode); + MatchController.instance.getGameController().useMana(colorCode); } return true; } @@ -91,7 +91,7 @@ public class VManaPool extends VDisplayArea { public boolean flick(float x, float y) { if (player.isLobbyPlayer(GamePlayerUtil.getGuiPlayer())) { //on two finger tap, keep using mana until it runs out or no longer can be put towards the cost - while (MatchUtil.getHumanController().useMana(colorCode)) {} + while (MatchController.instance.getGameController().useMana(colorCode)) {} } return true; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java b/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java index 86f1e9d7c77..de29e7c861d 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VPlayerPanel.java @@ -16,7 +16,6 @@ import forge.assets.FSkinColor.Colors; import forge.game.card.CardView; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.screens.match.MatchController; @@ -299,7 +298,7 @@ public class VPlayerPanel extends FContainer { } //when gui player loses life, vibrate device for a length of time based on amount of life lost - if (vibrateDuration > 0 && player.isLobbyPlayer(MatchUtil.getGuiPlayer()) && + if (vibrateDuration > 0 && MatchController.instance.isLocalPlayer(player) && FModel.getPreferences().getPrefBoolean(FPref.UI_VIBRATE_ON_LIFE_LOSS)) { //never vibrate more than two seconds regardless of life lost or poison counters gained Gdx.input.vibrate(Math.min(vibrateDuration, 2000)); @@ -308,7 +307,7 @@ public class VPlayerPanel extends FContainer { @Override public boolean tap(float x, float y, int count) { - MatchUtil.getHumanController().selectPlayer(player, null); //treat tapping on life the same as tapping on the avatar + MatchController.instance.getGameController().selectPlayer(player, null); //treat tapping on life the same as tapping on the avatar return true; } diff --git a/forge-gui-mobile/src/forge/screens/match/views/VPlayers.java b/forge-gui-mobile/src/forge/screens/match/views/VPlayers.java index 6602a6df273..15ef1d4a779 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VPlayers.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VPlayers.java @@ -5,10 +5,8 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import forge.Graphics; import forge.assets.FImage; import forge.assets.FSkinFont; -import forge.game.card.CardFactoryUtil; import forge.game.card.CardView; import forge.game.player.PlayerView; -import forge.match.MatchUtil; import forge.menu.FDropDown; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; @@ -20,7 +18,7 @@ import forge.util.Utils; public class VPlayers extends FDropDown { public VPlayers() { - for (final PlayerView p : MatchUtil.getGameView().getPlayers()) { + for (final PlayerView p : MatchController.instance.getGameView().getPlayers()) { add(new PlayerInfoPanel(p)); } } @@ -89,8 +87,8 @@ public class VPlayers extends FDropDown { builder.append(cv); } } - if (MatchUtil.getGameView().isCommander()) { - builder.append(" | " + CardFactoryUtil.getCommanderInfo(player)); + if (MatchController.instance.getGameView().isCommander()) { + builder.append(" | " + player.getCommanderInfo()); } g.drawText(builder.toString(), FONT, FList.FORE_COLOR, x, y, getWidth() - PADDING - x, h, true, HAlignment.LEFT, true); 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 f216897207f..30e485f6ef1 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VStack.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VStack.java @@ -19,18 +19,18 @@ import forge.card.CardRenderer; import forge.card.CardZoom; import forge.card.CardDetailUtil.DetailColors; import forge.card.CardRenderer.CardStackPosition; +import forge.game.GameView; import forge.game.card.CardView; -import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.spellability.StackItemView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; +import forge.interfaces.IGameController; +import forge.interfaces.IGuiGame; import forge.menu.FCheckBoxMenuItem; import forge.menu.FDropDown; import forge.menu.FMenuItem; import forge.menu.FMenuTab; import forge.menu.FPopupMenu; -import forge.player.PlayerControllerHuman; import forge.screens.match.MatchController; import forge.screens.match.TargetingOverlay; import forge.toolbox.FCardPanel; @@ -94,7 +94,7 @@ public class VStack extends FDropDown { activeStackInstance = null; //reset before updating stack restoreOldZones(); - final FCollectionView stack = MatchUtil.getGameView().getStack(); + final FCollectionView stack = MatchController.instance.getGameView().getStack(); if (stackSize != stack.size()) { int oldStackSize = stackSize; stackSize = stack.size(); @@ -125,7 +125,7 @@ public class VStack extends FDropDown { float totalWidth = maxWidth - MatchController.getView().getTopPlayerPanel().getTabs().iterator().next().getRight(); //keep avatar, life total, and hand tab visible to left of stack float width = totalWidth - 2 * MARGINS; - final FCollectionView stack = MatchUtil.getGameView().getStack(); + final FCollectionView stack = MatchController.instance.getGameView().getStack(); if (stack.isEmpty()) { //show label if stack empty FLabel label = add(new FLabel.Builder().text("[Empty]").font(FONT).align(HAlignment.CENTER).build()); @@ -227,7 +227,7 @@ public class VStack extends FDropDown { text = stackInstance.getText(); if (stackInstance.isOptionalTrigger() && - stackInstance0.getActivatingPlayer().equals(MatchUtil.getCurrentPlayer())) { + stackInstance0.getActivatingPlayer().equals(MatchController.instance.getCurrentPlayer())) { text = "(OPTIONAL) " + text; } @@ -250,59 +250,60 @@ public class VStack extends FDropDown { VStack.this.updateSizeAndPosition(); return true; } - final Player player = MatchUtil.getCurrentPlayer(); - if (player != null) { //don't show menu if tapping on art + final GameView gameView = MatchController.instance.getGameView(); + final IGuiGame gui = MatchController.instance; + final IGameController controller = MatchController.instance.getGameController(); + final PlayerView player = MatchController.instance.getCurrentPlayer(); + if (MatchController.instance.getCurrentPlayer() != null) { //don't show menu if tapping on art if (stackInstance.isAbility()) { FPopupMenu menu = new FPopupMenu() { @Override protected void buildMenu() { - final PlayerControllerHuman humanController = MatchUtil.getHumanController(); - final PlayerView playerView = PlayerView.get(player); final String key = stackInstance.getKey(); - final boolean autoYield = humanController.shouldAutoYield(key); + final boolean autoYield = gui.shouldAutoYield(key); addItem(new FCheckBoxMenuItem("Auto-Yield", autoYield, new FEventHandler() { @Override public void handleEvent(FEvent e) { - humanController.setShouldAutoYield(key, !autoYield); - if (!autoYield && stackInstance.equals(MatchUtil.getGameView().peekStack())) { + gui.setShouldAutoYield(key, !autoYield); + if (!autoYield && stackInstance.equals(gameView.peekStack())) { //auto-pass priority if ability is on top of stack - humanController.passPriority(); + controller.passPriority(); } } })); - if (stackInstance.isOptionalTrigger() && stackInstance.getActivatingPlayer().equals(playerView)) { + if (stackInstance.isOptionalTrigger() && stackInstance.getActivatingPlayer().equals(player)) { final int triggerID = stackInstance.getSourceTrigger(); addItem(new FCheckBoxMenuItem("Always Yes", - humanController.shouldAlwaysAcceptTrigger(triggerID), + gui.shouldAlwaysAcceptTrigger(triggerID), new FEventHandler() { @Override public void handleEvent(FEvent e) { - if (humanController.shouldAlwaysAcceptTrigger(triggerID)) { - humanController.setShouldAlwaysAskTrigger(triggerID); + if (gui.shouldAlwaysAcceptTrigger(triggerID)) { + gui.setShouldAlwaysAskTrigger(triggerID); } else { - humanController.setShouldAlwaysAcceptTrigger(triggerID); - if (stackInstance.equals(MatchUtil.getGameView().peekStack())) { + gui.setShouldAlwaysAcceptTrigger(triggerID); + if (stackInstance.equals(gameView.peekStack())) { //auto-yes if ability is on top of stack - humanController.confirm(); + controller.selectButtonOk(); } } } })); addItem(new FCheckBoxMenuItem("Always No", - humanController.shouldAlwaysDeclineTrigger(triggerID), + gui.shouldAlwaysDeclineTrigger(triggerID), new FEventHandler() { @Override public void handleEvent(FEvent e) { - if (humanController.shouldAlwaysDeclineTrigger(triggerID)) { - humanController.setShouldAlwaysAskTrigger(triggerID); + if (gui.shouldAlwaysDeclineTrigger(triggerID)) { + gui.setShouldAlwaysAskTrigger(triggerID); } else { - humanController.setShouldAlwaysDeclineTrigger(triggerID); - if (stackInstance.equals(MatchUtil.getGameView().peekStack())) { + gui.setShouldAlwaysDeclineTrigger(triggerID); + if (stackInstance.equals(gameView.peekStack())) { //auto-no if ability is on top of stack - humanController.confirm(); + controller.selectButtonOk(); } } } diff --git a/forge-gui-mobile/src/forge/screens/match/winlose/ControlWinLose.java b/forge-gui-mobile/src/forge/screens/match/winlose/ControlWinLose.java index 2d2bcb5b4b1..6aa1241e426 100644 --- a/forge-gui-mobile/src/forge/screens/match/winlose/ControlWinLose.java +++ b/forge-gui-mobile/src/forge/screens/match/winlose/ControlWinLose.java @@ -1,7 +1,7 @@ package forge.screens.match.winlose; +import forge.Forge; import forge.game.GameView; -import forge.match.MatchUtil; import forge.screens.match.MatchController; import forge.toolbox.FEvent; import forge.toolbox.FEvent.FEventHandler; @@ -54,21 +54,21 @@ public class ControlWinLose { view.hide(); saveOptions(); - MatchUtil.continueMatch(); + Forge.hostedMatch.continueMatch(); } /** Action performed when "restart" button is pressed in default win/lose UI. */ public void actionOnRestart() { view.hide(); saveOptions(); - MatchUtil.restartMatch(); + Forge.hostedMatch.restartMatch(); } /** Action performed when "quit" button is pressed in default win/lose UI. */ public void actionOnQuit() { // Reset other stuff saveOptions(); - MatchUtil.endCurrentGame(); + Forge.hostedMatch.endCurrentGame(); view.hide(); } diff --git a/forge-gui-mobile/src/forge/toolbox/FDialog.java b/forge-gui-mobile/src/forge/toolbox/FDialog.java index 9ee1e6f87aa..97bbb70d5b1 100644 --- a/forge-gui-mobile/src/forge/toolbox/FDialog.java +++ b/forge-gui-mobile/src/forge/toolbox/FDialog.java @@ -9,8 +9,8 @@ import forge.assets.FSkinFont; import forge.assets.FSkinImage; import forge.assets.FSkinTexture; import forge.assets.FSkinColor.Colors; -import forge.match.input.InputBase; import forge.screens.FScreen; +import forge.screens.match.MatchController; import forge.util.Utils; public abstract class FDialog extends FOverlay { @@ -58,7 +58,7 @@ public abstract class FDialog extends FOverlay { if (visible0) { openDialogCount++; - InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." prompt doesn't appear while dialog awaiting input + MatchController.instance.cancelAwaitNextInput(); //ensure "Waiting for opponent..." prompt doesn't appear while dialog awaiting input } else if (openDialogCount > 0) { openDialogCount--; diff --git a/forge-gui-mobile/src/forge/toolbox/FOptionPane.java b/forge-gui-mobile/src/forge/toolbox/FOptionPane.java index 174c586759c..47adbd05d2d 100644 --- a/forge-gui-mobile/src/forge/toolbox/FOptionPane.java +++ b/forge-gui-mobile/src/forge/toolbox/FOptionPane.java @@ -6,9 +6,11 @@ import com.badlogic.gdx.math.Vector2; import forge.Forge; import forge.Graphics; +import forge.assets.FSkin; import forge.assets.FSkinFont; import forge.assets.FImage; import forge.assets.FSkinImage; +import forge.assets.FSkinProp; import forge.card.CardRenderer; import forge.card.CardZoom; import forge.card.CardRenderer.CardStackPosition; @@ -16,6 +18,7 @@ import forge.screens.match.views.VPrompt; import forge.toolbox.FEvent.*; import forge.util.Callback; import forge.util.Utils; +import forge.util.WaitCallback; import forge.game.card.CardView; public class FOptionPane extends FDialog { @@ -94,6 +97,15 @@ public class FOptionPane extends FDialog { optionPane.show(); } + public static int showCardOptionDialog(final CardView card, final String message, final String title, final FSkinProp icon, final String[] options, final int defaultOption) { + return new WaitCallback() { + @Override + public void run() { + FOptionPane.showCardOptionDialog(card, message, title, icon == null ? null : FSkin.getImages().get(icon), options, defaultOption, this); + } + }.invokeAndWait(); + } + public static void showCardOptionDialog(final CardView card, String message, String title, FImage icon, String[] options, int defaultOption, final Callback callback) { final FDisplayObject cardDisplay; if (card != null) { diff --git a/forge-gui/src/main/java/forge/achievement/AchievementCollection.java b/forge-gui/src/main/java/forge/achievement/AchievementCollection.java index 506802a021a..c877263cbd7 100644 --- a/forge-gui/src/main/java/forge/achievement/AchievementCollection.java +++ b/forge-gui/src/main/java/forge/achievement/AchievementCollection.java @@ -18,7 +18,6 @@ import forge.game.Game; import forge.game.GameType; import forge.game.player.Player; import forge.interfaces.IComboBox; -import forge.match.MatchUtil; import forge.model.FModel; import forge.player.PlayerControllerHuman; import forge.properties.ForgeConstants; @@ -35,9 +34,9 @@ public abstract class AchievementCollection implements Iterable { FileUtil.ensureDirectoryExists(ForgeConstants.ACHIEVEMENTS_DIR); } - public static void updateAll(PlayerControllerHuman controller) { - //don't update achievements if player cheated during game or if it's not just a single human player - if (controller.hasCheated() || MatchUtil.getHumanCount() != 1) { + public static void updateAll(final PlayerControllerHuman controller) { + //don't update achievements if player cheated during game + if (controller.hasCheated()) { return; } diff --git a/forge-gui/src/main/java/forge/card/CardDetailUtil.java b/forge-gui/src/main/java/forge/card/CardDetailUtil.java index 97e8aab33e5..992e3695d62 100644 --- a/forge-gui/src/main/java/forge/card/CardDetailUtil.java +++ b/forge-gui/src/main/java/forge/card/CardDetailUtil.java @@ -5,11 +5,11 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; + import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Sets; -import forge.game.GameView; import forge.game.card.CardUtil; import forge.game.card.CardView; import forge.game.card.CardView.CardStateView; @@ -17,7 +17,6 @@ import forge.game.card.CounterType; import forge.item.InventoryItemFromSet; import forge.item.PreconDeck; import forge.item.SealedProduct; -import forge.match.MatchUtil; import forge.util.Lang; public class CardDetailUtil { @@ -477,8 +476,10 @@ public class CardDetailUtil { } //show current storm count for storm cards + // TODO add Storm + /* if (state.hasStorm()) { - GameView gameView = MatchUtil.getGameView(); + GameView gameView = HostedMatch.getGameView(); if (gameView != null) { if (area.length() != 0) { area.append("\n\n"); @@ -486,6 +487,7 @@ public class CardDetailUtil { area.append("Current Storm Count: " + gameView.getStormCount()); } } + */ return area.toString(); } } diff --git a/forge-gui/src/main/java/forge/card/CardScriptParser.java b/forge-gui/src/main/java/forge/card/CardScriptParser.java new file mode 100644 index 00000000000..b00be6998d6 --- /dev/null +++ b/forge-gui/src/main/java/forge/card/CardScriptParser.java @@ -0,0 +1,522 @@ +package forge.card; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import forge.game.ability.ApiType; +import forge.game.trigger.TriggerType; + +public final class CardScriptParser { + + private final String script; + private final Set sVars = Sets.newTreeSet(), sVarAbilities = Sets.newTreeSet(); + public CardScriptParser(final String script) { + this.script = script; + + final String[] lines = StringUtils.split(script, "\r\n"); + for (final String line : lines) { + if (StringUtils.isEmpty(line)) { + continue; + } + if (line.startsWith("SVar:")) { + final String[] sVarParts = StringUtils.split(line, ':'); + if (sVarParts.length != 3) { + continue; + } + sVars.add(sVarParts[1]); + } + } + } + + public boolean hasErrors() { + return !getErrorRegions(true).isEmpty(); + } + + public Map getErrorRegions() { + return getErrorRegions(false); + } + + /** + * Find all erroneous regions of this script. + * + * @param quick + * if {@code true}, stop when the first region is found. + * @return a {@link Map} mapping the starting index of each error region to + * the length of that region. + */ + private Map getErrorRegions(final boolean quick) { + final Map result = Maps.newTreeMap(); + + final String[] lines = StringUtils.split(script, '\n'); + int index = 0; + for (final String line : lines) { + final String trimLine = line.trim(); + if (StringUtils.isEmpty(line)) { + continue; + } + boolean bad = false; + if (trimLine.startsWith("Name:") && trimLine.length() > "Name:".length()) { + // whatever, nonempty name is always ok! + } else if (trimLine.startsWith("ManaCost:")) { + if (!isManaCostLegal(trimLine.substring("ManaCost:".length()))) { + bad = true; + } + } else if (trimLine.startsWith("Types:")) { + if (!isTypeLegal(trimLine.substring("Types:".length()))) { + bad = true; + } + } else if (trimLine.startsWith("A:")) { + result.putAll(getActivatedAbilityErrors(trimLine.substring("A:".length()), index + "A:".length())); + } else if (trimLine.startsWith("T:")) { + result.putAll(getTriggerErrors(trimLine.substring("T:".length()), index + "T:".length())); + } else if (trimLine.startsWith("SVar:")) { + final String[] sVarParts = trimLine.split(":", 3); + if (sVarParts.length != 3) { + bad = true; + } + if (sVarAbilities.contains(sVarParts[1])) { + result.putAll(getSubAbilityErrors(sVarParts[2], index + "SVar:".length() + 1 + sVarParts[1].length() + 1)); + } + } + if (bad) { + result.put(index, trimLine.length()); + } + index += line.length() + 1; + if (quick && !result.isEmpty()) { + break; + } + } + return result; + } + + private static boolean isManaCostLegal(final String manaCost) { + if (manaCost.equals("no cost")) { + return true; + } + if (StringUtils.isEmpty(manaCost) || StringUtils.isWhitespace(manaCost)) { + return false; + } + + for (final String part : StringUtils.split(manaCost, ' ')) { + if (StringUtils.isNumeric(part) || part.equals("X")) { + continue; + } + return isManaCostPart(part); + } + return true; + } + + private static boolean isManaCostPart(final String part) { + if (part.length() == 1) { + return isManaSymbol(part.charAt(0)); + } else if (part.length() == 2) { + if (!(part.startsWith("P") || part.startsWith("2") || isManaSymbol(part.charAt(0)))) { + return false; + } + if ((!isManaSymbol(part.charAt(1))) || part.charAt(0) == part.charAt(1)) { + return false; + } + return true; + } + return false; + } + private static boolean isManaSymbol(final char c) { + return c == 'W' || c == 'U' || c == 'B' || c == 'R' || c == 'G'; + } + + private static boolean isTypeLegal(final String type) { + for (final String t : StringUtils.split(type, ' ')) { + if (!isSingleTypeLegal(t)) { + return false; + } + } + return true; + } + private static boolean isSingleTypeLegal(final String type) { + return CardType.isACardType(type) || CardType.isASupertype(type) || CardType.isASubType(type); + } + + private static List getParams(final String ability, final int offset, final Map errorRegions) { + final String[] parts = StringUtils.split(ability, '|'); + final List params = Lists.newArrayList(); + int currentIndex = offset; + for (final String part : parts) { + final String[] subParts = StringUtils.split(part, '$'); + if (subParts.length > 0) { + params.add(new KeyValuePair(subParts[0], subParts.length > 1 ? subParts[1] : "", currentIndex)); + } else { + errorRegions.put(currentIndex, part.length()); + } + currentIndex += part.length() + 1; + } + + // Check spacing + for (final KeyValuePair param : params) { + if (!param.getKey().startsWith(" ") && param.startIndex() != offset) { + errorRegions.put(param.startIndex() - 1, 2); + } + if (!param.getValue().startsWith(" ")) { + errorRegions.put(param.startIndexValue() - 1, 2); + } + if (!param.getValue().endsWith(" ") && param.endIndex() != offset + ability.length()) { + errorRegions.put(param.endIndex() - 1, 2); + } + } + return params; + } + + private Map getActivatedAbilityErrors(final String ability, final int offset) { + return getAbilityErrors(ability, offset, true); + } + private Map getSubAbilityErrors(final String ability, final int offset) { + return getAbilityErrors(ability, offset, false); + } + private Map getAbilityErrors(final String ability, final int offset, final boolean requireCost) { + final Map result = Maps.newTreeMap(); + final List params = getParams(ability, offset, result); + + // First parameter should be Api declaration + if (!isAbilityApiDeclarerLegal(params.get(0).getKey())) { + result.put(params.get(0).startIndex(), params.get(0).length()); + } + // If present, second parameter should be cost + if (requireCost && !params.get(1).getKey().trim().equals("Cost")) { + result.put(params.get(1).startIndex(), params.get(1).length()); + } + + // Now, check all parameters + for (final KeyValuePair param : params) { + boolean isBadValue = false; + final String trimKey = param.getKey().trim(), trimValue = param.getValue().trim(); + if (isAbilityApiDeclarerLegal(trimKey)) { + if (!isAbilityApiLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("Cost")) { + if (!isCostLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("ValidTgts") || trimKey.equals("ValidCards")) { + if (!isValidLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("Defined")) { + if (!isDefinedLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("TgtPrompt") || trimKey.equals("StackDescription") || trimKey.equals("SpellDescription")) { + if (trimValue.isEmpty()) { + isBadValue = true; + } + } else if (trimKey.equals("SubAbility")) { + if (sVars.contains(trimValue)) { + sVarAbilities.add(trimValue); + } else { + isBadValue = true; + } + } else { + result.put(param.startIndex(), param.keyLength()); + } + if (isBadValue) { + result.put(param.startIndexValue(), param.valueLength()); + } + } + return result; + } + + private Map getTriggerErrors(final String trigger, final int offset) { + final Map result = Maps.newTreeMap(); + final List params = getParams(trigger, offset, result); + + // Check all parameters + for (final KeyValuePair param : params) { + boolean isBadValue = false; + final String trimKey = param.getKey().trim(), trimValue = param.getValue().trim(); + if (trimKey.equals("Mode")) { + if (!isTriggerApiLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("Cost")) { + if (!isCostLegal(trimValue)) { + isBadValue = true; + } + } else if (trimKey.equals("Execute")) { + if (sVars.contains(trimValue)) { + sVarAbilities.add(trimValue); + } else { + isBadValue = true; + } + } else if (trimKey.equals("TriggerDescription")) { + if (trimValue.isEmpty()) { + //isBadValue = true; + } + } else if (trimKey.equals("ValidCard")) { + if (!isValidLegal(trimValue)) { + isBadValue = true; + } + } else { + result.put(param.startIndex(), param.keyLength()); + } + if (isBadValue) { + result.put(param.startIndexValue(), param.valueLength()); + } + } + return result; + } + + private static boolean isCostLegal(final String cost) { + return isManaCostLegal(cost.trim()); // TODO include other costs (tap, sacrifice, etc.) + } + + private static boolean isAbilityApiDeclarerLegal(final String declarer) { + final String tDeclarer = declarer.trim(); + return tDeclarer.equals("AB") || tDeclarer.equals("DB") || tDeclarer.equals("SP"); + } + private static boolean isAbilityApiLegal(final String api) { + try { + return ApiType.smartValueOf(api.trim()) != null; + } catch (final RuntimeException e) { + return false; + } + } + private static boolean isTriggerApiLegal(final String api) { + try { + return TriggerType.smartValueOf(api.trim()) != null; + } catch (final RuntimeException e) { + return false; + } + } + + private static final Predicate startsWith(final String s) { + return new Predicate() { + public boolean apply(final String input) { + return s.startsWith(input); + }}; + } + + /** + * Literal defined strings for cards and spellabilities. + */ + private static final Set DEFINED_CARDS = ImmutableSortedSet.of( + "Self", "OriginalHost", "EffectSource", "Equipped", "Enchanted", + "TopOfLibrary", "BottomOfLibrary", "Targeted", "ThisTargetedCard", + "ParentTarget", "Remembered", "DirectRemembered", + "DelayTriggerRemembered", "FirstRemembered", "Clones", "Imprinted", + "ChosenCard", "SacrificedCards", "Sacrificed", "DiscardedCards", + "Discarded", "ExiledCards", "Exiled", "TappedCards", "Tapped", + "UntappedCards", "Untapped", "Parent", "SourceFirstSpell"); + /** + * Defined starting strings for cards and spellabilities. + */ + private static final Set DEFINED_CARDS_STARTSWITH = ImmutableSortedSet + .of("Triggered", "Replaced", "ThisTurnEntered"); + /** + * Literal defined strings for players. + */ + private static final Set DEFINED_PLAYERS = ImmutableSortedSet.of( + "Targeted", "TargetedPlayer", "ParentTarget", "TargetedController", + "TargetedOwner", "TargetedAndYou", "ParentTargetedController", + "Remembered", "DelayTriggerRemembered", "RememberedOpponents", + "RememberedController", "RememberedOwner", "ImprintedController", + "ImprintedOwner", "EnchantedController", "EnchantedOwner", + "EnchantedPlayer", "AttackingPlayer", "DefendingPlayer", + "ChosenPlayer", "ChosenAndYou", "SourceController", "CardOwner", + "ActivePlayer", "You", "Each", "Opponent"); + /** + * Defined starting strings for players. + */ + private static final Set DEFINED_PLAYERS_STARTSWITH = ImmutableSortedSet + .of("Triggered", "OppNonTriggered", "Replaced"); + + private static boolean isDefinedLegal(final String defined) { + return isDefinedCardOrSaLegal(defined) || isDefinedPlayerLegal(defined); + } + private static boolean isDefinedCardOrSaLegal(final String defined) { + if (defined.startsWith("Valid")) { + return isValidLegal(defined.substring("Valid".length())); + } + if (DEFINED_CARDS.contains(defined)) { + return true; + } + if (Iterables.any(DEFINED_CARDS_STARTSWITH, startsWith(defined))) { + return true; + } + return false; + } + private static boolean isDefinedPlayerLegal(final String defined) { + final boolean non = defined.startsWith("Non"), flipped = defined.startsWith("Flipped"); + if (non || flipped) { + String newDefined = null; + if (non) { + newDefined = defined.substring("Non".length()); + } else if (flipped) { + newDefined = defined.substring("Flipped".length()); + } + return isDefinedPlayerLegal(newDefined); + } + if (DEFINED_PLAYERS.contains(defined)) { + return true; + } + if (Iterables.any(DEFINED_PLAYERS_STARTSWITH, startsWith(defined))) { + return true; + } + return false; + } + + private static final Set VALID_INCLUSIVE = ImmutableSortedSet.of( + "Spell", "Permanent", "Card"); + private static boolean isValidLegal(final String valid) { + String remaining = valid; + if (remaining.charAt(0) == '!') { + remaining = valid.substring(1); + } + final String[] splitDot = remaining.split("\\."); + if (!(VALID_INCLUSIVE.contains(splitDot[0]) || isSingleTypeLegal(splitDot[0]))) { + return false; + } + if (splitDot.length < 2) { + return true; + } + + final String[] splitPlus = StringUtils.split(splitDot[1], '+'); + for (final String excl : splitPlus) { + if (!isValidExclusive(excl)) { + return false; + } + } + return true; + } + + private static final Set VALID_EXCLUSIVE = ImmutableSortedSet.of( + "sameName", "namedCard", "NamedByRememberedPlayer", "Permanent", + "ChosenCard", "nonChosenCard", "White", "Blue", "Black", "Red", + "Green", "nonWhite", "nonBlue", "nonBlack", "nonRed", "nonGreen", + "Colorless", "nonColorless", "Multicolor", "nonMulticolor", + "Monocolor", "nonMonocolor", "ChosenColor", "AllChosenColors", + "AnyChosenColor", "DoubleFaced", "Flip", "YouCtrl", "YouDontCtrl", + "OppCtrl", "ChosenCtrl", "DefenderCtrl", + "DefenderCtrlForRemembered", "DefendingPlayerCtrl", + "EnchantedPlayerCtrl", "EnchantedControllerCtrl", + "RememberedPlayer", "RememberedPlayerCtrl", + "nonRememberedPlayerCtrl", "TargetedPlayerCtrl", + "TargetedControllerCtrl", "ActivePlayerCtrl", + "NonActivePlayerCtrl", "YouOwn", "YouDontOwn", "OppOwn", + "TargetedPlayerOwn", "OwnerDoesntControl", "Other", "Self", + "AttachedBy", "Attached", "NameNotEnchantingEnchantedPlayer", + "NotAttachedTo", "Enchanted", "CanEnchantRemembered", + "CanEnchantSource", "CanBeEnchantedBy", "CanBeEnchantedByTargeted", + "CanBeEnchantedByAllRemembered", "EquippedBy", + "EquippedByTargeted", "EquippedByEnchanted", "FortifiedBy", + "CanBeEquippedBy", "Equipped", "Fortified", "HauntedBy", + "notTributed", "madness", "Paired", "NotPaired", "PairedWith", + "Above", "DirectlyAbove", "TopGraveyardCreature", + "BottomGraveyard", "TopLibrary", "Cloned", "DamagedBy", "Damaged", + "IsTargetingSource", "sharesPermanentTypeWith", + "canProduceSameManaTypeWith", "SecondSpellCastThisTurn", + "ThisTurnCast", "withFlashback", "tapped", "untapped", "faceDown", + "faceUp", "hasLevelUp", "DrawnThisTurn", + "enteredBattlefieldThisTurn", "notEnteredBattlefieldThisTurn", + "firstTurnControlled", "notFirstTurnControlled", + "startedTheTurnUntapped", "attackedOrBlockedSinceYourLastUpkeep", + "blockedOrBeenBlockedSinceYourLastUpkeep", + "dealtDamageToYouThisTurn", "dealtDamageToOppThisTurn", + "controllerWasDealtCombatDamageByThisTurn", + "controllerWasDealtDamageByThisTurn", "wasDealtDamageThisTurn", + "wasDealtDamageByHostThisTurn", "wasDealtDamageByEquipeeThisTurn", + "wasDealtDamageByEnchantedThisTurn", "dealtDamageThisTurn", + "attackedThisTurn", "attackedLastTurn", "blockedThisTurn", + "gotBlockedThisTurn", "notAttackedThisTurn", "notAttackedLastTurn", + "notBlockedThisTurn", "greatestPower", "yardGreatestPower", + "leastPower", "leastToughness", "greatestCMC", + "greatestRememberedCMC", "lowestRememberedCMC", "lowestCMC", + "enchanted", "unenchanted", "enchanting", "equipped", "unequipped", + "equipping", "token", "nonToken", "hasXCost", "suspended", + "delved", "attacking", "attackingYou", "notattacking", + "attackedBySourceThisCombat", "blocking", "blockingSource", + "blockingCreatureYouCtrl", "blockingRemembered", + "sharesBlockingAssignmentWith", "notblocking", "blocked", + "blockedBySource", "blockedThisTurn", "blockedByThisTurn", + "blockedBySourceThisTurn", "blockedSource", + "isBlockedByRemembered", "blockedRemembered", + "blockedByRemembered", "unblocked", "attackersBandedWith", + "kicked", "kicked1", "kicked2", "notkicked", "evoked", + "HasDevoured", "HasNotDevoured", "IsMonstrous", "IsNotMonstrous", + "CostsPhyrexianMana", "IsRemembered", "IsNotRemembered", + "IsImprinted", "IsNotImprinted", "hasActivatedAbilityWithTapCost", + "hasActivatedAbility", "hasManaAbility", + "hasNonManaActivatedAbility", "NoAbilities", "HasCounters", + "wasNotCast", "ChosenType", "IsNotChosenType", "IsCommander"); + private static final Set VALID_EXCLUSIVE_STARTSWITH = ImmutableSortedSet + .of("named", "notnamed", "OwnedBy", "ControlledBy", + "ControllerControls", "AttachedTo", "EnchantedBy", + "NotEnchantedBy", "TopGraveyard", "SharesColorWith", + "MostProminentColor", "notSharesColorWith", + "sharesCreatureTypeWith", "sharesCardTypeWith", + "sharesNameWith", "doesNotShareNameWith", + "sharesControllerWith", "sharesOwnerWith", + "ThisTurnEntered", "ControlledByPlayerInTheDirection", + "sharesTypeWith", "hasKeyword", "with", + "greatestPowerControlledBy", "greatestCMCControlledBy", + "power", "toughness", "cmc", "totalPT", "counters", "non", + "RememberMap", "wasCastFrom", "wasNotCastFrom", "set", + "inZone", "HasSVar"); + + private static boolean isValidExclusive(final String valid) { + if (VALID_EXCLUSIVE.contains(valid)) { + return true; + } + if (Iterables.any(VALID_EXCLUSIVE_STARTSWITH, startsWith(valid))) { + return true; + } + return false; + } + + private static final class KeyValuePair { + private final String key, value; + private final int index; + + private KeyValuePair(final String key, final String value, final int index) { + this.key = key; + this.value = value; + this.index = index; + } + + private String getKey() { + return key; + } + private String getValue() { + return value; + } + private int length() { + return keyLength() + 1 + valueLength(); + } + private int keyLength() { + return key.length(); + } + private int valueLength() { + return value.length(); + } + private int startIndex() { + return index; + } + private int endIndexKey() { + return startIndex() + key.length(); + } + private int startIndexValue() { + return endIndexKey() + 1; + } + private int endIndex() { + return startIndex() + length(); + } + } +} diff --git a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java index 99f514a62a0..45d77eecb01 100644 --- a/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java +++ b/forge-gui/src/main/java/forge/control/FControlGameEventHandler.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import org.apache.commons.lang3.tuple.Pair; @@ -50,24 +51,21 @@ import forge.game.player.PlayerView; import forge.game.zone.PlayerZone; import forge.game.zone.Zone; import forge.game.zone.ZoneType; -import forge.match.IMatchController; -import forge.match.MatchUtil; -import forge.match.input.ButtonUtil; -import forge.match.input.InputBase; +import forge.interfaces.IGuiGame; import forge.model.FModel; import forge.player.PlayerControllerHuman; import forge.properties.ForgePreferences.FPref; import forge.util.Lang; -import forge.util.gui.SGuiChoose; import forge.util.maps.MapOfLists; public class FControlGameEventHandler extends IGameEventVisitor.Base { private final PlayerControllerHuman humanController; - private final HashSet cardsUpdate = new HashSet(); - private final HashSet cardsRefreshDetails = new HashSet(); - private final HashSet livesUpdate = new HashSet(); - private final HashSet manaPoolUpdate = new HashSet(); - private final ArrayList> zonesUpdate = new ArrayList>(); + private final IGuiGame matchController; + private final Set cardsUpdate = new HashSet(); + private final Set cardsRefreshDetails = new HashSet(); + private final Set livesUpdate = new HashSet(); + private final Set manaPoolUpdate = new HashSet(); + private final List> zonesUpdate = new ArrayList>(); private boolean processEventsQueued, needPhaseUpdate, needCombatUpdate, needStackUpdate, needPlayerControlUpdate; private boolean gameOver, gameFinished; @@ -75,6 +73,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { public FControlGameEventHandler(final PlayerControllerHuman humanController0) { humanController = humanController0; + matchController = humanController.getGui(); } private final Runnable processEvents = new Runnable() { @@ -82,68 +81,69 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { public void run() { processEventsQueued = false; - IMatchController controller = MatchUtil.getController(); synchronized (cardsUpdate) { if (!cardsUpdate.isEmpty()) { - MatchUtil.updateCards(cardsUpdate); + for (final CardView c : cardsUpdate) { + matchController.updateSingleCard(c); + } cardsUpdate.clear(); } } synchronized (cardsRefreshDetails) { if (!cardsRefreshDetails.isEmpty()) { - controller.refreshCardDetails(cardsRefreshDetails); + matchController.updateCards(cardsRefreshDetails); cardsRefreshDetails.clear(); } } synchronized (livesUpdate) { if (!livesUpdate.isEmpty()) { - controller.updateLives(livesUpdate); + matchController.updateLives(livesUpdate); livesUpdate.clear(); } } synchronized (manaPoolUpdate) { if (!manaPoolUpdate.isEmpty()) { - controller.updateManaPool(manaPoolUpdate); + matchController.updateManaPool(manaPoolUpdate); manaPoolUpdate.clear(); } } if (turnUpdate != null) { - controller.updateTurn(turnUpdate); + matchController.updateTurn(turnUpdate); turnUpdate = null; } if (needPhaseUpdate) { needPhaseUpdate = false; - controller.updatePhase(); + matchController.updatePhase(); } if (needCombatUpdate) { needCombatUpdate = false; - controller.showCombat(); + matchController.showCombat(); } if (needStackUpdate) { needStackUpdate = false; - controller.updateStack(); + matchController.updateStack(); } if (needPlayerControlUpdate) { needPlayerControlUpdate = false; - controller.updatePlayerControl(); + matchController.updatePlayerControl(); } synchronized (zonesUpdate) { if (!zonesUpdate.isEmpty()) { - controller.updateZones(zonesUpdate); + matchController.updateZones(zonesUpdate); zonesUpdate.clear(); } } if (gameOver) { gameOver = false; - MatchUtil.onGameOver(true); // this will unlock any game threads waiting for inputs to complete + humanController.getInputQueue().onGameOver(true); // this will unlock any game threads waiting for inputs to complete } if (gameFinished) { gameFinished = false; - PlayerView localPlayer = humanController.getLocalPlayerView(); - InputBase.cancelAwaitNextInput(); //ensure "Waiting for opponent..." doesn't appear behind WinLo - controller.showPromptMessage(localPlayer, ""); //clear prompt behind WinLose overlay - ButtonUtil.update(localPlayer, "", "", false, false, false); - controller.finishGame(); + final PlayerView localPlayer = humanController.getLocalPlayerView(); + humanController.cancelAwaitNextInput(); //ensure "Waiting for opponent..." doesn't appear behind WinLo + matchController.showPromptMessage(localPlayer, ""); //clear prompt behind WinLose overlay + matchController.updateButtons(localPlayer, "", "", false, false, false); + matchController.finishGame(); humanController.updateAchievements(); } } @@ -161,13 +161,13 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return null; } - private Void processCard(Card card, HashSet list) { + private Void processCard(Card card, Set list) { synchronized (list) { list.add(card.getView()); } return processEvent(); } - private Void processCards(Collection cards, HashSet list) { + private Void processCards(Collection cards, Set list) { if (cards.isEmpty()) { return null; } synchronized (list) { @@ -177,7 +177,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { } return processEvent(); } - private Void processPlayer(Player player, HashSet list) { + private Void processPlayer(Player player, Set list) { synchronized (list) { list.add(player.getView()); } @@ -233,7 +233,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { options.add(fakeCard); options.add(kv.getValue().getView()); } - SGuiChoose.reveal("These cards were chosen to ante", options); + humanController.getGui().reveal("These cards were chosen to ante", options); return null; } diff --git a/forge-gui/src/main/java/forge/control/FControlGamePlayback.java b/forge-gui/src/main/java/forge/control/FControlGamePlayback.java index 27e7abef558..592418d1593 100644 --- a/forge-gui/src/main/java/forge/control/FControlGamePlayback.java +++ b/forge-gui/src/main/java/forge/control/FControlGamePlayback.java @@ -7,7 +7,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import com.google.common.eventbus.Subscribe; import forge.FThreads; -import forge.GuiBase; import forge.game.Game; import forge.game.card.CardView; import forge.game.event.GameEvent; @@ -20,8 +19,6 @@ import forge.game.event.GameEventSpellAbilityCast; import forge.game.event.GameEventSpellResolved; import forge.game.event.GameEventTurnPhase; import forge.game.event.IGameEventVisitor; -import forge.game.player.PlayerView; -import forge.match.MatchUtil; import forge.match.input.InputPlaybackControl; import forge.player.PlayerControllerHuman; @@ -33,7 +30,15 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { private final PlayerControllerHuman humanController; public FControlGamePlayback(final PlayerControllerHuman humanController0) { - humanController = humanController0; + this.humanController = humanController0; + } + + public final PlayerControllerHuman getController() { + return humanController; + } + + public InputPlaybackControl getInput() { + return inputPlayback; } private Game game; @@ -42,7 +47,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { return game; } - public void setGame(Game game0) { + public void setGame(final Game game0) { game = game0; inputPlayback = new InputPlaybackControl(game, this); } @@ -57,17 +62,17 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { private boolean fasterPlayback = false; - private void pauseForEvent(int delay) { + private void pauseForEvent(final int delay) { try { Thread.sleep(fasterPlayback ? delay / 10 : delay); - } catch (InterruptedException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. + } catch (final InterruptedException e) { + // Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. e.printStackTrace(); } } @Override - public Void visit(GameEventBlockersDeclared event) { + public Void visit(final GameEventBlockersDeclared event) { pauseForEvent(combatDelay); return super.visit(event); } @@ -76,8 +81,9 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventTurnPhase) */ @Override - public Void visit(GameEventTurnPhase ev) { - boolean isUiToStop = MatchUtil.getController().stopAtPhase(PlayerView.get(ev.playerTurn), ev.phase); + public Void visit(final GameEventTurnPhase ev) { + try { + final boolean isUiToStop = !humanController.getGui().isUiSetToSkipPhase(ev.playerTurn.getView(), ev.phase); switch(ev.phase) { case COMBAT_END: @@ -93,6 +99,9 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { } break; } + } catch (Exception e) { + e.printStackTrace(); + } return null; } @@ -101,19 +110,19 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventDuelFinished) */ @Override - public Void visit(GameEventGameFinished event) { + public Void visit(final GameEventGameFinished event) { humanController.getInputQueue().removeInput(inputPlayback); return null; } @Override - public Void visit(GameEventGameStarted event) { + public Void visit(final GameEventGameStarted event) { humanController.getInputQueue().setInput(inputPlayback); return null; } @Override - public Void visit(GameEventLandPlayed event) { + public Void visit(final GameEventLandPlayed event) { pauseForEvent(resolveDelay); return super.visit(event); } @@ -123,7 +132,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { - GuiBase.getInterface().setCard(CardView.get(event.spell.getHostCard())); + humanController.getGui().setCard(CardView.get(event.spell.getHostCard())); } }); pauseForEvent(resolveDelay); @@ -138,7 +147,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { - GuiBase.getInterface().setCard(CardView.get(event.sa.getHostCard())); + humanController.getGui().setCard(CardView.get(event.sa.getHostCard())); } }); pauseForEvent(castDelay); @@ -149,17 +158,17 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { * @see forge.game.event.IGameEventVisitor.Base#visit(forge.game.event.GameEventPlayerPriority) */ @Override - public Void visit(GameEventPlayerPriority event) { + public Void visit(final GameEventPlayerPriority event) { inputPlayback.updateTurnMessage(); if (paused.get()) { try { gameThreadPauser.await(); gameThreadPauser.reset(); } - catch (InterruptedException e) { + catch (final InterruptedException e) { e.printStackTrace(); } - catch (BrokenBarrierException e) { + catch (final BrokenBarrierException e) { e.printStackTrace(); } } @@ -175,17 +184,16 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { private void releaseGameThread() { // just need to run another thread through the barrier... not edt preferrably :) - getGame().getAction().invoke(new Runnable() { @Override public void run() { try { gameThreadPauser.await(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. + } catch (final InterruptedException e) { + // Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. e.printStackTrace(); - } catch (BrokenBarrierException e) { - // TODO Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. + } catch (final BrokenBarrierException e) { + // Auto-generated catch block ignores the exception, but sends it to System.err and probably forge.log. e.printStackTrace(); } } @@ -205,11 +213,7 @@ public class FControlGamePlayback extends IGameEventVisitor.Base { releaseGameThread(); } - /** - * TODO: Write javadoc for this method. - * @param isFast - */ - public void setSpeed(boolean isFast) { + public void setSpeed(final boolean isFast) { fasterPlayback = isFast; } } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/control/WatchLocalGame.java b/forge-gui/src/main/java/forge/control/WatchLocalGame.java index 97b231eb18c..0e16b07d62e 100644 --- a/forge-gui/src/main/java/forge/control/WatchLocalGame.java +++ b/forge-gui/src/main/java/forge/control/WatchLocalGame.java @@ -8,18 +8,19 @@ import java.util.List; import forge.LobbyPlayer; import forge.game.Game; import forge.game.card.CardView; -import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; +import forge.interfaces.IDevModeCheats; +import forge.interfaces.IGuiGame; import forge.match.input.Input; import forge.match.input.InputPlaybackControl; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; - public class WatchLocalGame extends PlayerControllerHuman { - public WatchLocalGame(Game game0, Player p, LobbyPlayer lp) { - super(game0, p, lp); + public WatchLocalGame(final Game game0, final LobbyPlayer lp, final IGuiGame gui) { + super(game0, null, lp); + setGui(gui); } @Override @@ -77,11 +78,14 @@ public class WatchLocalGame extends PlayerControllerHuman { } @Override - public void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) { + public void selectPlayer(final PlayerView player, + final ITriggerEvent triggerEvent) { } @Override - public boolean selectCard(final CardView card, final List otherCardViewsToSelect, final ITriggerEvent triggerEvent) { + public boolean selectCard(final CardView card, + final List otherCardViewsToSelect, + final ITriggerEvent triggerEvent) { return false; } @@ -93,49 +97,13 @@ public class WatchLocalGame extends PlayerControllerHuman { public void alphaStrike() { } - @Override - public Iterable getAutoYields() { - return null; - } - @Override - public boolean shouldAutoYield(final String key) { - return false; - } - @Override - public void setShouldAutoYield(final String key, final boolean autoYield) { - } - @Override - public boolean shouldAlwaysAcceptTrigger(final Integer trigger) { - return false; - } - @Override - public boolean shouldAlwaysDeclineTrigger(final Integer trigger) { - return false; - } - @Override - public boolean shouldAlwaysAskTrigger(final Integer trigger) { - return false; - } - @Override - public void setShouldAlwaysAcceptTrigger(final Integer trigger) { - } - @Override - public void setShouldAlwaysDeclineTrigger(final Integer trigger) { - } - @Override - public void setShouldAlwaysAskTrigger(final Integer trigger) { - } - @Override - public void autoPassCancel() { - } - @Override public boolean canPlayUnlimitedLands() { return false; } @Override - public DevModeCheats cheat() { - return null; + public IDevModeCheats cheat() { + return DevModeCheats.NO_CHEAT; } } diff --git a/forge-gui/src/main/java/forge/events/IUiEventVisitor.java b/forge-gui/src/main/java/forge/events/IUiEventVisitor.java index 88c75008e27..ad66b2ad475 100644 --- a/forge-gui/src/main/java/forge/events/IUiEventVisitor.java +++ b/forge-gui/src/main/java/forge/events/IUiEventVisitor.java @@ -3,4 +3,5 @@ package forge.events; public interface IUiEventVisitor { T visit(UiEventBlockerAssigned event); T visit(UiEventAttackerDeclared event); + T visit(UiEventNextGameDecision event); } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/events/UiEvent.java b/forge-gui/src/main/java/forge/events/UiEvent.java index e7f9b294e7c..29110121681 100644 --- a/forge-gui/src/main/java/forge/events/UiEvent.java +++ b/forge-gui/src/main/java/forge/events/UiEvent.java @@ -1,7 +1,8 @@ package forge.events; +import forge.game.event.Event; -public abstract class UiEvent { +public abstract class UiEvent extends Event { public abstract T visit(IUiEventVisitor visitor); } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java b/forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java index 9a4a17ede00..c1b9317a0fd 100644 --- a/forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java +++ b/forge-gui/src/main/java/forge/events/UiEventAttackerDeclared.java @@ -3,11 +3,10 @@ package forge.events; import forge.game.GameEntityView; import forge.game.card.CardView; - public class UiEventAttackerDeclared extends UiEvent { public final CardView attacker; public final GameEntityView defender; - + public UiEventAttackerDeclared(final CardView card, final GameEntityView currentDefender) { attacker = card; defender = currentDefender; @@ -17,7 +16,7 @@ public class UiEventAttackerDeclared extends UiEvent { public T visit(final IUiEventVisitor visitor) { return visitor.visit(this); } - + /* (non-Javadoc) * @see java.lang.Object#toString() */ diff --git a/forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java b/forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java new file mode 100644 index 00000000000..71e92f416f6 --- /dev/null +++ b/forge-gui/src/main/java/forge/events/UiEventNextGameDecision.java @@ -0,0 +1,28 @@ +package forge.events; + +import forge.match.NextGameDecision; +import forge.player.PlayerControllerHuman; + +public final class UiEventNextGameDecision extends UiEvent { + + private final PlayerControllerHuman controller; + private final NextGameDecision decision; + + public UiEventNextGameDecision(final PlayerControllerHuman controller, final NextGameDecision decision) { + this.controller = controller; + this.decision = decision; + } + + public PlayerControllerHuman getController() { + return controller; + } + public NextGameDecision getDecision() { + return decision; + } + + @Override + public T visit(IUiEventVisitor visitor) { + return visitor.visit(this); + } + +} diff --git a/forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java b/forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java index f5ff43f22c4..ed87fa8f97d 100644 --- a/forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java +++ b/forge-gui/src/main/java/forge/gauntlet/GauntletWinLoseController.java @@ -4,6 +4,7 @@ import java.util.List; import com.google.common.collect.Lists; +import forge.GuiBase; import forge.LobbyPlayer; import forge.assets.FSkinProp; import forge.deck.Deck; @@ -12,13 +13,14 @@ import forge.game.GameView; import forge.game.player.RegisteredPlayer; import forge.interfaces.IButton; import forge.interfaces.IWinLoseView; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; public abstract class GauntletWinLoseController { - private final GameView lastGame; + private HostedMatch hostedMatch = null; private final IWinLoseView view; + private final GameView lastGame; public GauntletWinLoseController(IWinLoseView view0, final GameView game0) { view = view0; @@ -111,17 +113,21 @@ public abstract class GauntletWinLoseController { public final boolean actionOnContinue() { if (lastGame.isMatchOver()) { // To change the AI deck, we have to create a new match. - GauntletData gd = FModel.getGauntletData(); - Deck aiDeck = gd.getDecks().get(gd.getCompleted()); - List players = Lists.newArrayList(); - players.add(new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + final GauntletData gd = FModel.getGauntletData(); + final RegisteredPlayer human = new RegisteredPlayer(gd.getUserDeck()).setPlayer(GamePlayerUtil.getGuiPlayer()); + final Deck aiDeck = gd.getDecks().get(gd.getCompleted()); + final List players = Lists.newArrayList(); + players.add(human); players.add(new RegisteredPlayer(aiDeck).setPlayer(GamePlayerUtil.createAiPlayer())); view.hide(); saveOptions(); - MatchUtil.endCurrentGame(); + if (hostedMatch != null) { + hostedMatch.endCurrentGame(); + } - MatchUtil.startMatch(GameType.Gauntlet, players); + hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(GameType.Gauntlet, null, players, human, GuiBase.getInterface().getNewGuiGame()); return true; } return false; diff --git a/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java b/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java new file mode 100644 index 00000000000..32bd32f9b26 --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/IDevModeCheats.java @@ -0,0 +1,87 @@ +package forge.interfaces; + +public interface IDevModeCheats { + + void setCanPlayUnlimitedLands(boolean canPlayUnlimitedLands0); + + void setViewAllCards(boolean canViewAll); + + void generateMana(); + + void dumpGameState(); + + void setupGameState(); + + void tutorForCard(); + + void addCountersToPermanent(); + + void tapPermanents(); + + void untapPermanents(); + + void setPlayerLife(); + + void winGame(); + + void addCardToHand(); + + void addCardToBattlefield(); + + void riggedPlanarRoll(); + + void planeswalkTo(); + + /** + * Implementation of {@link IDevModeCheats} that disallows cheating by + * performing no action whatsoever when any of its methods is called. + */ + public static final IDevModeCheats NO_CHEAT = new IDevModeCheats() { + @Override + public void winGame() { + } + @Override + public void untapPermanents() { + } + @Override + public void tutorForCard() { + } + @Override + public void tapPermanents() { + } + @Override + public void setupGameState() { + } + @Override + public void setViewAllCards(final boolean canViewAll) { + } + @Override + public void setPlayerLife() { + } + @Override + public void setCanPlayUnlimitedLands(final boolean canPlayUnlimitedLands0) { + } + @Override + public void riggedPlanarRoll() { + } + @Override + public void planeswalkTo() { + } + @Override + public void generateMana() { + } + @Override + public void dumpGameState() { + } + @Override + public void addCountersToPermanent() { + } + @Override + public void addCardToHand() { + } + @Override + public void addCardToBattlefield() { + } + }; + +} \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/interfaces/IGameController.java b/forge-gui/src/main/java/forge/interfaces/IGameController.java new file mode 100644 index 00000000000..29fe616b5b9 --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/IGameController.java @@ -0,0 +1,45 @@ +package forge.interfaces; + +import java.util.List; + +import forge.game.card.CardView; +import forge.game.player.PlayerView; +import forge.game.spellability.SpellAbility; +import forge.match.NextGameDecision; +import forge.util.ITriggerEvent; + +public interface IGameController { + + boolean mayLookAtAllCards(); + + boolean canPlayUnlimitedLands(); + + void concede(); + + void alphaStrike(); + + boolean useMana(byte color); + + void selectButtonOk(); + + void selectButtonCancel(); + + boolean passPriority(); + + boolean passPriorityUntilEndOfTurn(); + + void selectPlayer(PlayerView playerView, ITriggerEvent triggerEvent); + + boolean selectCard(CardView cardView, + List otherCardViewsToSelect, ITriggerEvent triggerEvent); + + void selectAbility(SpellAbility sa); + + boolean tryUndoLastAction(); + + IDevModeCheats cheat(); + + void nextGameDecision(NextGameDecision decision); + + String getActivateDescription(CardView card); +} diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java index a37ec212f7c..af1d1b28890 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java @@ -1,34 +1,28 @@ package forge.interfaces; import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; import java.util.Collection; import java.util.List; import com.google.common.base.Function; -import forge.LobbyPlayer; import forge.assets.FSkinProp; import forge.assets.ISkinImage; -import forge.deck.CardPool; import forge.download.GuiDownloadService; -import forge.game.GameEntity; -import forge.game.GameEntityView; -import forge.game.card.CardView; -import forge.game.player.DelayedReveal; -import forge.game.player.IHasIcon; import forge.item.PaperCard; -import forge.player.PlayerControllerHuman; +import forge.match.HostedMatch; import forge.sound.IAudioClip; import forge.sound.IAudioMusic; import forge.util.Callback; -import forge.util.FCollectionView; public interface IGuiBase { boolean isRunningOnDesktop(); String getCurrentVersion(); String getAssetsDir(); void invokeInEdtLater(Runnable runnable); - void invokeInEdtAndWait(final Runnable proc); + void invokeInEdtAndWait(Runnable proc); boolean isGuiThread(); IGuiTimer createGuiTimer(Runnable proc, int interval); ISkinImage getSkinIcon(FSkinProp skinProp); @@ -38,27 +32,23 @@ public interface IGuiBase { void showBugReportDialog(String title, String text, boolean showExitAppBtn); void showImageDialog(ISkinImage image, String message, String title); int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption); - int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption); String showInputDialog(String message, String title, FSkinProp icon, String initialInput, String[] inputOptions); - List getChoices(final String message, final int min, final int max, final Collection choices, final T selected, final Function display); - List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode); - List sideboard(CardPool sideboard, CardPool main); - GameEntityView chooseSingleEntityForEffect(String title, FCollectionView optionList, DelayedReveal delayedReveal, boolean isOptional, PlayerControllerHuman controller); + List getChoices(String message, int min, int max, Collection choices, T selected, Function display); + List order(String title, String top, int remainingObjectsMin, int remainingObjectsMax, List sourceChoices, List destChoices); String showFileDialog(String title, String defaultDir); File getSaveFile(File defaultFile); void download(GuiDownloadService service, Callback callback); - void showCardList(final String title, final String message, final List list); - boolean showBoxedProduct(final String title, final String message, final List list); - void setCard(CardView card); + void showCardList(String title, String message, List list); + boolean showBoxedProduct(String title, String message, List list); int getAvatarCount(); void copyToClipboard(String text); - void browseToUrl(String url) throws Exception; + void browseToUrl(String url) throws IOException, URISyntaxException; IAudioClip createAudioClip(String filename); IAudioMusic createAudioMusic(String filename); void startAltSoundSystem(String filename, boolean isSynchronized); void clearImageCache(); void showSpellShop(); void showBazaar(); - void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi); + IGuiGame getNewGuiGame(); + HostedMatch hostMatch(); } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiGame.java b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java new file mode 100644 index 00000000000..4c9cc232dd0 --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/IGuiGame.java @@ -0,0 +1,196 @@ +package forge.interfaces; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Pair; + +import com.google.common.base.Function; + +import forge.LobbyPlayer; +import forge.assets.FSkinProp; +import forge.deck.CardPool; +import forge.game.GameEntity; +import forge.game.GameEntityView; +import forge.game.GameView; +import forge.game.card.CardView; +import forge.game.phase.PhaseType; +import forge.game.player.DelayedReveal; +import forge.game.player.IHasIcon; +import forge.game.player.PlayerView; +import forge.game.spellability.SpellAbility; +import forge.game.zone.ZoneType; +import forge.item.PaperCard; +import forge.player.PlayerControllerHuman; +import forge.util.FCollectionView; +import forge.util.ITriggerEvent; + +public interface IGuiGame { + void setGameView(GameView gameView); + void setGameController(PlayerView player, IGameController gameController); + boolean resetForNewGame(); + void openView(FCollectionView myPlayers); + void afterGameEnd(); + void showCombat(); + void showPromptMessage(PlayerView playerView, String message); + boolean stopAtPhase(PlayerView playerTurn, PhaseType phase); + IButton getBtnOK(PlayerView playerView); + IButton getBtnCancel(PlayerView playerView); + void focusButton(IButton button); + void flashIncorrectAction(); + void updatePhase(); + void updateTurn(PlayerView player); + void updatePlayerControl(); + void enableOverlay(); + void disableOverlay(); + void finishGame(); + Object showManaPool(PlayerView player); + void hideManaPool(PlayerView player, Object zoneToRestore); + void updateStack(); + void updateZones(List> zonesToUpdate); + void updateSingleCard(CardView card); + void updateCards(Iterable cards); + void updateManaPool(Iterable manaPoolUpdate); + void updateLives(Iterable livesUpdate); + void setPanelSelection(CardView hostCard); + void hear(LobbyPlayer player, String message); + SpellAbility getAbilityToPlay(List abilities, + ITriggerEvent triggerEvent); + Map assignDamage(CardView attacker, + List blockers, int damage, GameEntityView defender, + boolean overrideOrder); + + void message(String message); + void message(String message, String title); + + void showErrorDialog(String message); + void showErrorDialog(String message, String title); + + boolean showConfirmDialog(String message); + boolean showConfirmDialog(String message, String title); + boolean showConfirmDialog(String message, String title, boolean defaultYes); + boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText); + boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText, boolean defaultYes); + + int showOptionDialog(String message, String title, FSkinProp icon, + String[] options, int defaultOption); + int showCardOptionDialog(CardView card, String message, String title, + FSkinProp icon, String[] options, int defaultOption); + + String showInputDialog(String message, String title); + String showInputDialog(String message, String title, FSkinProp icon); + String showInputDialog(String message, String title, FSkinProp icon, + String initialInput); + String showInputDialog(String message, String title, FSkinProp icon, + String initialInput, String[] inputOptions); + + boolean confirm(CardView c, String question); + boolean confirm(CardView c, String question, boolean defaultChoice); + boolean confirm(CardView c, String question, String[] options); + boolean confirm(CardView c, String question, boolean defaultIsYes, String[] options); + + List getChoices(String message, int min, int max, T[] choices); + List getChoices(String message, int min, int max, + Collection choices); + List getChoices(String message, int min, int max, + Collection choices, T selected, Function display); + + // Get Integer in range + Integer getInteger(String message); + Integer getInteger(String message, int min); + Integer getInteger(String message, int min, int max); + Integer getInteger(String message, int min, int max, boolean sortDesc); + Integer getInteger(String message, int min, int max, int cutoff); + + /** + * Convenience for getChoices(message, 0, 1, choices). + * + * @param + * is automatically inferred. + * @param message + * a {@link java.lang.String} object. + * @param choices + * a T object. + * @return null if choices is missing, empty, or if the users' choices are + * empty; otherwise, returns the first item in the List returned by + * getChoices. + * @see #getChoices(String, int, int, Object...) + */ + T oneOrNone(String message, T[] choices); + T oneOrNone(String message, Collection choices); + + // returned Object will never be null + /** + *

+ * getChoice. + *

+ * + * @param + * a T object. + * @param message + * a {@link java.lang.String} object. + * @param choices + * a T object. + * @return a T object. + */ + T one(String message, T[] choices); + T one(String message, Collection choices); + List noneOrMany(String message, Collection choices); + + void reveal(String message, T item); + void reveal(String message, T[] items); + void reveal(String message, Collection items); + + List many(String title, String topCaption, int min, int max, + List sourceChoices); + List many(String title, String topCaption, int cnt, + List sourceChoices); + List many(String title, String topCaption, int cnt, + List sourceChoices, CardView c); + List many(String title, String topCaption, int min, int max, + List sourceChoices, CardView c); + + List order(String title, String top, List sourceChoices); + List order(String title, String top, List sourceChoices, CardView c); + List order(String title, String top, int remainingObjectsMin, + int remainingObjectsMax, List sourceChoices, + List destChoices, CardView referenceCard, + boolean sideboardingMode); + List insertInList(String title, T newItem, List oldItems); + + List sideboard(CardPool sideboard, CardPool main); + GameEntityView chooseSingleEntityForEffect(String title, + FCollectionView optionList, + DelayedReveal delayedReveal, boolean isOptional, + PlayerControllerHuman controller); + void setCard(CardView card); + void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi); + boolean openZones(Collection zones, Map players); + void restoreOldZones(Map playersToRestoreZonesFor); + void updateButtons(PlayerView owner, boolean okEnabled, + boolean cancelEnabled, boolean focusOk); + void updateButtons(PlayerView owner, String okLabel, String cancelLabel, + boolean okEnabled, boolean cancelEnabled, boolean focusOk); + void setHighlighted(PlayerView pv, boolean b); + void setUsedToPay(CardView card, boolean value); + + void awaitNextInput(); + void cancelAwaitNextInput(); + + boolean isUiSetToSkipPhase(PlayerView playerTurn, PhaseType phase); + void autoPassUntilEndOfTurn(PlayerView player); + boolean mayAutoPass(PlayerView player); + void autoPassCancel(PlayerView player); + void updateAutoPassPrompt(); + boolean shouldAutoYield(String key); + void setShouldAutoYield(String key, boolean autoYield); + boolean shouldAlwaysAcceptTrigger(int trigger); + boolean shouldAlwaysDeclineTrigger(int trigger); + boolean shouldAlwaysAskTrigger(int trigger); + void setShouldAlwaysAcceptTrigger(int trigger); + void setShouldAlwaysDeclineTrigger(int trigger); + void setShouldAlwaysAskTrigger(int trigger); + + void setCurrentPlayer(PlayerView player); +} diff --git a/forge-gui/src/main/java/forge/interfaces/IMayViewCards.java b/forge-gui/src/main/java/forge/interfaces/IMayViewCards.java new file mode 100644 index 00000000000..49e1880dbd4 --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/IMayViewCards.java @@ -0,0 +1,36 @@ +package forge.interfaces; + +import forge.game.card.CardView; + +/** + * Interface that receives requests on whether a {@link Card} can be shown. + */ +public interface IMayViewCards { + + /** + * @param c + * a {@link CardView} + * @return whether {@code c} can be shown. + */ + boolean mayView(CardView c); + + /** + * @param c + * a {@link CardView} + * @return whether the flip side of {@code c} can be shown. + */ + boolean mayFlip(CardView c); + + /** {@link IMayViewCards} that lets you view all cards unconditionally. */ + public static final IMayViewCards ALL = new IMayViewCards() { + @Override + public boolean mayView(final CardView c) { + return true; + } + + @Override + public boolean mayFlip(final CardView c) { + return c.hasAlternateState(); + } + }; +} diff --git a/forge-gui/src/main/java/forge/limited/GauntletMini.java b/forge-gui/src/main/java/forge/limited/GauntletMini.java index adbeb848708..8e7f6daea8e 100644 --- a/forge-gui/src/main/java/forge/limited/GauntletMini.java +++ b/forge-gui/src/main/java/forge/limited/GauntletMini.java @@ -20,10 +20,11 @@ package forge.limited; import java.util.ArrayList; import java.util.List; +import forge.GuiBase; import forge.deck.Deck; import forge.game.GameType; import forge.game.player.RegisteredPlayer; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.util.Aggregates; @@ -38,6 +39,7 @@ import forge.util.Aggregates; * @since 1.2.xx */ public class GauntletMini { + private HostedMatch hostedMatch = null; private int rounds; private Deck humanDeck; private int currentRound; @@ -76,14 +78,17 @@ public class GauntletMini { * Advances the tournament to the next round. */ public void nextRound() { - // System.out.println("Moving from round " + currentRound + " to round " + currentRound + 1 + " of " + rounds); + if (hostedMatch == null) { + return; + } + if (currentRound >= rounds) { currentRound = rounds - 1; return; } currentRound++; - MatchUtil.endCurrentGame(); + hostedMatch.endCurrentGame(); startRound(); } @@ -129,18 +134,19 @@ public class GauntletMini { } resetCurrentRound(); - startRound(); } /** * Starts the tournament. */ private void startRound() { - List starter = new ArrayList(); - starter.add(new RegisteredPlayer(humanDeck).setPlayer(GamePlayerUtil.getGuiPlayer())); + final List starter = new ArrayList(); + final RegisteredPlayer human = new RegisteredPlayer(humanDeck).setPlayer(GamePlayerUtil.getGuiPlayer()); + starter.add(human); starter.add(aiOpponents.get(currentRound - 1).setPlayer(GamePlayerUtil.createAiPlayer())); - MatchUtil.startMatch(gauntletType, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + hostedMatch.startMatch(gauntletType, null, starter, human, GuiBase.getInterface().getNewGuiGame()); } /** diff --git a/forge-gui/src/main/java/forge/match/AbstractGuiGame.java b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java new file mode 100644 index 00000000000..bdbb697f7de --- /dev/null +++ b/forge-gui/src/main/java/forge/match/AbstractGuiGame.java @@ -0,0 +1,648 @@ +package forge.match; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import forge.FThreads; +import forge.assets.FSkinProp; +import forge.card.CardStateName; +import forge.game.GameView; +import forge.game.card.CardView; +import forge.game.card.CardView.CardStateView; +import forge.game.player.PlayerView; +import forge.interfaces.IButton; +import forge.interfaces.IGameController; +import forge.interfaces.IGuiGame; +import forge.interfaces.IMayViewCards; +import forge.util.FCollectionView; + +public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards { + private FCollectionView localPlayers; + private PlayerView currentPlayer = null; + + protected final void setLocalPlayers(final FCollectionView players) { + this.localPlayers = players; + } + public final boolean hasLocalPlayers() { + return localPlayers != null && !localPlayers.isEmpty(); + } + public final FCollectionView getLocalPlayers() { + return localPlayers; + } + public final int getLocalPlayerCount() { + return localPlayers == null ? 0 : localPlayers.size(); + } + public final boolean isLocalPlayer(final PlayerView player) { + return hasLocalPlayers() && localPlayers.contains(player); + } + + public final PlayerView getCurrentPlayer() { + return currentPlayer; + } + @Override + public final void setCurrentPlayer(final PlayerView player) { + this.currentPlayer = player; + updateCurrentPlayer(player); + } + protected abstract void updateCurrentPlayer(PlayerView player); + + private GameView gameView = null; + public final GameView getGameView() { + return gameView; + } + public void setGameView(final GameView gameView) { + this.gameView = gameView; + } + + private final Map gameControllers = Maps.newHashMap(); + public final IGameController getGameController() { + return gameControllers.get(currentPlayer); + } + public final Collection getGameControllers() { + return gameControllers.values(); + } + @Override + public void setGameController(final PlayerView player, final IGameController gameController) { + this.gameControllers.put(player, gameController); + } + + @Override + public void updateCards(final Iterable cards) { + for (final CardView card : cards) { + updateSingleCard(card); + } + } + + public String getCardImageKey(final CardStateView csv) { + if (getCurrentPlayer() == null) { return csv.getImageKey(null); } //if not in game, card can be shown + return csv.getImageKey(getCurrentPlayer()); + } + + @Override + public boolean mayView(final CardView c) { + if (!hasLocalPlayers()) { + return true; //if not in game, card can be shown + } + if (getGameController().mayLookAtAllCards()) { + return true; + } + return Iterables.any(localPlayers, new Predicate() { + @Override public boolean apply(final PlayerView input) { return c.canBeShownTo(input); }; + }); + } + + @Override + public boolean mayFlip(final CardView cv) { + if (cv == null) { return false; } + + CardStateView altState = cv.getAlternateState(); + if (altState == null) { return false; } + + switch (altState.getState()) { + case Original: + CardStateView currentState = cv.getCurrentState(); + if (currentState.getState() == CardStateName.FaceDown) { + return getCurrentPlayer() == null || cv.canFaceDownBeShownTo(getCurrentPlayer()); + } + return true; //original can always be shown if not a face down that can't be shown + case Flipped: + case Transformed: + return true; + default: + return false; + } + } + + private Set highlightedPlayers = Sets.newHashSet(); + @Override + public void setHighlighted(final PlayerView pv, final boolean b) { + if (b) { + highlightedPlayers.add(pv); + } else { + highlightedPlayers.remove(pv); + } + } + + public boolean isHighlighted(PlayerView player) { + return highlightedPlayers.contains(player); + } + + private Set highlightedCards = Sets.newHashSet(); + // used to highlight cards in UI + @Override + public void setUsedToPay(CardView card, boolean value) { + boolean hasChanged = value ? highlightedCards.add(card) : highlightedCards.remove(card); + if (hasChanged) { // since we are in UI thread, may redraw the card right now + updateSingleCard(card); + } + } + + public boolean isUsedToPay(CardView card) { + return highlightedCards.contains(card); + } + + /** Concede game, bring up WinLose UI. */ + public void concede() { + final String userPrompt = + "This will end the current game and you will not be able to resume.\n\n" + + "Concede anyway?"; + if (hasLocalPlayers() && showConfirmDialog(userPrompt, "Concede Game?", "Concede", "Cancel")) { + for (final IGameController c : getGameControllers()) { + // Concede each player on this Gui + c.concede(); + } + /* + if (humanCount == 0) { // no human? then all players surrender! + for (Player p : game.getPlayers()) { + p.concede(); + } + } + else { + getCurrentPlayer().concede(); + } + + Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer(); + boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() instanceof LobbyPlayerHuman; + + if (humanCount > 0 && humanHasPriority) { + game.getAction().checkGameOverCondition(); + } + else { + game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here + onGameOver(false); //release any waiting input, effectively passing priority + } + + if (playbackControl != null) { + playbackControl.onGameStopRequested(); + } + */ + } + } + + @Override + public void updateButtons(final PlayerView owner, final boolean okEnabled, final boolean cancelEnabled, final boolean focusOk) { + updateButtons(owner, "OK", "Cancel", okEnabled, cancelEnabled, focusOk); + } + + @Override + public void updateButtons(final PlayerView owner, final String okLabel, final String cancelLabel, final boolean okEnabled, final boolean cancelEnabled, final boolean focusOk) { + final IButton btnOk = getBtnOK(owner); + final IButton btnCancel = getBtnCancel(owner); + + btnOk.setText(okLabel); + btnCancel.setText(cancelLabel); + btnOk.setEnabled(okEnabled); + btnCancel.setEnabled(cancelEnabled); + if (okEnabled && focusOk) { + focusButton(btnOk); + } else if (cancelEnabled) { + focusButton(btnCancel); + } + } + + // Auto-yield and other input-related code + + private final Set autoPassUntilEndOfTurn = Sets.newHashSet(); + + /** + * Automatically pass priority until reaching the Cleanup phase of the + * current turn. + */ + @Override + public final void autoPassUntilEndOfTurn(final PlayerView player) { + autoPassUntilEndOfTurn.add(player); + updateAutoPassPrompt(); + } + + public final void autoPassCancel(final PlayerView player) { + if (!autoPassUntilEndOfTurn.remove(player)) { + return; + } + + //prevent prompt getting stuck on yielding message while actually waiting for next input opportunity + final PlayerView playerView = getCurrentPlayer(); + showPromptMessage(playerView, ""); + updateButtons(playerView, false, false, false); + awaitNextInput(); + } + + public final boolean mayAutoPass(final PlayerView player) { + return autoPassUntilEndOfTurn.contains(player); + } + + private final Timer awaitNextInputTimer = new Timer(); + private TimerTask awaitNextInputTask; + + @Override + public final void awaitNextInput() { + //delay updating prompt to await next input briefly so buttons don't flicker disabled then enabled + awaitNextInputTask = new TimerTask() { + @Override + public void run() { + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + synchronized (awaitNextInputTimer) { + if (awaitNextInputTask != null) { + updatePromptForAwait(getCurrentPlayer()); + awaitNextInputTask = null; + } + } + } + }); + } + }; + awaitNextInputTimer.schedule(awaitNextInputTask, 250); + } + + protected final void updatePromptForAwait(final PlayerView playerView) { + showPromptMessage(playerView, "Waiting for opponent..."); + updateButtons(playerView, false, false, false); + } + + @Override + public final void cancelAwaitNextInput() { + synchronized (awaitNextInputTimer) { //ensure task doesn't reset awaitNextInputTask during this block + if (awaitNextInputTask != null) { + try { + awaitNextInputTask.cancel(); //cancel timer once next input shown if needed + } catch (final Exception ex) {} //suppress any exception thrown by cancel() + awaitNextInputTask = null; + } + } + } + + @Override + public final void updateAutoPassPrompt() { + if (!autoPassUntilEndOfTurn.isEmpty()) { + //allow user to cancel auto-pass + cancelAwaitNextInput(); //don't overwrite prompt with awaiting opponent + showPromptMessage(getCurrentPlayer(), "Yielding until end of turn.\nYou may cancel this yield to take an action."); + updateButtons(getCurrentPlayer(), false, true, false); + } + } + // End auto-yield/input code + + // Abilities to auto-yield to + private final Set autoYields = Sets.newHashSet(); + public final Iterable getAutoYields() { + return autoYields; + } + @Override + public final boolean shouldAutoYield(final String key) { + return !getDisableAutoYields() && autoYields.contains(key); + } + @Override + public final void setShouldAutoYield(final String key, final boolean autoYield) { + if (autoYield) { + autoYields.add(key); + } + else { + autoYields.remove(key); + } + } + + private boolean disableAutoYields; + public final boolean getDisableAutoYields() { + return disableAutoYields; + } + public final void setDisableAutoYields(final boolean b0) { + disableAutoYields = b0; + } + + // Triggers preliminary choice: ask, decline or play + private final Map triggersAlwaysAccept = Maps.newTreeMap(); + + @Override + public final boolean shouldAlwaysAcceptTrigger(final int trigger) { return Boolean.TRUE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); } + @Override + public final boolean shouldAlwaysDeclineTrigger(final int trigger) { return Boolean.FALSE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); } + @Override + public final boolean shouldAlwaysAskTrigger(final int trigger) { return !triggersAlwaysAccept.containsKey(Integer.valueOf(trigger)); } + + @Override + public final void setShouldAlwaysAcceptTrigger(final int trigger) { triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.TRUE); } + @Override + public final void setShouldAlwaysDeclineTrigger(final int trigger) { triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.FALSE); } + @Override + public final void setShouldAlwaysAskTrigger(final int trigger) { triggersAlwaysAccept.remove(Integer.valueOf(trigger)); } + + // End of Triggers preliminary choice + + // Start of Choice code + + /** + * Convenience for getChoices(message, 0, 1, choices). + * + * @param + * is automatically inferred. + * @param message + * a {@link java.lang.String} object. + * @param choices + * a T object. + * @return null if choices is missing, empty, or if the users' choices are + * empty; otherwise, returns the first item in the List returned by + * getChoices. + * @see #getChoices(String, int, int, Object...) + */ + @Override + public T oneOrNone(final String message, final T[] choices) { + if ((choices == null) || (choices.length == 0)) { + return null; + } + final List choice = getChoices(message, 0, 1, choices); + return choice.isEmpty() ? null : choice.get(0); + } + + @Override + public T oneOrNone(final String message, final Collection choices) { + if ((choices == null) || choices.isEmpty()) { + return null; + } + final List choice = getChoices(message, 0, 1, choices); + return choice.isEmpty() ? null : choice.get(0); + } + + // returned Object will never be null + /** + *

+ * getChoice. + *

+ * + * @param + * a T object. + * @param message + * a {@link java.lang.String} object. + * @param choices + * a T object. + * @return a T object. + */ + @Override + public T one(final String message, final T[] choices) { + final List choice = getChoices(message, 1, 1, choices); + assert choice.size() == 1; + return choice.get(0); + } + + @Override + public T one(final String message, final Collection choices) { + if (choices == null || choices.isEmpty()) { + return null; + } + if (choices.size() == 1) { + return Iterables.getFirst(choices, null); + } + + final List choice = getChoices(message, 1, 1, choices); + assert choice.size() == 1; + return choice.get(0); + } + + @Override + public List noneOrMany(final String message, final Collection choices) { + return getChoices(message, 0, choices.size(), choices, null, null); + } + + @Override + // Nothing to choose here. Code uses this to just reveal one or more items + public void reveal(final String message, final T item) { + List items = new ArrayList(); + items.add(item); + reveal(message, items); + } + @Override + public void reveal(final String message, final T[] items) { + getChoices(message, -1, -1, items); + } + @Override + public void reveal(final String message, final Collection items) { + getChoices(message, -1, -1, items); + } + + // Get Integer in range + @Override + public Integer getInteger(final String message) { + return getInteger(message, 0, Integer.MAX_VALUE, false); + } + @Override + public Integer getInteger(final String message, int min) { + return getInteger(message, min, Integer.MAX_VALUE, false); + } + @Override + public Integer getInteger(final String message, int min, int max) { + return getInteger(message, min, max, false); + } + @Override + public Integer getInteger(final String message, final int min, final int max, final boolean sortDesc) { + if (max <= min) { return min; } //just return min if max <= min + + //force cutting off after 100 numbers at most + if (max == Integer.MAX_VALUE) { + return getInteger(message, min, max, min + 99); + } + int count = max - min + 1; + if (count > 100) { + return getInteger(message, min, max, min + 99); + } + + final Integer[] choices = new Integer[count]; + if (sortDesc) { + for (int i = 0; i < count; i++) { + choices[count - i - 1] = Integer.valueOf(i + min); + } + } + else { + for (int i = 0; i < count; i++) { + choices[i] = Integer.valueOf(i + min); + } + } + return oneOrNone(message, choices); + } + @Override + public Integer getInteger(final String message, final int min, final int max, final int cutoff) { + if (max <= min || cutoff < min) { + return min; //just return min if max <= min or cutoff < min + } + + if (cutoff >= max) { //fallback to regular integer prompt if cutoff at or after max + return getInteger(message, min, max); + } + + final List choices = new ArrayList(); + for (int i = min; i <= cutoff; i++) { + choices.add(Integer.valueOf(i)); + } + choices.add("Other..."); + + final Object choice = oneOrNone(message, choices); + if (choice instanceof Integer || choice == null) { + return (Integer)choice; + } + + //if Other option picked, prompt for number input + String prompt = "Enter a number"; + if (min != Integer.MIN_VALUE) { + if (max != Integer.MAX_VALUE) { + prompt += " between " + min + " and " + max; + } else { + prompt += " greater than or equal to " + min; + } + } else if (max != Integer.MAX_VALUE) { + prompt += " less than or equal to " + max; + } + prompt += ":"; + + while (true) { + final String str = showInputDialog(prompt, message); + if (str == null) { return null; } // that is 'cancel' + + if (StringUtils.isNumeric(str)) { + final Integer val = Integer.valueOf(str); + if (val >= min && val <= max) { + return val; + } + } + } + } + + // returned Object will never be null + @Override + public List getChoices(final String message, final int min, final int max, final T[] choices) { + return getChoices(message, min, max, Arrays.asList(choices), null, null); + } + + @Override + public List getChoices(final String message, final int min, final int max, final Collection choices) { + return getChoices(message, min, max, choices, null, null); + } + + @Override + public List many(final String title, final String topCaption, int cnt, final List sourceChoices) { + return many(title, topCaption, cnt, sourceChoices, null); + } + + @Override + public List many(final String title, final String topCaption, final int cnt, final List sourceChoices, final CardView c) { + return many(title, topCaption, cnt, cnt, sourceChoices, c); + } + + @Override + public List many(final String title, final String topCaption, final int min, final int max, final List sourceChoices) { + return many(title, topCaption, min, max, sourceChoices, null); + } + + @Override + public List many(final String title, final String topCaption, int min, int max, final List sourceChoices, final CardView c) { + final int m2 = min >= 0 ? sourceChoices.size() - min : -1; + final int m1 = max >= 0 ? sourceChoices.size() - max : -1; + return order(title, topCaption, m1, m2, sourceChoices, null, c, false); + } + + @Override + public List order(final String title, final String top, final List sourceChoices) { + return order(title, top, sourceChoices, null); + } + + @Override + public List order(final String title, final String top, final List sourceChoices, final CardView c) { + return order(title, top, 0, 0, sourceChoices, null, c, false); + } + + /** + * Ask the user to insert an object into a list of other objects. The + * current implementation requires the user to cancel in order to get the + * new item to be the first item in the resulting list. + * + * @param title the dialog title. + * @param newItem the object to insert. + * @param oldItems the list of objects. + * @return A shallow copy of the list of objects, with newItem inserted. + */ + @Override + public List insertInList(final String title, final T newItem, final List oldItems) { + final T placeAfter = oneOrNone(title, oldItems); + final int indexAfter = (placeAfter == null ? 0 : oldItems.indexOf(placeAfter) + 1); + final List result = Lists.newArrayListWithCapacity(oldItems.size() + 1); + result.addAll(oldItems); + result.add(indexAfter, newItem); + return result; + } + + @Override + public String showInputDialog(final String message, final String title) { + return showInputDialog(message, title, null, "", null); + } + + + @Override + public String showInputDialog(final String message, final String title, final FSkinProp icon) { + return showInputDialog(message, title, icon, "", null); + } + + + @Override + public String showInputDialog(final String message, final String title, final FSkinProp icon, final String initialInput) { + return showInputDialog(message, title, icon, initialInput, null); + } + + @Override + public boolean confirm(final CardView c, final String question) { + return confirm(c, question, true, null); + } + @Override + public boolean confirm(final CardView c, final String question, final boolean defaultChoice) { + return confirm(c, question, defaultChoice, null); + } + @Override + public boolean confirm(final CardView c, final String question, String[] options) { + return confirm(c, question, true, options); + } + + @Override + public void message(final String message) { + message(message, "Forge"); + } + + @Override + public void showErrorDialog(final String message) { + showErrorDialog(message, "Error"); + } + + @Override + public boolean showConfirmDialog(final String message) { + return showConfirmDialog(message, null); + } + + @Override + public boolean showConfirmDialog(final String message, final String title) { + return showConfirmDialog(message, title, true); + } + + @Override + public boolean showConfirmDialog(final String message, final String title, + final boolean defaultYes) { + return showConfirmDialog(message, title, "Yes", "No"); + } + + @Override + public boolean showConfirmDialog(final String message, final String title, + final String yesButtonText, final String noButtonText) { + return showConfirmDialog(message, title, yesButtonText, noButtonText, true); + } + + // End of Choice code +} diff --git a/forge-gui/src/main/java/forge/match/HostedMatch.java b/forge-gui/src/main/java/forge/match/HostedMatch.java new file mode 100644 index 00000000000..37e6cddb25e --- /dev/null +++ b/forge-gui/src/main/java/forge/match/HostedMatch.java @@ -0,0 +1,358 @@ +package forge.match; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.eventbus.Subscribe; + +import forge.FThreads; +import forge.GuiBase; +import forge.LobbyPlayer; +import forge.control.FControlGameEventHandler; +import forge.control.FControlGamePlayback; +import forge.control.WatchLocalGame; +import forge.events.IUiEventVisitor; +import forge.events.UiEvent; +import forge.events.UiEventAttackerDeclared; +import forge.events.UiEventBlockerAssigned; +import forge.events.UiEventNextGameDecision; +import forge.game.Game; +import forge.game.GameRules; +import forge.game.GameType; +import forge.game.GameView; +import forge.game.Match; +import forge.game.player.Player; +import forge.game.player.PlayerView; +import forge.game.player.RegisteredPlayer; +import forge.interfaces.IGuiGame; +import forge.model.FModel; +import forge.player.GamePlayerUtil; +import forge.player.LobbyPlayerHuman; +import forge.player.PlayerControllerHuman; +import forge.properties.ForgePreferences; +import forge.properties.ForgePreferences.FPref; +import forge.quest.QuestController; +import forge.sound.MusicPlaylist; +import forge.sound.SoundSystem; +import forge.util.CollectionSuppliers; +import forge.util.FCollection; +import forge.util.GuiDisplayUtil; +import forge.util.NameGenerator; +import forge.util.maps.HashMapOfLists; +import forge.util.maps.MapOfLists; + +public class HostedMatch { + private Match match; + private Game game; + private String title; + private final List humanControllers = Lists.newArrayList(); + private Map guis; + private int humanCount; + private FControlGamePlayback playbackControl = null; + private final MatchUiEventVisitor visitor = new MatchUiEventVisitor(); + private final Map nextGameDecisions = Maps.newHashMap(); + + public HostedMatch() { + } + + private static GameRules getDefaultRules(final GameType gameType) { + final GameRules gameRules = new GameRules(gameType); + gameRules.setPlayForAnte(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE)); + gameRules.setMatchAnteRarity(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY)); + gameRules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); + gameRules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); + return gameRules; + } + + public void startMatch(final GameType gameType, final Set appliedVariants, final List players, final RegisteredPlayer human, final IGuiGame gui) { + startMatch(getDefaultRules(gameType), appliedVariants, players, human, gui); + } + public void startMatch(final GameType gameType, final Set appliedVariants, final List players, final Map guis) { + startMatch(getDefaultRules(gameType), appliedVariants, players, guis); + } + public void startMatch(final GameRules gameRules, final Set appliedVariants, final List players, final RegisteredPlayer human, final IGuiGame gui) { + startMatch(gameRules, appliedVariants, players, human == null || gui == null ? null : ImmutableMap.of(human, gui)); + } + public void startMatch(final GameRules gameRules, final Set appliedVariants, final List players, final Map guis) { + if (gameRules == null || gameRules.getGameType() == null || players == null || players.isEmpty()) { + throw new IllegalArgumentException(); + } + + this.guis = guis == null ? ImmutableMap.of() : guis; + final boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); + for (final RegisteredPlayer rp : players) { + rp.setRandomFoil(useRandomFoil); + } + + if (appliedVariants != null && !appliedVariants.isEmpty()) { + gameRules.setAppliedVariants(appliedVariants); + } + + if (players.size() == 2) { + title = String.format("%s vs %s", players.get(0).getPlayer().getName(), players.get(1).getPlayer().getName()); + } else { + title = String.format("Multiplayer Game (%d players)", players.size()); + } + this.match = new Match(gameRules, players, title); + startGame(); + } + + public void continueMatch() { + endCurrentGame(); + startGame(); + } + + public void restartMatch() { + endCurrentGame(); + this.match = new Match(match.getRules(), match.getPlayers(), this.title); + startGame(); + } + + public void startGame() { + nextGameDecisions.clear(); + SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MATCH); + + game = match.createGame(); + + if (game.getRules().getGameType() == GameType.Quest) { + QuestController qc = FModel.getQuest(); + // Reset new list when the Match round starts, not when each game starts + if (game.getMatch().getPlayedGames().isEmpty()) { + qc.getCards().resetNewList(); + } + game.subscribeToEvents(qc); // this one listens to player's mulligans ATM + } + + game.subscribeToEvents(SoundSystem.instance); + game.subscribeToEvents(visitor); + + final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(","); + + // Instantiate all required field slots (user at 0) + final List sortedPlayers = Lists.newArrayList(game.getRegisteredPlayers()); + Collections.sort(sortedPlayers, new Comparator() { + @Override + public int compare(final Player p1, final Player p2) { + final int v1 = p1.getController() instanceof PlayerControllerHuman ? 0 : 1; + final int v2 = p2.getController() instanceof PlayerControllerHuman ? 0 : 1; + return Integer.compare(v1, v2); + } + }); + + final GameView gameView = getGameView(); + + int i = 0; + int avatarIndex = 0; + humanCount = 0; + final MapOfLists playersPerGui = new HashMapOfLists(CollectionSuppliers.arrayLists()); + for (final Player p : sortedPlayers) { + if (i < indices.length) { + avatarIndex = Integer.parseInt(indices[i]); + i++; + } + p.getLobbyPlayer().setAvatarIndex(avatarIndex); + p.updateAvatar(); + + if (p.getController() instanceof PlayerControllerHuman) { + final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController(); + final IGuiGame gui = guis.get(p.getRegisteredPlayer()); + humanController.setGui(gui); + gui.setGameView(gameView); + gui.setGameController(p.getView(), humanController); + + game.subscribeToEvents(new FControlGameEventHandler(humanController)); + playersPerGui.add(gui, p.getView()); + humanControllers.add(humanController); + humanCount++; + } + } + for (final Entry> e : playersPerGui.entrySet()) { + e.getKey().openView(new FCollection(e.getValue())); + } + + if (humanCount == 0) { //watch game but do not participate + final IGuiGame gui = GuiBase.getInterface().getNewGuiGame(); + gui.setGameView(gameView); + + final PlayerControllerHuman humanController = new WatchLocalGame(game, new LobbyPlayerHuman("Spectator"), gui); + game.subscribeToEvents(new FControlGameEventHandler(humanController)); + humanControllers.add(humanController); + gui.setGameController(null, humanController); + + gui.openView(null); + } else if (humanCount == sortedPlayers.size()) { + //if there are no AI's, allow all players to see all cards (hotseat mode). + for (final PlayerControllerHuman humanController : humanControllers) { + humanController.setMayLookAtAllCards(true); + } + } + + //prompt user for player one name if needed + if (StringUtils.isBlank(FModel.getPreferences().getPref(FPref.PLAYER_NAME)) && humanCount == 1) { + GamePlayerUtil.setPlayerName(); + } + + //ensure opponents set properly + for (final Player p : sortedPlayers) { + p.updateOpponentsForView(); + } + + // It's important to run match in a different thread to allow GUI inputs to be invoked from inside game. + // Game is set on pause while gui player takes decisions + game.getAction().invoke(new Runnable() { + @Override public void run() { + if (humanCount == 0) { + // Create FControlGamePlayback in game thread to allow pausing + playbackControl = new FControlGamePlayback(humanControllers.get(0)); + playbackControl.setGame(game); + game.subscribeToEvents(playbackControl); + } + + // Actually start the game! + match.startGame(game); + + // After game is over... + if (humanCount == 0) { + // ... if no human players, let AI decide next game + addNextGameDecision(null, match.isMatchOver() ? NextGameDecision.QUIT : NextGameDecision.CONTINUE); + } + } + }); + + } + + public void registerSpectator(final LobbyPlayer lobbyPlayer, final IGuiGame gui) { + final PlayerControllerHuman humanController = new WatchLocalGame(game, null, gui); + gui.setGameController(null, humanController); + gui.openView(null); + + game.subscribeToEvents(new FControlGameEventHandler(humanController)); + humanControllers.add(humanController); + } + + public Game getGame() { + return game; + } + public GameView getGameView() { + return game == null ? null : game.getView(); + } + + public void endCurrentGame() { + if (game == null) { return; } + + game = null; + + for (final PlayerControllerHuman humanController : humanControllers) { + humanController.getGui().afterGameEnd(); + } + humanControllers.clear(); + } + + public void pause() { + final ForgePreferences prefs = FModel.getPreferences(); + if (prefs == null) { return; } //do nothing if prefs haven't been initialized yet + + SoundSystem.instance.pause(); + //pause playback if needed + if (prefs.getPrefBoolean(FPref.UI_PAUSE_WHILE_MINIMIZED) && playbackControl != null) { + playbackControl.getInput().pause(); + } + } + + public void resume() { + SoundSystem.instance.resume(); + } + + /** Returns a random name from the supplied list. */ + public static String getRandomName() { + final String playerName = GuiDisplayUtil.getPlayerName(); + final String aiName = NameGenerator.getRandomName("Any", "Generic", playerName); + return aiName; + } + + private final class MatchUiEventVisitor implements IUiEventVisitor { + @Override + public Void visit(final UiEventBlockerAssigned event) { + for (final PlayerControllerHuman humanController : humanControllers) { + humanController.getGui().updateSingleCard(event.blocker); + final PlayerView p = humanController.getPlayer().getView(); + if (event.attackerBeingBlocked.getController().equals(p)) { + humanController.getGui().autoPassCancel(p); + } + } + return null; + } + + @Override + public Void visit(final UiEventAttackerDeclared event) { + for (final PlayerControllerHuman humanController : humanControllers) { + humanController.getGui().updateSingleCard(event.attacker); + } + return null; + } + + @Override + public Void visit(final UiEventNextGameDecision event) { + addNextGameDecision(event.getController(), event.getDecision()); + return null; + } + + @Subscribe + public void receiveEvent(final UiEvent evt) { + evt.visit(this); + } + } + + private void addNextGameDecision(final PlayerControllerHuman controller, final NextGameDecision decision) { + if (decision == NextGameDecision.QUIT) { + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override public void run() { + endCurrentGame(); + } + }); + return; // if any player chooses quit, quit the match + } + + nextGameDecisions.put(controller, decision); + if (nextGameDecisions.size() < humanControllers.size()) { + return; + } + + int newMatch = 0, continueMatch = 0; + for (final NextGameDecision dec : nextGameDecisions.values()) { + switch (dec) { + case CONTINUE: + continueMatch++; + break; + case NEW: + newMatch++; + break; + default: + } + } + + if (continueMatch >= newMatch) { + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override public void run() { + continueMatch(); + } + }); + } else { + FThreads.invokeInEdtNowOrLater(new Runnable() { + @Override public void run() { + restartMatch(); + } + }); + } + } +} diff --git a/forge-gui/src/main/java/forge/match/IMatchController.java b/forge-gui/src/main/java/forge/match/IMatchController.java deleted file mode 100644 index 71c16822b55..00000000000 --- a/forge-gui/src/main/java/forge/match/IMatchController.java +++ /dev/null @@ -1,54 +0,0 @@ -package forge.match; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.tuple.Pair; - -import forge.LobbyPlayer; -import forge.game.GameEntityView; -import forge.game.Match; -import forge.game.card.CardView; -import forge.game.phase.PhaseType; -import forge.game.player.Player; -import forge.game.player.PlayerView; -import forge.game.spellability.SpellAbility; -import forge.game.zone.ZoneType; -import forge.interfaces.IButton; -import forge.util.ITriggerEvent; - -public interface IMatchController { - void startNewMatch(Match match); - boolean resetForNewGame(); - boolean hotSeatMode(); - void openView(List sortedPlayers); - void afterGameEnd(); - void showCombat(); - void showPromptMessage(PlayerView playerView, String message); - boolean stopAtPhase(PlayerView playerTurn, PhaseType phase); - IButton getBtnOK(PlayerView playerView); - IButton getBtnCancel(PlayerView playerView); - void focusButton(IButton button); - void flashIncorrectAction(); - void updatePhase(); - void updateTurn(PlayerView player); - void updatePlayerControl(); - void enableOverlay(); - void disableOverlay(); - void finishGame(); - Object showManaPool(PlayerView player); - void hideManaPool(PlayerView player, Object zoneToRestore); - boolean openZones(Collection zones, Map players); - void restoreOldZones(Map playersToRestoreZonesFor); - void updateStack(); - void updateZones(List> zonesToUpdate); - void updateSingleCard(CardView card); - void refreshCardDetails(Iterable cards); - void updateManaPool(Iterable manaPoolUpdate); - void updateLives(Iterable livesUpdate); - void setPanelSelection(CardView hostCard); - void hear(LobbyPlayer player, String message); - SpellAbility getAbilityToPlay(List abilities, ITriggerEvent triggerEvent); - Map assignDamage(CardView attacker, List blockers, int damage, GameEntityView defender, boolean overrideOrder); -} diff --git a/forge-gui/src/main/java/forge/match/MatchUtil.java b/forge-gui/src/main/java/forge/match/MatchUtil.java deleted file mode 100644 index 9da5bffd756..00000000000 --- a/forge-gui/src/main/java/forge/match/MatchUtil.java +++ /dev/null @@ -1,459 +0,0 @@ -package forge.match; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; - -import com.google.common.eventbus.EventBus; -import com.google.common.eventbus.Subscribe; - -import forge.LobbyPlayer; -import forge.ai.LobbyPlayerAi; -import forge.card.CardStateName; -import forge.control.FControlGameEventHandler; -import forge.control.FControlGamePlayback; -import forge.control.WatchLocalGame; -import forge.events.IUiEventVisitor; -import forge.events.UiEvent; -import forge.events.UiEventAttackerDeclared; -import forge.events.UiEventBlockerAssigned; -import forge.game.Game; -import forge.game.GameEntityView; -import forge.game.GameRules; -import forge.game.GameType; -import forge.game.GameView; -import forge.game.Match; -import forge.game.card.CardView; -import forge.game.card.CardView.CardStateView; -import forge.game.player.Player; -import forge.game.player.PlayerView; -import forge.game.player.RegisteredPlayer; -import forge.match.input.InputPlaybackControl; -import forge.match.input.InputQueue; -import forge.model.FModel; -import forge.player.GamePlayerUtil; -import forge.player.LobbyPlayerHuman; -import forge.player.PlayerControllerHuman; -import forge.properties.ForgePreferences; -import forge.properties.ForgePreferences.FPref; -import forge.quest.QuestController; -import forge.sound.MusicPlaylist; -import forge.sound.SoundSystem; -import forge.util.GuiDisplayUtil; -import forge.util.NameGenerator; -import forge.util.gui.SOptionPane; - -public class MatchUtil { - private static IMatchController controller; - private static Game game; - private static Player currentPlayer; - private static final List humanControllers = new ArrayList(); - private static int humanCount; - private static final EventBus uiEvents; - private static FControlGamePlayback playbackControl; - private static final MatchUiEventVisitor visitor = new MatchUiEventVisitor(); - - static { - uiEvents = new EventBus("ui events"); - uiEvents.register(SoundSystem.instance); - uiEvents.register(visitor); - } - - public static IMatchController getController() { - return controller; - } - public static void setController(IMatchController controller0) { - controller = controller0; - } - - public static void startMatch(GameType gameType, List players) { - startMatch(gameType, null, players); - } - public static void startMatch(GameType gameType, Set appliedVariants, List players) { - boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); - for (RegisteredPlayer rp : players) { - rp.setRandomFoil(useRandomFoil); - } - - GameRules rules = new GameRules(gameType); - if (appliedVariants != null && !appliedVariants.isEmpty()) { - rules.setAppliedVariants(appliedVariants); - } - rules.setPlayForAnte(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE)); - rules.setMatchAnteRarity(FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY)); - rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); - rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); - - controller.startNewMatch(new Match(rules, players)); - } - - public static void continueMatch() { - final Match match = game.getMatch(); - endCurrentGame(); - startGame(match); - } - - public static void restartMatch() { - final Match match = game.getMatch(); - endCurrentGame(); - match.clearGamesPlayed(); - startGame(match); - } - - public static void startGame(final Match match) { - if (!controller.resetForNewGame()) { return; } - - SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MATCH); - - game = match.createGame(); - - if (game.getRules().getGameType() == GameType.Quest) { - QuestController qc = FModel.getQuest(); - // Reset new list when the Match round starts, not when each game starts - if (game.getMatch().getPlayedGames().isEmpty()) { - qc.getCards().resetNewList(); - } - game.subscribeToEvents(qc); // this one listens to player's mulligans ATM - } - - game.subscribeToEvents(SoundSystem.instance); - - final String[] indices = FModel.getPreferences().getPref(FPref.UI_AVATARS).split(","); - - // Instantiate all required field slots (user at 0) - final List sortedPlayers = new ArrayList(game.getRegisteredPlayers()); - Collections.sort(sortedPlayers, new Comparator() { - @Override - public int compare(Player p1, Player p2) { - int v1 = p1.getController() instanceof PlayerControllerHuman ? 0 : 1; - int v2 = p2.getController() instanceof PlayerControllerHuman ? 0 : 1; - return Integer.compare(v1, v2); - } - }); - - int i = 0; - int avatarIndex = 0; - humanCount = 0; - for (Player p : sortedPlayers) { - if (i < indices.length) { - avatarIndex = Integer.parseInt(indices[i]); - i++; - } - p.getLobbyPlayer().setAvatarIndex(avatarIndex); - p.updateAvatar(); - - if (p.getController() instanceof PlayerControllerHuman) { - final PlayerControllerHuman humanController = (PlayerControllerHuman) p.getController(); - if (humanCount == 0) { - currentPlayer = p; - game.subscribeToEvents(new FControlGameEventHandler(humanController)); - } - humanControllers.add(humanController); - humanCount++; - } - } - - if (humanCount == 0) { //watch game but do not participate - currentPlayer = sortedPlayers.get(0); - PlayerControllerHuman humanController = new WatchLocalGame(game, currentPlayer, currentPlayer.getLobbyPlayer()); - game.subscribeToEvents(new FControlGameEventHandler(humanController)); - humanControllers.add(humanController); - } - else if (humanCount == sortedPlayers.size() && controller.hotSeatMode()) { - //if there are no AI's, allow all players to see all cards (hotseat mode). - for (Player p : sortedPlayers) { - ((PlayerControllerHuman) p.getController()).setMayLookAtAllCards(true); - } - } - - controller.openView(sortedPlayers); - - if (humanCount == 0) { - playbackControl = new FControlGamePlayback(getHumanController()); - playbackControl.setGame(game); - game.subscribeToEvents(playbackControl); - } - - //ensure opponents set properly - for (Player p : sortedPlayers) { - p.updateOpponentsForView(); - } - - // It's important to run match in a different thread to allow GUI inputs to be invoked from inside game. - // Game is set on pause while gui player takes decisions - game.getAction().invoke(new Runnable() { - @Override - public void run() { - //prompt user for player one name if needed - if (StringUtils.isBlank(FModel.getPreferences().getPref(FPref.PLAYER_NAME))) { - boolean isPlayerOneHuman = match.getPlayers().get(0).getPlayer() instanceof LobbyPlayerHuman; - boolean isPlayerTwoComputer = match.getPlayers().get(1).getPlayer() instanceof LobbyPlayerAi; - if (isPlayerOneHuman && isPlayerTwoComputer) { - GamePlayerUtil.setPlayerName(); - } - } - match.startGame(game); - } - }); - } - - public static Game getGame() { - return game; - } - public static GameView getGameView() { - return game == null ? null : game.getView(); - } - - public static PlayerControllerHuman getHumanController() { - return getHumanController(currentPlayer); - } - public static PlayerControllerHuman getHumanController(Player player) { - switch (humanControllers.size()) { - case 1: - return humanControllers.get(0); - case 0: - return null; - default: - return humanControllers.get(player.getId()); - } - } - - public static int getHumanCount() { - return humanCount; - } - - public static PlayerControllerHuman getOtherHumanController() { - //return other game view besides current game view - if (humanControllers.size() < 2) { - return null; - } - PlayerControllerHuman humanController = getHumanController(); - if (humanController == humanControllers.get(0)) { - return humanControllers.get(1); - } - return humanControllers.get(0); - } - - public static InputQueue getInputQueue() { - PlayerControllerHuman humanController = getHumanController(); - if (humanController != null) { - return humanController.getInputQueue(); - } - return null; - } - - public static void endCurrentTurn() { - getHumanController().passPriorityUntilEndOfTurn(); - } - - public static Player getCurrentPlayer() { - return currentPlayer; - } - public static void setCurrentPlayer(Player currentPlayer0) { - if (currentPlayer == currentPlayer0) { return; } - currentPlayer = currentPlayer0; - if (humanControllers.size() > 1) { - //TODO: ensure card views updated when current player changes to account for changes in card visibility - } - } - - public static void alphaStrike() { - getHumanController().alphaStrike(); - } - - public static Map getDamageToAssign(final CardView attacker, final List blockers, final int damage, final GameEntityView defender, final boolean overrideOrder) { - if (damage <= 0) { - return new HashMap(); - } - - // If the first blocker can absorb all of the damage, don't show the Assign Damage dialog - CardView firstBlocker = blockers.get(0); - if (!overrideOrder && !attacker.getCurrentState().hasDeathtouch() && firstBlocker.getLethalDamage() >= damage) { - Map res = new HashMap(); - res.put(firstBlocker, damage); - return res; - } - - return controller.assignDamage(attacker, blockers, damage, defender, overrideOrder); - } - - public static String getCardImageKey(CardStateView csv) { - if (currentPlayer == null) { return csv.getImageKey(null); } //if not in game, card can be shown - return csv.getImageKey(currentPlayer.getView()); - } - - public static boolean canCardBeShown(CardView cv) { - if (currentPlayer == null) { return true; } //if not in game, card can be shown - if (currentPlayer.getController() instanceof PlayerControllerHuman && ((PlayerControllerHuman) currentPlayer.getController()).mayLookAtAllCards()) { - return true; - } - return cv.canBeShownTo(currentPlayer.getView()); - } - - public static boolean canCardBeFlipped(CardView cv) { - if (cv == null) { return false; } - - CardStateView altState = cv.getAlternateState(); - if (altState == null) { return false; } - - switch (altState.getState()) { - case Original: - CardStateView currentState = cv.getCurrentState(); - if (currentState.getState() == CardStateName.FaceDown) { - return currentPlayer == null || cv.canFaceDownBeShownTo(currentPlayer.getView()); - } - return true; //original can always be shown if not a face down that can't be shown - case Flipped: - case Transformed: - return true; - default: - return false; - } - } - - private static Set highlightedPlayers = new HashSet(); - public static void setHighlighted(PlayerView pv, boolean b) { - if (b) { - highlightedPlayers.add(pv); - } - else { - highlightedPlayers.remove(pv); - } - } - - public static boolean isHighlighted(PlayerView player) { - return highlightedPlayers.contains(player); - } - - private static Set highlightedCards = new HashSet(); - // used to highlight cards in UI - public static void setUsedToPay(CardView card, boolean value) { - boolean hasChanged = value ? highlightedCards.add(card) : highlightedCards.remove(card); - if (hasChanged) { // since we are in UI thread, may redraw the card right now - controller.updateSingleCard(card); - } - } - - public static boolean isUsedToPay(CardView card) { - return highlightedCards.contains(card); - } - - public static void updateCards(Iterable cardsToUpdate) { - for (CardView c : cardsToUpdate) { - controller.updateSingleCard(c); - } - } - - /** Concede game, bring up WinLose UI. */ - public static void concede() { - String userPrompt = - "This will end the current game and you will not be able to resume.\n\n" + - "Concede anyway?"; - if (SOptionPane.showConfirmDialog(userPrompt, "Concede Game?", "Concede", "Cancel")) { - if (humanCount == 0) { // no human? then all players surrender! - for (Player p : game.getPlayers()) { - p.concede(); - } - } - else { - getCurrentPlayer().concede(); - } - - Player priorityPlayer = game.getPhaseHandler().getPriorityPlayer(); - boolean humanHasPriority = priorityPlayer == null || priorityPlayer.getLobbyPlayer() instanceof LobbyPlayerHuman; - - if (humanCount > 0 && humanHasPriority) { - game.getAction().checkGameOverCondition(); - } - else { - game.isGameOver(); // this is synchronized method - it's used to make Game-0 thread see changes made here - onGameOver(false); //release any waiting input, effectively passing priority - } - - if (playbackControl != null) { - playbackControl.onGameStopRequested(); - } - } - } - - public static void onGameOver(boolean releaseAllInputs) { - for (PlayerControllerHuman humanController : humanControllers) { - humanController.getInputQueue().onGameOver(releaseAllInputs); - } - } - - public static void endCurrentGame() { - if (game == null) { return; } - - game = null; - currentPlayer = null; - humanControllers.clear(); - - controller.afterGameEnd(); - } - - public static void pause() { - ForgePreferences prefs = FModel.getPreferences(); - if (prefs == null) { return; } //do nothing if prefs haven't been initialized yet - - SoundSystem.instance.pause(); - //pause playback if needed - if (prefs.getPrefBoolean(FPref.UI_PAUSE_WHILE_MINIMIZED)) { - InputQueue inputQueue = getInputQueue(); - if (inputQueue != null && inputQueue.getInput() instanceof InputPlaybackControl) { - ((InputPlaybackControl) inputQueue.getInput()).pause(); - } - } - } - - public static void resume() { - SoundSystem.instance.resume(); - } - - private final static boolean LOG_UIEVENTS = false; - - // UI-related events should arrive here - public static void fireEvent(UiEvent uiEvent) { - if (LOG_UIEVENTS) { - //System.out.println("UI: " + uiEvent.toString() + " \t\t " + FThreads.debugGetStackTraceItem(4, true)); - } - uiEvents.post(uiEvent); - } - - /** Returns a random name from the supplied list. */ - public static String getRandomName() { - String playerName = GuiDisplayUtil.getPlayerName(); - String aiName = NameGenerator.getRandomName("Any", "Generic", playerName); - return aiName; - } - - public final static LobbyPlayer getGuiPlayer() { - return GamePlayerUtil.getGuiPlayer(); - } - - private static class MatchUiEventVisitor implements IUiEventVisitor { - @Override - public Void visit(UiEventBlockerAssigned event) { - controller.updateSingleCard(event.blocker); - return null; - } - - @Override - public Void visit(UiEventAttackerDeclared event) { - controller.updateSingleCard(event.attacker); - return null; - } - - @Subscribe - public void receiveEvent(UiEvent evt) { - evt.visit(this); - } - } -} diff --git a/forge-gui/src/main/java/forge/match/NextGameDecision.java b/forge-gui/src/main/java/forge/match/NextGameDecision.java new file mode 100644 index 00000000000..88e11189c41 --- /dev/null +++ b/forge-gui/src/main/java/forge/match/NextGameDecision.java @@ -0,0 +1,7 @@ +package forge.match; + +public enum NextGameDecision { + NEW, + CONTINUE, + QUIT; +} diff --git a/forge-gui/src/main/java/forge/match/input/ButtonUtil.java b/forge-gui/src/main/java/forge/match/input/ButtonUtil.java deleted file mode 100644 index 0b55ac03f5d..00000000000 --- a/forge-gui/src/main/java/forge/match/input/ButtonUtil.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Forge: Play Magic: the Gathering. - * Copyright (C) 2011 Forge Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package forge.match.input; - -import forge.game.player.PlayerView; -import forge.interfaces.IButton; -import forge.match.MatchUtil; - -/** - * Manages match UI OK/Cancel button enabling and focus - */ -public class ButtonUtil { - public static void update(PlayerView owner, boolean okEnabled, boolean cancelEnabled, boolean focusOk) { - update(owner, "OK", "Cancel", okEnabled, cancelEnabled, focusOk); - } - public static void update(PlayerView owner, String okLabel, String cancelLabel, boolean okEnabled, boolean cancelEnabled, boolean focusOk) { - IButton btnOk = MatchUtil.getController().getBtnOK(owner); - IButton btnCancel = MatchUtil.getController().getBtnCancel(owner); - - btnOk.setText(okLabel); - btnCancel.setText(cancelLabel); - btnOk.setEnabled(okEnabled); - btnCancel.setEnabled(cancelEnabled); - if (okEnabled && focusOk) { - MatchUtil.getController().focusButton(btnOk); - } - else if (cancelEnabled) { - MatchUtil.getController().focusButton(btnCancel); - } - } -} diff --git a/forge-gui/src/main/java/forge/match/input/InputAttack.java b/forge-gui/src/main/java/forge/match/input/InputAttack.java index 068b9758294..2768c176fd0 100644 --- a/forge-gui/src/main/java/forge/match/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/match/input/InputAttack.java @@ -39,7 +39,6 @@ import forge.game.combat.CombatUtil; import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; import forge.util.FCollectionView; import forge.util.ITriggerEvent; @@ -89,10 +88,9 @@ public class InputAttack extends InputSyncronizedBase { private void updatePrompt() { if (canCallBackAttackers()) { - ButtonUtil.update(getOwner(), "OK", "Call Back", true, true, true); - } - else { - ButtonUtil.update(getOwner(), "OK", "Alpha Strike", true, true, true); + getController().getGui().updateButtons(getOwner(), "OK", "Call Back", true, true, true); + } else { + getController().getGui().updateButtons(getOwner(), "OK", "Alpha Strike", true, true, true); } } @@ -137,7 +135,7 @@ public class InputAttack extends InputSyncronizedBase { } } } - MatchUtil.updateCards(refreshCards); + getController().getGui().updateCards(refreshCards); updateMessage(); } @@ -147,7 +145,7 @@ public class InputAttack extends InputSyncronizedBase { setCurrentDefender(selected); } else { - MatchUtil.getController().flashIncorrectAction(); // cannot attack that player + getController().getGui().flashIncorrectAction(); // cannot attack that player } } @@ -260,18 +258,18 @@ public class InputAttack extends InputSyncronizedBase { combat.addAttacker(card, currentDefender, activeBand); activateBand(activeBand); - MatchUtil.fireEvent(new UiEventAttackerDeclared( + card.getGame().fireEvent(new UiEventAttackerDeclared( CardView.get(card), GameEntityView.get(currentDefender))); } private boolean undeclareAttacker(final Card card) { combat.removeFromCombat(card); - MatchUtil.setUsedToPay(CardView.get(card), false); + getController().getGui().setUsedToPay(CardView.get(card), false); // When removing an attacker clear the attacking band activateBand(null); - MatchUtil.fireEvent(new UiEventAttackerDeclared( + card.getGame().fireEvent(new UiEventAttackerDeclared( CardView.get(card), null)); return true; } @@ -280,10 +278,10 @@ public class InputAttack extends InputSyncronizedBase { currentDefender = def; for (final GameEntity ge : defenders) { if (ge instanceof Card) { - MatchUtil.setUsedToPay(CardView.get((Card) ge), ge == def); + getController().getGui().setUsedToPay(CardView.get((Card) ge), ge == def); } else if (ge instanceof Player) { - MatchUtil.setHighlighted(PlayerView.get((Player) ge), ge == def); + getController().getGui().setHighlighted(PlayerView.get((Player) ge), ge == def); } } @@ -293,14 +291,14 @@ public class InputAttack extends InputSyncronizedBase { private final void activateBand(final AttackingBand band) { if (activeBand != null) { for (final Card card : activeBand.getAttackers()) { - MatchUtil.setUsedToPay(CardView.get(card), false); + getController().getGui().setUsedToPay(CardView.get(card), false); } } activeBand = band; if (activeBand != null) { for (final Card card : activeBand.getAttackers()) { - MatchUtil.setUsedToPay(CardView.get(card), true); + getController().getGui().setUsedToPay(CardView.get(card), true); } } } @@ -324,6 +322,6 @@ public class InputAttack extends InputSyncronizedBase { showMessage(message); updatePrompt(); - MatchUtil.getController().showCombat(); // redraw sword icons + getController().getGui().showCombat(); // redraw sword icons } } diff --git a/forge-gui/src/main/java/forge/match/input/InputBase.java b/forge-gui/src/main/java/forge/match/input/InputBase.java index cc1b42bb14c..5a73c55de28 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBase.java +++ b/forge-gui/src/main/java/forge/match/input/InputBase.java @@ -18,17 +18,13 @@ package forge.match.input; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import forge.FThreads; import forge.game.Game; import forge.game.card.Card; import forge.game.phase.PhaseHandler; import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; @@ -41,8 +37,8 @@ import forge.util.ITriggerEvent; * @version $Id: InputBase.java 24769 2014-02-09 13:56:04Z Hellfish $ */ public abstract class InputBase implements java.io.Serializable, Input { - /** Constant serialVersionUID=-6539552513871194081L. */ - private static final long serialVersionUID = -6539552513871194081L; + /** Constant serialVersionUID=-2531867688249685076L. */ + private static final long serialVersionUID = -2531867688249685076L; private final PlayerControllerHuman controller; public InputBase(final PlayerControllerHuman controller0) { @@ -52,7 +48,8 @@ public abstract class InputBase implements java.io.Serializable, Input { return controller; } public PlayerView getOwner() { - return controller.getPlayer().getView(); + final Player owner = getController().getPlayer(); + return owner == null ? null : owner.getView(); } private boolean finished = false; @@ -61,7 +58,7 @@ public abstract class InputBase implements java.io.Serializable, Input { finished = true; if (allowAwaitNextInput()) { - awaitNextInput(controller); + controller.awaitNextInput(); } } @@ -69,66 +66,11 @@ public abstract class InputBase implements java.io.Serializable, Input { return false; } - private static final Timer awaitNextInputTimer = new Timer(); - private static TimerTask awaitNextInputTask; - - public static void awaitNextInput(final PlayerControllerHuman controller) { - //delay updating prompt to await next input briefly so buttons don't flicker disabled then enabled - awaitNextInputTask = new TimerTask() { - @Override - public void run() { - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - synchronized (awaitNextInputTimer) { - if (awaitNextInputTask != null) { - updatePromptForAwait(controller); - awaitNextInputTask = null; - } - } - } - }); - } - }; - awaitNextInputTimer.schedule(awaitNextInputTask, 250); - } - - public static void waitForOtherPlayer() { - final PlayerControllerHuman controller = MatchUtil.getOtherHumanController(); - if (controller == null) { return; } - - cancelAwaitNextInput(); - FThreads.invokeInEdtNowOrLater(new Runnable() { - @Override - public void run() { - updatePromptForAwait(controller); - } - }); - } - - private static void updatePromptForAwait(final PlayerControllerHuman controller) { - PlayerView playerView = controller.getLocalPlayerView(); - MatchUtil.getController().showPromptMessage(playerView, "Waiting for opponent..."); - ButtonUtil.update(playerView, false, false, false); - } - - public static void cancelAwaitNextInput() { - synchronized (awaitNextInputTimer) { //ensure task doesn't reset awaitNextInputTask during this block - if (awaitNextInputTask != null) { - try { - awaitNextInputTask.cancel(); //cancel timer once next input shown if needed - } - catch (Exception ex) {} //suppress any exception thrown by cancel() - awaitNextInputTask = null; - } - } - } - // showMessage() is always the first method called @Override public final void showMessageInitial() { finished = false; - cancelAwaitNextInput(); + controller.cancelAwaitNextInput(); showMessage(); } @@ -172,7 +114,7 @@ public abstract class InputBase implements java.io.Serializable, Input { // to remove need for CMatchUI dependence protected final void showMessage(final String message) { - MatchUtil.getController().showPromptMessage(getOwner(), message); + controller.getGui().showPromptMessage(getOwner(), message); } protected String getTurnPhasePriorityMessage(final Game game) { diff --git a/forge-gui/src/main/java/forge/match/input/InputBlock.java b/forge-gui/src/main/java/forge/match/input/InputBlock.java index dc267bf7786..145f98852e2 100644 --- a/forge-gui/src/main/java/forge/match/input/InputBlock.java +++ b/forge-gui/src/main/java/forge/match/input/InputBlock.java @@ -30,11 +30,9 @@ import forge.game.combat.CombatUtil; import forge.game.event.GameEventCombatChanged; import forge.game.player.Player; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; import forge.util.ThreadUtil; -import forge.util.gui.SGuiDialog; /** *

@@ -78,7 +76,7 @@ public class InputBlock extends InputSyncronizedBase { @Override protected final void showMessage() { // could add "Reset Blockers" button - ButtonUtil.update(getOwner(), true, false, true); + getController().getGui().updateButtons(getOwner(), true, false, true); if (currentAttacker == null) { showMessage("Select another attacker to declare blockers for."); @@ -89,7 +87,7 @@ public class InputBlock extends InputSyncronizedBase { showMessage(message); } - MatchUtil.getController().showCombat(); + getController().getGui().showCombat(); } /** {@inheritDoc} */ @@ -106,7 +104,7 @@ public class InputBlock extends InputSyncronizedBase { ThreadUtil.invokeInGameThread(new Runnable() { @Override public void run() { - SGuiDialog.message(blockErrors); + getController().getGui().message(blockErrors); } }); } @@ -118,7 +116,7 @@ public class InputBlock extends InputSyncronizedBase { boolean isCorrectAction = false; if (triggerEvent != null && triggerEvent.getButton() == 3 && card.getController() == defender) { combat.removeFromCombat(card); - MatchUtil.fireEvent(new UiEventBlockerAssigned( + card.getGame().fireEvent(new UiEventBlockerAssigned( CardView.get(card), (CardView) null)); isCorrectAction = true; } @@ -134,7 +132,7 @@ public class InputBlock extends InputSyncronizedBase { if (combat.isBlocking(card, currentAttacker)) { //if creature already blocking current attacker, remove blocker from combat combat.removeBlockAssignment(currentAttacker, card); - MatchUtil.fireEvent(new UiEventBlockerAssigned( + card.getGame().fireEvent(new UiEventBlockerAssigned( CardView.get(card), (CardView) null)); isCorrectAction = true; } @@ -142,7 +140,7 @@ public class InputBlock extends InputSyncronizedBase { isCorrectAction = CombatUtil.canBlock(currentAttacker, card, combat); if (isCorrectAction) { combat.addBlocker(currentAttacker, card); - MatchUtil.fireEvent(new UiEventBlockerAssigned( + card.getGame().fireEvent(new UiEventBlockerAssigned( CardView.get(card), CardView.get(currentAttacker))); } @@ -178,7 +176,7 @@ public class InputBlock extends InputSyncronizedBase { private void setCurrentAttacker(final Card card) { currentAttacker = card; for (final Card c : combat.getAttackers()) { - MatchUtil.setUsedToPay(CardView.get(c), card == c); + getController().getGui().setUsedToPay(CardView.get(c), card == c); } } } diff --git a/forge-gui/src/main/java/forge/match/input/InputConfirm.java b/forge-gui/src/main/java/forge/match/input/InputConfirm.java index f69a8b14541..eac9c27a006 100644 --- a/forge-gui/src/main/java/forge/match/input/InputConfirm.java +++ b/forge-gui/src/main/java/forge/match/input/InputConfirm.java @@ -57,7 +57,7 @@ public class InputConfirm extends InputSyncronizedBase { /** {@inheritDoc} */ @Override protected final void showMessage() { - ButtonUtil.update(getOwner(), yesButtonText, noButtonText, true, true, defaultYes); + getController().getGui().updateButtons(getOwner(), yesButtonText, noButtonText, true, true, defaultYes); showMessage(message); } diff --git a/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java b/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java index 1a55b755d9f..1b152900d0f 100644 --- a/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java +++ b/forge-gui/src/main/java/forge/match/input/InputConfirmMulligan.java @@ -26,12 +26,10 @@ import forge.game.card.CardCollectionView; import forge.game.card.CardView; import forge.game.player.Player; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; import forge.util.Lang; import forge.util.ThreadUtil; -import forge.util.gui.SGuiDialog; /** *

@@ -74,11 +72,11 @@ public class InputConfirmMulligan extends InputSyncronizedBase { } if (isCommander) { - ButtonUtil.update(getOwner(), "Keep", "Exile", true, false, true); + getController().getGui().updateButtons(getOwner(), "Keep", "Exile", true, false, true); sb.append("Will you keep your hand or choose some cards to exile those and draw one less card?"); } else { - ButtonUtil.update(getOwner(), "Keep", "Mulligan", true, true, true); + getController().getGui().updateButtons(getOwner(), "Keep", "Mulligan", true, true, true); sb.append("Do you want to keep your hand?"); } @@ -103,7 +101,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase { if (isCommander) { // Clear the "selected" icon after clicking the done button for (final Card c : this.selected) { - MatchUtil.setUsedToPay(c.getView(), false); + getController().getGui().setUsedToPay(c.getView(), false); } } stop(); @@ -121,7 +119,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase { } final CardView cView = c0.getView(); - if (isSerumPowder && SGuiDialog.confirm(cView, "Use " + cView + "'s ability?")) { + if (isSerumPowder && getController().getGui().confirm(cView, "Use " + cView + "'s ability?")) { cardSelectLocked = true; ThreadUtil.invokeInGameThread(new Runnable() { public void run() { @@ -138,14 +136,14 @@ public class InputConfirmMulligan extends InputSyncronizedBase { if (isCommander) { // allow to choose cards for partial paris if (selected.contains(c0)) { - MatchUtil.setUsedToPay(c0.getView(), false); + getController().getGui().setUsedToPay(c0.getView(), false); selected.remove(c0); } else { - MatchUtil.setUsedToPay(c0.getView(), true); + getController().getGui().setUsedToPay(c0.getView(), true); selected.add(c0); } - ButtonUtil.update(getOwner(), "Keep", "Exile", true, !selected.isEmpty(), true); + getController().getGui().updateButtons(getOwner(), "Keep", "Exile", true, !selected.isEmpty(), true); } return true; } diff --git a/forge-gui/src/main/java/forge/match/input/InputLockUI.java b/forge-gui/src/main/java/forge/match/input/InputLockUI.java index 220fe6bd761..c467add0545 100644 --- a/forge-gui/src/main/java/forge/match/input/InputLockUI.java +++ b/forge-gui/src/main/java/forge/match/input/InputLockUI.java @@ -9,7 +9,7 @@ import forge.game.card.Card; import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; -import forge.match.MatchUtil; +import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; import forge.util.ThreadUtil; @@ -18,9 +18,11 @@ public class InputLockUI implements Input { private final InputQueue inputQueue; private final Game game; - public InputLockUI(final Game game0, final InputQueue inputQueue0) { + private final PlayerControllerHuman controller; + public InputLockUI(final Game game0, final InputQueue inputQueue0, final PlayerControllerHuman controller) { game = game0; inputQueue = inputQueue0; + this.controller = controller; } @Override @@ -32,7 +34,7 @@ public class InputLockUI implements Input { int ixCall = 1 + iCall.getAndIncrement(); ThreadUtil.delay(500, new InputUpdater(ixCall)); } - + @Override public String toString() { return "lockUI"; @@ -56,7 +58,7 @@ public class InputLockUI implements Input { private final Runnable showMessageFromEdt = new Runnable() { @Override public void run() { - ButtonUtil.update(InputLockUI.this.getOwner(), "", "", false, false, false); + controller.getGui().updateButtons(InputLockUI.this.getOwner(), "", "", false, false, false); showMessage("Waiting for actions..."); } }; @@ -66,7 +68,7 @@ public class InputLockUI implements Input { } protected void showMessage(String message) { - MatchUtil.getController().showPromptMessage(getOwner(), message); + controller.getGui().showPromptMessage(getOwner(), message); } @Override diff --git a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java index 19e5438d1b0..fef154550e9 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPassPriority.java +++ b/forge-gui/src/main/java/forge/match/input/InputPassPriority.java @@ -31,7 +31,6 @@ import forge.player.PlayerControllerHuman; import forge.properties.ForgePreferences.FPref; import forge.util.ITriggerEvent; import forge.util.ThreadUtil; -import forge.util.gui.SOptionPane; /** *

@@ -44,25 +43,23 @@ import forge.util.gui.SOptionPane; public class InputPassPriority extends InputSyncronizedBase { /** Constant serialVersionUID=-581477682214137181L. */ private static final long serialVersionUID = -581477682214137181L; - private final Player player; private List chosenSa; - public InputPassPriority(final PlayerControllerHuman controller, final Player human) { + public InputPassPriority(final PlayerControllerHuman controller) { super(controller); - player = human; } /** {@inheritDoc} */ @Override public final void showMessage() { - showMessage(getTurnPhasePriorityMessage(player.getGame())); + showMessage(getTurnPhasePriorityMessage(getController().getGame())); chosenSa = null; if (getController().canUndoLastAction()) { //allow undoing with cancel button if can undo last action - ButtonUtil.update(getOwner(), "OK", "Undo", true, true, true); + getController().getGui().updateButtons(getOwner(), "OK", "Undo", true, true, true); } else { //otherwise allow ending turn with cancel button - ButtonUtil.update(getOwner(), "OK", "End Turn", true, true, true); + getController().getGui().updateButtons(getOwner(), "OK", "End Turn", true, true, true); } } @@ -85,7 +82,7 @@ public class InputPassPriority extends InputSyncronizedBase { passPriority(new Runnable() { @Override public void run() { - player.getController().autoPassUntilEndOfTurn(); + getController().autoPassUntilEndOfTurn(); stop(); } }); @@ -94,13 +91,13 @@ public class InputPassPriority extends InputSyncronizedBase { @Override protected boolean allowAwaitNextInput() { - return chosenSa == null && !player.getController().mayAutoPass(); //don't allow awaiting next input if player chose to end the turn or if a spell/ability is chosen + return chosenSa == null && !getController().mayAutoPass(); //don't allow awaiting next input if player chose to end the turn or if a spell/ability is chosen } private void passPriority(final Runnable runnable) { if (FModel.getPreferences().getPrefBoolean(FPref.UI_MANA_LOST_PROMPT)) { //if gui player has mana floating that will be lost if phase ended right now, prompt before passing priority - final Game game = player.getGame(); + final Game game = getController().getGame(); if (game.getStack().isEmpty()) { //phase can't end right now if stack isn't empty Player player = game.getPhaseHandler().getPriorityPlayer(); if (player != null && player.getManaPool().willManaBeLostAtEndOfPhase() && player.getLobbyPlayer() == GamePlayerUtil.getGuiPlayer()) { @@ -111,7 +108,7 @@ public class InputPassPriority extends InputSyncronizedBase { if (FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)) { message += " You will take mana burn damage equal to the amount of floating mana lost this way."; } - if (SOptionPane.showOptionDialog(message, "Mana Floating", SOptionPane.WARNING_ICON, new String[]{"OK", "Cancel"}) == 0) { + if (getController().getGui().showConfirmDialog(message, "Mana Floating", "Ok", "Cancel")) { runnable.run(); } } @@ -128,12 +125,12 @@ public class InputPassPriority extends InputSyncronizedBase { @Override protected boolean onCardSelected(final Card card, final List otherCardsToSelect, final ITriggerEvent triggerEvent) { //remove unplayable unless triggerEvent specified, in which case unplayable may be shown as disabled options - List abilities = card.getAllPossibleAbilities(player, triggerEvent == null); + List abilities = card.getAllPossibleAbilities(getController().getPlayer(), triggerEvent == null); if (abilities.isEmpty()) { return false; } - final SpellAbility ability = player.getController().getAbilityToPlay(abilities, triggerEvent); + final SpellAbility ability = getController().getAbilityToPlay(abilities, triggerEvent); if (ability != null) { chosenSa = new ArrayList(); chosenSa.add(ability); @@ -141,7 +138,7 @@ public class InputPassPriority extends InputSyncronizedBase { //if mana ability activated, activate same ability on other cards to select if possible String abStr = ability.toUnsuppressedString(); for (Card c : otherCardsToSelect) { - for (SpellAbility ab : c.getAllPossibleAbilities(player, true)) { + for (SpellAbility ab : c.getAllPossibleAbilities(getController().getPlayer(), true)) { if (ab.toUnsuppressedString().equals(abStr)) { chosenSa.add(ab); break; @@ -155,12 +152,12 @@ public class InputPassPriority extends InputSyncronizedBase { } @Override - public String getActivateAction(Card card) { - List abilities = card.getAllPossibleAbilities(player, true); + public String getActivateAction(final Card card) { + final List abilities = card.getAllPossibleAbilities(getController().getPlayer(), true); if (abilities.isEmpty()) { return null; } - SpellAbility sa = abilities.get(0); + final SpellAbility sa = abilities.get(0); if (sa.isSpell()) { return "cast spell"; } diff --git a/forge-gui/src/main/java/forge/match/input/InputPayMana.java b/forge-gui/src/main/java/forge/match/input/InputPayMana.java index bec9ac60e0a..a665412951c 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPayMana.java +++ b/forge-gui/src/main/java/forge/match/input/InputPayMana.java @@ -24,16 +24,13 @@ import forge.game.player.PlayerView; import forge.game.replacement.ReplacementEffect; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.SpellAbility; -import forge.match.MatchUtil; import forge.player.HumanPlay; import forge.player.PlayerControllerHuman; import forge.util.Evaluator; import forge.util.ITriggerEvent; -import forge.util.gui.SGuiChoose; - public abstract class InputPayMana extends InputSyncronizedBase { - private static final long serialVersionUID = -9133423708688480255L; + private static final long serialVersionUID = 718128600948280315L; protected int phyLifeToLose = 0; @@ -58,13 +55,13 @@ public abstract class InputPayMana extends InputSyncronizedBase { //if player is floating mana, show mana pool to make it easier to use that mana wasFloatingMana = !player.getManaPool().isEmpty(); - zoneToRestore = wasFloatingMana ? MatchUtil.getController().showManaPool(PlayerView.get(player)) : null; + zoneToRestore = wasFloatingMana ? getController().getGui().showManaPool(PlayerView.get(player)) : null; } @Override protected void onStop() { if (wasFloatingMana) { //hide mana pool if it was shown due to floating mana - MatchUtil.getController().hideManaPool(PlayerView.get(player), zoneToRestore); + getController().getGui().hideManaPool(PlayerView.get(player), zoneToRestore); } } @@ -273,9 +270,8 @@ public abstract class InputPayMana extends InputSyncronizedBase { final SpellAbility chosen; if (chosenAbility == null) { - chosen = abilities.size() > 1 && choice ? SGuiChoose.one("Choose mana ability", abilities) : abilities.get(0); - } - else { + chosen = abilities.size() > 1 && choice ? getController().getGui().one("Choose mana ability", abilities) : abilities.get(0); + } else { chosen = chosenAbility; } ColorSet colors = ColorSet.fromMask(0 == colorNeeded ? colorCanUse : colorNeeded); @@ -387,10 +383,9 @@ public abstract class InputPayMana extends InputSyncronizedBase { protected void updateButtons() { if (supportAutoPay()) { - ButtonUtil.update(getOwner(), "Auto", "Cancel", false, true, false); - } - else { - ButtonUtil.update(getOwner(), "", "Cancel", false, true, false); + getController().getGui().updateButtons(getOwner(), "Auto", "Cancel", false, true, false); + } else { + getController().getGui().updateButtons(getOwner(), "", "Cancel", false, true, false); } } @@ -412,7 +407,7 @@ public abstract class InputPayMana extends InputSyncronizedBase { canPayManaCost = proc.getResult(); } if (canPayManaCost) { //enabled Auto button if mana cost can be paid - ButtonUtil.update(getOwner(), "Auto", "Cancel", true, true, true); + getController().getGui().updateButtons(getOwner(), "Auto", "Cancel", true, true, true); } } showMessage(getMessage()); diff --git a/forge-gui/src/main/java/forge/match/input/InputPlaybackControl.java b/forge-gui/src/main/java/forge/match/input/InputPlaybackControl.java index a8d743e7e8a..9fd20bb110f 100644 --- a/forge-gui/src/main/java/forge/match/input/InputPlaybackControl.java +++ b/forge-gui/src/main/java/forge/match/input/InputPlaybackControl.java @@ -4,10 +4,8 @@ import forge.control.FControlGamePlayback; import forge.game.Game; import forge.game.card.Card; import forge.game.phase.PhaseHandler; -import forge.game.player.PlayerView; -import forge.match.MatchUtil; -public class InputPlaybackControl extends InputSyncronizedBase implements InputSynchronized { +public class InputPlaybackControl extends InputSyncronizedBase { private static final long serialVersionUID = 7979208993306642072L; final FControlGamePlayback control; @@ -17,17 +15,12 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS private final Game game; public InputPlaybackControl(final Game game0, final FControlGamePlayback fControlGamePlayback) { - super(null); + super(fControlGamePlayback.getController()); game = game0; control = fControlGamePlayback; setPause(false); } - @Override - public PlayerView getOwner() { - return MatchUtil.getHumanController().getLocalPlayerView(); - } - @Override protected void showMessage() { setPause(false); @@ -39,8 +32,7 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS if (isPaused) { showMessage(getTurnPhasePriorityMessage(game)); currentTurn = 0; - } - else { + } else { final PhaseHandler ph = game.getPhaseHandler(); if (currentTurn == ph.getTurn()) { return; } @@ -49,13 +41,12 @@ public class InputPlaybackControl extends InputSyncronizedBase implements InputS } } - private void setPause(boolean pause) { + private void setPause(final boolean pause) { isPaused = pause; if (isPaused) { - ButtonUtil.update(getOwner(), "Resume", "Step", true, true, true); - } - else { - ButtonUtil.update(getOwner(), "Pause", isFast ? "1x Speed" : "10x Faster", true, true, true); + getController().getGui().updateButtons(null, "Resume", "Step", true, true, true); + } else { + getController().getGui().updateButtons(null, "Pause", isFast ? "1x Speed" : "10x Faster", true, true, true); } } diff --git a/forge-gui/src/main/java/forge/match/input/InputProliferate.java b/forge-gui/src/main/java/forge/match/input/InputProliferate.java index 46aac4c8700..f339ef17165 100644 --- a/forge-gui/src/main/java/forge/match/input/InputProliferate.java +++ b/forge-gui/src/main/java/forge/match/input/InputProliferate.java @@ -13,7 +13,6 @@ import forge.game.card.CounterType; import forge.game.player.Player; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; -import forge.util.gui.SGuiChoose; public final class InputProliferate extends InputSelectManyBase { private static final long serialVersionUID = -1779224307654698954L; @@ -61,7 +60,7 @@ public final class InputProliferate extends InputSelectManyBase { } } - CounterType toAdd = choices.size() == 1 ? choices.get(0) : SGuiChoose.one("Select counter type", choices); + CounterType toAdd = choices.size() == 1 ? choices.get(0) : getController().getGui().one("Select counter type", choices); chosenCounters.put(card, toAdd); } diff --git a/forge-gui/src/main/java/forge/match/input/InputProxy.java b/forge-gui/src/main/java/forge/match/input/InputProxy.java index 8b7f2538312..5eb7a9a79c2 100644 --- a/forge-gui/src/main/java/forge/match/input/InputProxy.java +++ b/forge-gui/src/main/java/forge/match/input/InputProxy.java @@ -61,7 +61,10 @@ public class InputProxy implements Observer { game.getPhaseHandler().debugPrintState(), Singletons.getControl().getInputQueue().printInputStack()); */ input.set(nextInput); - Runnable showMessage = new Runnable() { + if (!(nextInput instanceof InputLockUI)) { + controller.getGui().setCurrentPlayer(nextInput.getOwner()); + } + final Runnable showMessage = new Runnable() { @Override public void run() { Input current = getInput(); @@ -70,7 +73,6 @@ public class InputProxy implements Observer { current.showMessageInitial(); } }; - FThreads.invokeInEdtLater(showMessage); } /** @@ -79,7 +81,7 @@ public class InputProxy implements Observer { *

*/ public final void selectButtonOK() { - Input inp = getInput(); + final Input inp = getInput(); if (inp != null) { inp.selectButtonOK(); } diff --git a/forge-gui/src/main/java/forge/match/input/InputQueue.java b/forge-gui/src/main/java/forge/match/input/InputQueue.java index d8975c16355..da55f3ea63d 100644 --- a/forge-gui/src/main/java/forge/match/input/InputQueue.java +++ b/forge-gui/src/main/java/forge/match/input/InputQueue.java @@ -22,7 +22,6 @@ import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; import forge.game.Game; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; /** @@ -35,11 +34,9 @@ import forge.player.PlayerControllerHuman; */ public class InputQueue extends Observable { private final BlockingDeque inputStack = new LinkedBlockingDeque(); - private final InputLockUI inputLock; private final Game game; public InputQueue(final Game game, final InputProxy inputProxy) { - inputLock = new InputLockUI(game, this); this.game = game; addObserver(inputProxy); } @@ -63,11 +60,11 @@ public class InputQueue extends Observable { } public final Input getActualInput(final PlayerControllerHuman controller) { - Input topMost = inputStack.peek(); // incoming input to Control - if (topMost != null && !controller.getGame().isGameOver()) { + final Input topMost = inputStack.peek(); // incoming input to Control + if (topMost != null && !game.isGameOver()) { return topMost; } - return inputLock; + return new InputLockUI(game, this, controller); } // getInput() // only for debug purposes @@ -76,23 +73,22 @@ public class InputQueue extends Observable { } public void setInput(final InputSynchronized input) { - if (MatchUtil.getHumanCount() > 1) { //update current player if needed - MatchUtil.setCurrentPlayer(game.getPlayer(input.getOwner())); - } + //if (HostedMatch.getHumanCount() > 1) { //update current player if needed + //HostedMatch.setCurrentPlayer(game.getPlayer(input.getOwner())); + //} inputStack.push(input); - InputBase.waitForOtherPlayer(); syncPoint(); updateObservers(); } - public void syncPoint() { - synchronized (inputLock) { + void syncPoint() { + synchronized (this) { // acquire and release lock, so that actions from Game thread happen before EDT reads their results } } - public void onGameOver(boolean releaseAllInputs) { - for (InputSynchronized inp : inputStack) { + public void onGameOver(final boolean releaseAllInputs) { + for (final InputSynchronized inp : inputStack) { inp.relaseLatchWhenGameIsOver(); if (!releaseAllInputs) { break; diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectManyBase.java b/forge-gui/src/main/java/forge/match/input/InputSelectManyBase.java index ca322ddcd46..9d831506567 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectManyBase.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectManyBase.java @@ -7,7 +7,6 @@ import com.google.common.collect.Iterables; import forge.game.GameEntity; import forge.game.card.Card; import forge.game.card.CardView; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; public abstract class InputSelectManyBase extends InputSyncronizedBase { @@ -46,7 +45,7 @@ public abstract class InputSelectManyBase extends InputSyn @Override public final void showMessage() { showMessage(getMessage()); - ButtonUtil.update(getOwner(), hasEnoughTargets(), allowCancel, true); + getController().getGui().updateButtons(getOwner(), hasEnoughTargets(), allowCancel, true); } @Override @@ -76,14 +75,14 @@ public abstract class InputSelectManyBase extends InputSyn protected void onSelectStateChanged(final GameEntity c, final boolean newState) { if (c instanceof Card) { - MatchUtil.setUsedToPay(CardView.get((Card) c), newState); // UI supports card highlighting though this abstraction-breaking mechanism + getController().getGui().setUsedToPay(CardView.get((Card) c), newState); // UI supports card highlighting though this abstraction-breaking mechanism } } private void resetUsedToPay() { for (final GameEntity c : getSelected()) { if (c instanceof Card) { - MatchUtil.setUsedToPay(CardView.get((Card) c), false); + getController().getGui().setUsedToPay(CardView.get((Card) c), false); } } } diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java index 73639b7d23a..e4138933147 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectTargets.java @@ -14,11 +14,8 @@ import forge.game.card.CardView; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; -import forge.match.MatchUtil; import forge.player.PlayerControllerHuman; import forge.util.ITriggerEvent; -import forge.util.gui.SGuiChoose; - public final class InputSelectTargets extends InputSyncronizedBase { private final List choices; @@ -70,19 +67,19 @@ public final class InputSelectTargets extends InputSyncronizedBase { if (!tgt.isMinTargetsChosen(sa.getHostCard(), sa) || tgt.isDividedAsYouChoose()) { if (mandatory && tgt.hasCandidates(sa, true)) { // Player has to click on a target - ButtonUtil.update(getOwner(), false, false, false); + getController().getGui().updateButtons(getOwner(), false, false, false); } else { - ButtonUtil.update(getOwner(), false, true, false); + getController().getGui().updateButtons(getOwner(), false, true, false); } } else { if (mandatory && tgt.hasCandidates(sa, true)) { // Player has to click on a target or ok - ButtonUtil.update(getOwner(), true, false, true); + getController().getGui().updateButtons(getOwner(), true, false, true); } else { - ButtonUtil.update(getOwner(), true, true, true); + getController().getGui().updateButtons(getOwner(), true, true, true); } } } @@ -170,7 +167,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { final StringBuilder sb = new StringBuilder(); sb.append(apiBasedMessage); sb.append(card.toString()); - Integer chosen = SGuiChoose.oneOrNone(sb.toString(), choices); + final Integer chosen = getController().getGui().oneOrNone(sb.toString(), choices); if (chosen == null) { return true; //still return true since there was a valid choice } @@ -226,7 +223,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { final StringBuilder sb = new StringBuilder(); sb.append(apiBasedMessage); sb.append(player.getName()); - Integer chosen = SGuiChoose.oneOrNone(sb.toString(), choices); + final Integer chosen = getController().getGui().oneOrNone(sb.toString(), choices); if (null == chosen) { return; } @@ -243,7 +240,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { private void addTarget(final GameEntity ge) { sa.getTargets().add(ge); if (ge instanceof Card) { - MatchUtil.setUsedToPay(CardView.get((Card) ge), true); + getController().getGui().setUsedToPay(CardView.get((Card) ge), true); lastTarget = (Card) ge; } final Integer val = targetDepth.get(ge); @@ -260,7 +257,7 @@ public final class InputSelectTargets extends InputSyncronizedBase { private void done() { for (final GameEntity c : targetDepth.keySet()) { if (c instanceof Card) { - MatchUtil.setUsedToPay(CardView.get((Card) c), false); + getController().getGui().setUsedToPay(CardView.get((Card) c), false); } } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java index f1585dab97a..ef6c3d50e0e 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestController.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestController.java @@ -27,6 +27,7 @@ import java.util.Set; import com.google.common.base.Predicate; import forge.FThreads; +import forge.GuiBase; import forge.ImageKeys; import forge.LobbyPlayer; import forge.card.CardRarity; @@ -37,12 +38,11 @@ import forge.deck.Deck; import forge.game.GameRules; import forge.game.GameType; import forge.game.GameView; -import forge.game.Match; import forge.game.player.RegisteredPlayer; import forge.interfaces.IButton; import forge.interfaces.IWinLoseView; import forge.item.PaperCard; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.planarconquest.ConquestPlaneData.RegionData; import forge.planarconquest.ConquestPreferences.CQPref; @@ -253,8 +253,8 @@ public class ConquestController { variants.add(GameType.Planechase); } - RegisteredPlayer humanStart = new RegisteredPlayer(commander.getDeck()); - RegisteredPlayer aiStart = new RegisteredPlayer(opponent.getDeck()); + final RegisteredPlayer humanStart = new RegisteredPlayer(commander.getDeck()); + final RegisteredPlayer aiStart = new RegisteredPlayer(opponent.getDeck()); if (isHumanDefending) { //give human a small life bonus if defending humanStart.setStartingLife(humanStart.getStartingLife() + prefs.getPrefInt(CQPref.DEFEND_BONUS_LIFE)); @@ -276,28 +276,28 @@ public class ConquestController { aiPlayerName += " (AI)"; //ensure player names are distinct } - List starter = new ArrayList(); + final List starter = new ArrayList(); humanPlayer = new LobbyPlayerHuman(humanPlayerName); humanPlayer.setAvatarCardImageKey(ImageKeys.getImageKey(commander.getCard(), false)); starter.add(humanStart.setPlayer(humanPlayer)); - LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(aiPlayerName, -1); + final LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(aiPlayerName, -1); aiPlayer.setAvatarCardImageKey(ImageKeys.getImageKey(opponent.getCard(), false)); starter.add(aiStart.setPlayer(aiPlayer)); - boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); - for(RegisteredPlayer rp : starter) { + final boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); + for (final RegisteredPlayer rp : starter) { rp.setRandomFoil(useRandomFoil); } - GameRules rules = new GameRules(GameType.PlanarConquest); + final GameRules rules = new GameRules(GameType.PlanarConquest); rules.setGamesPerMatch(1); //only play one game at a time rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); - final Match mc = new Match(rules, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); FThreads.invokeInEdtNowOrLater(new Runnable(){ @Override public void run() { - MatchUtil.startGame(mc); + hostedMatch.startMatch(rules, null, starter, humanStart, GuiBase.getInterface().getNewGuiGame()); } }); } diff --git a/forge-gui/src/main/java/forge/player/GamePlayerUtil.java b/forge-gui/src/main/java/forge/player/GamePlayerUtil.java index 42cfcf2bc22..62a70219da0 100644 --- a/forge-gui/src/main/java/forge/player/GamePlayerUtil.java +++ b/forge-gui/src/main/java/forge/player/GamePlayerUtil.java @@ -7,7 +7,6 @@ import forge.LobbyPlayer; import forge.ai.AiProfileUtil; import forge.ai.LobbyPlayerAi; import forge.game.player.Player; -import forge.match.MatchUtil; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.util.GuiDisplayUtil; @@ -87,17 +86,6 @@ public final class GamePlayerUtil { newPlayerName = getVerifiedPlayerName(getPlayerNameUsingStandardPrompt(oldPlayerName), oldPlayerName); } - //update name for player in active game if needed - if (MatchUtil.getGame() != null) { - for (Player player : MatchUtil.getGame().getPlayers()) { - if (player.getLobbyPlayer() == MatchUtil.getGuiPlayer()) { - player.setName(newPlayerName); - player.getLobbyPlayer().setName(newPlayerName); - break; - } - } - } - FModel.getPreferences().setPref(FPref.PLAYER_NAME, newPlayerName); FModel.getPreferences().save(); diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 532d09d328d..a83d0c9f2c3 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -1,5 +1,13 @@ package forge.player; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -16,7 +24,34 @@ import forge.game.card.CardPredicates; import forge.game.card.CardPredicates.Presets; import forge.game.card.CardView; import forge.game.card.CounterType; -import forge.game.cost.*; +import forge.game.cost.CostAddMana; +import forge.game.cost.CostChooseCreatureType; +import forge.game.cost.CostDamage; +import forge.game.cost.CostDecisionMakerBase; +import forge.game.cost.CostDiscard; +import forge.game.cost.CostDraw; +import forge.game.cost.CostExile; +import forge.game.cost.CostExileFromStack; +import forge.game.cost.CostExiledMoveToGrave; +import forge.game.cost.CostFlipCoin; +import forge.game.cost.CostGainControl; +import forge.game.cost.CostGainLife; +import forge.game.cost.CostMill; +import forge.game.cost.CostPartMana; +import forge.game.cost.CostPayLife; +import forge.game.cost.CostPutCardToLib; +import forge.game.cost.CostPutCounter; +import forge.game.cost.CostRemoveAnyCounter; +import forge.game.cost.CostRemoveCounter; +import forge.game.cost.CostReturn; +import forge.game.cost.CostReveal; +import forge.game.cost.CostSacrifice; +import forge.game.cost.CostTap; +import forge.game.cost.CostTapType; +import forge.game.cost.CostUnattach; +import forge.game.cost.CostUntap; +import forge.game.cost.CostUntapType; +import forge.game.cost.PaymentDecision; import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.spellability.SpellAbility; @@ -28,11 +63,6 @@ import forge.util.Aggregates; import forge.util.FCollectionView; import forge.util.ITriggerEvent; import forge.util.Lang; -import forge.util.gui.SGuiChoose; -import forge.util.gui.SGuiDialog; - -import java.util.*; -import java.util.Map.Entry; public class HumanCostDecision extends CostDecisionMakerBase { private final PlayerControllerHuman controller; @@ -298,18 +328,18 @@ public class HumanCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(0); } final Game game = controller.getGame(); - final Player p = game.getPlayer(SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone))); + final Player p = game.getPlayer(controller.getGui().oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone))); if (p == null) { return null; } - CardCollection typeList = CardLists.filter(list, CardPredicates.isOwner(p)); - int count = typeList.size(); + final CardCollection typeList = CardLists.filter(list, CardPredicates.isOwner(p)); + final int count = typeList.size(); if (count < nNeeded) { return null; } - CardCollection toExile = game.getCardList(SGuiChoose.many("Exile from " + cost.getFrom(), "To be exiled", nNeeded, CardView.getCollection(typeList), null)); + final CardCollection toExile = game.getCardList(controller.getGui().many("Exile from " + cost.getFrom(), "To be exiled", nNeeded, CardView.getCollection(typeList), null)); return PaymentDecision.card(toExile); } @@ -357,7 +387,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { List exiled = new ArrayList(); for (int i = 0; i < c; i++) { //Have to use the stack descriptions here because some copied spells have no description otherwise - final String o = SGuiChoose.oneOrNone("Exile from Stack", descList); + final String o = controller.getGui().oneOrNone("Exile from Stack", descList); if (o != null) { final SpellAbility toExile = saList.get(descList.indexOf(o)); @@ -393,7 +423,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { CardCollection exiled = new CardCollection(); for (int i = 0; i < nNeeded; i++) { - final Card c = getCard(SGuiChoose.oneOrNone("Exile from " + cost.getFrom(), CardView.getCollection(typeList))); + final Card c = getCard(controller.getGui().oneOrNone("Exile from " + cost.getFrom(), CardView.getCollection(typeList))); if (c == null) { return null; } typeList.remove(c); @@ -422,7 +452,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { if (list.size() < c) { return null; } - final CardCollection choice = controller.getGame().getCardList(SGuiChoose.many("Choose an exiled card to put into graveyard", "To graveyard", c, CardView.getCollection(list), CardView.get(source))); + final CardCollection choice = controller.getGame().getCardList(controller.getGui().many("Choose an exiled card to put into graveyard", "To graveyard", c, CardView.getCollection(list), CardView.get(source))); return PaymentDecision.card(choice); } @@ -494,7 +524,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { final StringBuilder sb = new StringBuilder(); sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:"); - final Player chosenToGain = controller.getGame().getPlayer(SGuiChoose.oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife))); + final Player chosenToGain = controller.getGame().getPlayer(controller.getGui().oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife))); if (chosenToGain == null) { return null; } @@ -604,7 +634,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { CardCollection chosen = new CardCollection(); for (int i = 0; i < nNeeded; i++) { - final Card c = getCard(SGuiChoose.oneOrNone("Put from " + fromZone + " to library", CardView.getCollection(typeList))); + final Card c = getCard(controller.getGui().oneOrNone("Put from " + fromZone + " to library", CardView.getCollection(typeList))); if (c == null) { return null; } @@ -619,7 +649,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { return PaymentDecision.number(0); } - final Player p = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone))); + final Player p = controller.getGame().getPlayer(controller.getGui().oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone))); if (p == null) { return null; } @@ -631,7 +661,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { CardCollection chosen = new CardCollection(); for (int i = 0; i < nNeeded; i++) { - final Card c = getCard(SGuiChoose.oneOrNone("Put cards from " + fromZone + " to Library", CardView.getCollection(typeList))); + final Card c = getCard(controller.getGui().oneOrNone("Put cards from " + fromZone + " to Library", CardView.getCollection(typeList))); if (c == null) { return null; } @@ -805,7 +835,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { } String prompt = "Select type counters to remove"; - cost.setCounterType(SGuiChoose.one(prompt, typeChoices)); + cost.setCounterType(controller.getGui().one(prompt, typeChoices)); return PaymentDecision.card(selected, cost.getCounter()); } @@ -903,7 +933,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { int maxCounters = source.getCounters(cost.counter); if (amount.equals("All")) { final CardView view = CardView.get(ability.getHostCard()); - if (!SGuiDialog.confirm(view, "Remove all counters?")) { + if (!controller.getGui().confirm(view, "Remove all counters?")) { return null; } cntRemoved = maxCounters; @@ -959,7 +989,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { } } - final Card card = getCard(SGuiChoose.oneOrNone("Remove counter(s) from a card in " + cost.zone, suspended)); + final Card card = getCard(controller.getGui().oneOrNone("Remove counter(s) from a card in " + cost.zone, suspended)); return null == card ? null : PaymentDecision.card(card, c); } diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 1008b6fd783..3ae9dd436e7 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -450,7 +450,7 @@ public class HumanPlay { } if (typeChoices.size() > 1) { String cprompt = "Select type counters to remove"; - counterType = SGuiChoose.one(cprompt, typeChoices); + counterType = controller.getGui().one(cprompt, typeChoices); } else { counterType = typeChoices.get(0); diff --git a/forge-gui/src/main/java/forge/player/LobbyPlayerHuman.java b/forge-gui/src/main/java/forge/player/LobbyPlayerHuman.java index 34830411547..deb7ae0405f 100644 --- a/forge-gui/src/main/java/forge/player/LobbyPlayerHuman.java +++ b/forge-gui/src/main/java/forge/player/LobbyPlayerHuman.java @@ -5,7 +5,6 @@ import forge.game.Game; import forge.game.player.IGameEntitiesFactory; import forge.game.player.Player; import forge.game.player.PlayerController; -import forge.match.MatchUtil; import forge.util.GuiDisplayUtil; public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactory { @@ -19,14 +18,14 @@ public class LobbyPlayerHuman extends LobbyPlayer implements IGameEntitiesFactor } @Override - public Player createIngamePlayer(Game game, final int id) { - Player player = new Player(GuiDisplayUtil.personalizeHuman(getName()), game, id); - PlayerControllerHuman controller = new PlayerControllerHuman(game, player, this); + public Player createIngamePlayer(final Game game, final int id) { + final Player player = new Player(GuiDisplayUtil.personalizeHuman(getName()), game, id); + final PlayerControllerHuman controller = new PlayerControllerHuman(game, player, this); player.setFirstController(controller); return player; } public void hear(LobbyPlayer player, String message) { - MatchUtil.getController().hear(player, message); + //ostedMatch.getController().hear(player, message); } } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 56d5b3d2586..27d7d932e74 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -41,6 +41,7 @@ import forge.control.FControlGamePlayback; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckSection; +import forge.events.UiEventNextGameDecision; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameEntityView; @@ -63,7 +64,6 @@ import forge.game.cost.Cost; import forge.game.cost.CostPart; import forge.game.cost.CostPartMana; import forge.game.mana.Mana; -import forge.game.phase.PhaseType; import forge.game.player.DelayedReveal; import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; @@ -80,13 +80,14 @@ import forge.game.trigger.WrappedAbility; import forge.game.zone.MagicStack; import forge.game.zone.Zone; import forge.game.zone.ZoneType; +import forge.interfaces.IDevModeCheats; +import forge.interfaces.IGameController; +import forge.interfaces.IGuiGame; import forge.item.IPaperCard; import forge.item.PaperCard; -import forge.match.MatchUtil; -import forge.match.input.ButtonUtil; +import forge.match.NextGameDecision; import forge.match.input.Input; import forge.match.input.InputAttack; -import forge.match.input.InputBase; import forge.match.input.InputBlock; import forge.match.input.InputConfirm; import forge.match.input.InputConfirmMulligan; @@ -107,8 +108,6 @@ import forge.util.ITriggerEvent; import forge.util.Lang; import forge.util.MessageUtil; import forge.util.TextUtil; -import forge.util.gui.SGuiChoose; -import forge.util.gui.SGuiDialog; import forge.util.gui.SOptionPane; /** @@ -116,7 +115,9 @@ import forge.util.gui.SOptionPane; * * Handles phase skips for now. */ -public class PlayerControllerHuman extends PlayerController { +public class PlayerControllerHuman + extends PlayerController + implements IGameController { /** * Cards this player may look at right now, for example when searching a * library. @@ -124,20 +125,29 @@ public class PlayerControllerHuman extends PlayerController { private boolean mayLookAtAllCards = false; private boolean disableAutoYields = false; + private IGuiGame gui; + protected final InputQueue inputQueue; protected final InputProxy inputProxy; - - public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) { + public PlayerControllerHuman(final Game game0, final Player p, final LobbyPlayer lp) { super(game0, p, lp); inputProxy = new InputProxy(this); inputQueue = new InputQueue(game, inputProxy); } - public PlayerControllerHuman(Player p, LobbyPlayer lp, PlayerControllerHuman owner) { + public PlayerControllerHuman(final Player p, final LobbyPlayer lp, final PlayerControllerHuman owner) { super(owner.getGame(), p, lp); + gui = owner.gui; inputProxy = owner.inputProxy; inputQueue = owner.getInputQueue(); } + public final IGuiGame getGui() { + return gui; + } + public final void setGui(final IGuiGame gui) { + this.gui = gui; + } + public final InputQueue getInputQueue() { return inputQueue; } @@ -147,7 +157,7 @@ public class PlayerControllerHuman extends PlayerController { } public PlayerView getLocalPlayerView() { - return player.getView(); + return player == null ? null : player.getView(); } public boolean getDisableAutoYields() { @@ -157,12 +167,13 @@ public class PlayerControllerHuman extends PlayerController { disableAutoYields = disableAutoYields0; } + @Override public boolean mayLookAtAllCards() { return mayLookAtAllCards; } private final HashSet tempShownCards = new HashSet(); - public void tempShow(Iterable objects) { + public void tempShow(final Iterable objects) { for (final T t : objects) { if (t instanceof Card) { // assume you may see any card passed through here @@ -170,22 +181,22 @@ public class PlayerControllerHuman extends PlayerController { } } } - private void tempShowCard(Card c) { + private void tempShowCard(final Card c) { if (c == null) { return; } tempShownCards.add(c); c.setMayLookAt(player, true, true); } - private void tempShowCards(Iterable cards) { + private void tempShowCards(final Iterable cards) { if (mayLookAtAllCards) { return; } //no needed if this is set - for (Card c : cards) { + for (final Card c : cards) { tempShowCard(c); } } private void endTempShowCards() { if (tempShownCards.isEmpty()) { return; } - for (Card c : tempShownCards) { + for (final Card c : tempShownCards) { c.setMayLookAt(player, false, true); } tempShownCards.clear(); @@ -202,15 +213,12 @@ public class PlayerControllerHuman extends PlayerController { this.mayLookAtAllCards = mayLookAtAllCards; } - public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) { - return !MatchUtil.getController().stopAtPhase(PlayerView.get(turn), phase); - } - /** * Uses GUI to learn which spell the player (human in our case) would like to play */ public SpellAbility getAbilityToPlay(final List abilities, final ITriggerEvent triggerEvent) { - return MatchUtil.getController().getAbilityToPlay(abilities, triggerEvent); + return getGui().getAbilityToPlay(abilities, triggerEvent); + //return HostedMatch.getController().getAbilityToPlay(abilities, triggerEvent); } @Override @@ -258,11 +266,11 @@ public class PlayerControllerHuman extends PlayerController { else { errMsg = String.format("Too many cards in your sideboard (maximum %d), please make modifications to your deck again.", sbMax); } - SOptionPane.showErrorDialog(errMsg, "Invalid Deck"); + getGui().showErrorDialog(errMsg, "Invalid Deck"); } // Sideboard rules have changed for M14, just need to consider min maindeck and max sideboard sizes // No longer need 1:1 sideboarding in non-limited formats - newMain = GuiBase.getInterface().sideboard(sideboard, main); + newMain = getGui().sideboard(sideboard, main); } while (conform && (newMain.size() < deckMinSize || combinedDeckSize - newMain.size() > sbMax)); return newMain; @@ -283,7 +291,7 @@ public class PlayerControllerHuman extends PlayerController { if ((attacker.hasKeyword("Trample") && defender != null) || (blockers.size() > 1)) { final CardView vAttacker = CardView.get(attacker); final GameEntityView vDefender = GameEntityView.get(defender); - final Map result = MatchUtil.getDamageToAssign(vAttacker, vBlockers, damageDealt, vDefender, overrideOrder); + final Map result = getGui().assignDamage(vAttacker, vBlockers, damageDealt, vDefender, overrideOrder); for (final Entry e : result.entrySet()) { map.put(game.getCard(e.getKey()), e.getValue()); } @@ -298,13 +306,13 @@ public class PlayerControllerHuman extends PlayerController { private final boolean assignDamageAsIfNotBlocked(final Card attacker) { return attacker.hasKeyword("CARDNAME assigns its combat damage as though it weren't blocked.") || (attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.") - && SGuiDialog.confirm(CardView.get(attacker), "Do you want to assign its combat damage as though it weren't blocked?")); + && getGui().confirm(CardView.get(attacker), "Do you want to assign its combat damage as though it weren't blocked?")); } @Override public Integer announceRequirements(SpellAbility ability, String announce, boolean canChooseZero) { int min = canChooseZero ? 0 : 1; - return SGuiChoose.getInteger("Choose " + announce + " for " + ability.getHostCard().getName(), + return getGui().getInteger("Choose " + announce + " for " + ability.getHostCard().getName(), min, Integer.MAX_VALUE, min + 9); } @@ -347,7 +355,7 @@ public class PlayerControllerHuman extends PlayerController { return singleChosen == null ? CardCollection.EMPTY : new CardCollection(singleChosen); } - MatchUtil.getController().setPanelSelection(CardView.get(sa.getHostCard())); + getGui().setPanelSelection(CardView.get(sa.getHostCard())); // try to use InputSelectCardsFromList when possible boolean cardsAreInMyHandOrBattlefield = true; @@ -369,7 +377,7 @@ public class PlayerControllerHuman extends PlayerController { } tempShowCards(sourceList); - final CardCollection choices = getGame().getCardList(SGuiChoose.many(title, "Chosen Cards", min, max, CardView.getCollection(sourceList), CardView.get(sa.getHostCard()))); + final CardCollection choices = getGame().getCardList(getGui().many(title, "Chosen Cards", min, max, CardView.getCollection(sourceList), CardView.get(sa.getHostCard()))); endTempShowCards(); return choices; @@ -417,7 +425,7 @@ public class PlayerControllerHuman extends PlayerController { return Iterables.getFirst(input.getSelected(), null); } - final GameEntityView result = GuiBase.getInterface().chooseSingleEntityForEffect(title, optionList, delayedReveal, isOptional, this); + final GameEntityView result = getGui().chooseSingleEntityForEffect(title, optionList, delayedReveal, isOptional, this); endTempShowCards(); //assume tempShow called by GuiBase.getInterface().chooseSingleEntityForEffect if (result instanceof CardView) { return (T) game.getCard((CardView)result); @@ -437,12 +445,12 @@ public class PlayerControllerHuman extends PlayerController { for (int i = 0; i <= max - min; i++) { choices[i] = Integer.valueOf(i + min); } - return SGuiChoose.one(title, choices).intValue(); + return getGui().one(title, choices).intValue(); } @Override public int chooseNumber(SpellAbility sa, String title, List choices, Player relatedPlayer) { - return SGuiChoose.one(title, choices).intValue(); + return getGui().one(title, choices).intValue(); } @Override @@ -452,7 +460,7 @@ public class PlayerControllerHuman extends PlayerController { } // Human is supposed to read the message and understand from it what to choose - return SGuiChoose.one(title, spells); + return getGui().one(title, spells); } /* (non-Javadoc) @@ -460,26 +468,26 @@ public class PlayerControllerHuman extends PlayerController { */ @Override public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message) { - return SGuiDialog.confirm(CardView.get(sa.getHostCard()), message); + return getGui().confirm(CardView.get(sa.getHostCard()), message); } @Override public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode bidlife, String string, int bid, Player winner) { - return SGuiDialog.confirm(CardView.get(sa.getHostCard()), string + " Highest Bidder " + winner); + return getGui().confirm(CardView.get(sa.getHostCard()), string + " Highest Bidder " + winner); } @Override public boolean confirmStaticApplication(Card hostCard, GameEntity affected, String logic, String message) { - return SGuiDialog.confirm(CardView.get(hostCard), message); + return getGui().confirm(CardView.get(hostCard), message); } @Override public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map triggerParams, boolean isMandatory) { - if (this.shouldAlwaysAcceptTrigger(regtrig.getId())) { + if (getGui().shouldAlwaysAcceptTrigger(regtrig.getId())) { return true; } - if (this.shouldAlwaysDeclineTrigger(regtrig.getId())) { + if (getGui().shouldAlwaysDeclineTrigger(regtrig.getId())) { return false; } @@ -535,22 +543,22 @@ public class PlayerControllerHuman extends PlayerController { @Override public CardCollection orderBlockers(final Card attacker, final CardCollection blockers) { final CardView vAttacker = CardView.get(attacker); - MatchUtil.getController().setPanelSelection(vAttacker); - return game.getCardList(SGuiChoose.order("Choose Damage Order for " + vAttacker, "Damaged First", CardView.getCollection(blockers), vAttacker)); + getGui().setPanelSelection(vAttacker); + return game.getCardList(getGui().order("Choose Damage Order for " + vAttacker, "Damaged First", CardView.getCollection(blockers), vAttacker)); } @Override public CardCollection orderBlocker(final Card attacker, final Card blocker, final CardCollection oldBlockers) { final CardView vAttacker = CardView.get(attacker); - MatchUtil.getController().setPanelSelection(vAttacker); - return game.getCardList(SGuiChoose.insertInList("Choose blocker after which to place " + vAttacker + " in damage order; cancel to place it first", CardView.get(blocker), CardView.getCollection(oldBlockers))); + getGui().setPanelSelection(vAttacker); + return game.getCardList(getGui().insertInList("Choose blocker after which to place " + vAttacker + " in damage order; cancel to place it first", CardView.get(blocker), CardView.getCollection(oldBlockers))); } @Override public CardCollection orderAttackers(final Card blocker, final CardCollection attackers) { final CardView vBlocker = CardView.get(blocker); - MatchUtil.getController().setPanelSelection(vBlocker); - return game.getCardList(SGuiChoose.order("Choose Damage Order for " + vBlocker, "Damaged First", CardView.getCollection(attackers), vBlocker)); + getGui().setPanelSelection(vBlocker); + return game.getCardList(getGui().order("Choose Damage Order for " + vBlocker, "Damaged First", CardView.getCollection(attackers), vBlocker)); } @Override @@ -564,11 +572,11 @@ public class PlayerControllerHuman extends PlayerController { String fm = MessageUtil.formatMessage(message, player, owner); if (!cards.isEmpty()) { tempShowCards(cards); - SGuiChoose.reveal(fm, CardView.getCollection(cards)); + getGui().reveal(fm, CardView.getCollection(cards)); endTempShowCards(); } else { - SGuiDialog.message(MessageUtil.formatMessage("There are no cards in {player's} " + + getGui().message(MessageUtil.formatMessage("There are no cards in {player's} " + zone.name().toLowerCase(), player, owner), fm); } } @@ -588,7 +596,7 @@ public class PlayerControllerHuman extends PlayerController { } } else { - toBottom = game.getCardList(SGuiChoose.many("Select cards to be put on the bottom of your library", "Cards to put on the bottom", -1, CardView.getCollection(topN), null)); + toBottom = game.getCardList(getGui().many("Select cards to be put on the bottom of your library", "Cards to put on the bottom", -1, CardView.getCollection(topN), null)); topN.removeAll((Collection)toBottom); if (topN.isEmpty()) { toTop = null; @@ -597,7 +605,7 @@ public class PlayerControllerHuman extends PlayerController { toTop = topN; } else { - toTop = game.getCardList(SGuiChoose.order("Arrange cards to be put on top of your library", "Top of Library", CardView.getCollection(topN), null)); + toTop = game.getCardList(getGui().order("Arrange cards to be put on top of your library", "Top of Library", CardView.getCollection(topN), null)); } } endTempShowCards(); @@ -609,7 +617,7 @@ public class PlayerControllerHuman extends PlayerController { final CardView view = CardView.get(c); tempShowCard(c); - boolean result = SGuiDialog.confirm(view, "Put " + view + " on the top or bottom of your library?", new String[]{"Top", "Bottom"}); + final boolean result = getGui().confirm(view, "Put " + view + " on the top or bottom of your library?", new String[]{"Top", "Bottom"}); endTempShowCards(); return result; @@ -621,22 +629,22 @@ public class PlayerControllerHuman extends PlayerController { tempShowCards(cards); switch (destinationZone) { case Library: - choices = SGuiChoose.order("Choose order of cards to put into the library", "Closest to top", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of cards to put into the library", "Closest to top", CardView.getCollection(cards), null); break; case Battlefield: - choices = SGuiChoose.order("Choose order of cards to put onto the battlefield", "Put first", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of cards to put onto the battlefield", "Put first", CardView.getCollection(cards), null); break; case Graveyard: - choices = SGuiChoose.order("Choose order of cards to put into the graveyard", "Closest to bottom", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of cards to put into the graveyard", "Closest to bottom", CardView.getCollection(cards), null); break; case PlanarDeck: - choices = SGuiChoose.order("Choose order of cards to put into the planar deck", "Closest to top", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of cards to put into the planar deck", "Closest to top", CardView.getCollection(cards), null); break; case SchemeDeck: - choices = SGuiChoose.order("Choose order of cards to put into the scheme deck", "Closest to top", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of cards to put into the scheme deck", "Closest to top", CardView.getCollection(cards), null); break; case Stack: - choices = SGuiChoose.order("Choose order of copies to cast", "Put first", CardView.getCollection(cards), null); + choices = getGui().order("Choose order of copies to cast", "Put first", CardView.getCollection(cards), null); break; default: System.out.println("ZoneType " + destinationZone + " - Not Ordered"); @@ -651,7 +659,7 @@ public class PlayerControllerHuman extends PlayerController { public CardCollectionView chooseCardsToDiscardFrom(Player p, SpellAbility sa, CardCollection valid, int min, int max) { if (p != player) { tempShowCards(valid); - final CardCollection choices = game.getCardList(SGuiChoose.many("Choose " + min + " card" + (min != 1 ? "s" : "") + " to discard", + final CardCollection choices = game.getCardList(getGui().many("Choose " + min + " card" + (min != 1 ? "s" : "") + " to discard", "Discarded", min, min, CardView.getCollection(valid), null)); endTempShowCards(); return choices; @@ -666,7 +674,7 @@ public class PlayerControllerHuman extends PlayerController { @Override public void playMiracle(final SpellAbility miracle, final Card card) { final CardView view = CardView.get(card); - if (SGuiDialog.confirm(view, view + " - Drawn. Play for Miracle Cost?")) { + if (getGui().confirm(view, view + " - Drawn. Play for Miracle Cost?")) { HumanPlay.playSpellAbility(this, player, miracle); } } @@ -683,9 +691,9 @@ public class PlayerControllerHuman extends PlayerController { cntChoice[i] = Integer.valueOf(i); } - final Integer chosenAmount = SGuiChoose.one("Delve how many cards?", cntChoice); + final Integer chosenAmount = getGui().one("Delve how many cards?", cntChoice); for (int i = 0; i < chosenAmount; i++) { - final CardView nowChosen = SGuiChoose.oneOrNone("Exile which card?", CardView.getCollection(grave)); + final CardView nowChosen = getGui().oneOrNone("Exile which card?", CardView.getCollection(grave)); if (nowChosen == null) { // User canceled,abort delving. @@ -754,7 +762,7 @@ public class PlayerControllerHuman extends PlayerController { Mana m = manaChoices.get(i); options.add(String.format("%d. %s mana from %s", 1+i, MagicColor.toLongString(m.getColor()), m.getSourceCard())); } - String chosen = SGuiChoose.one("Pay Mana from Mana Pool", options); + String chosen = getGui().one("Pay Mana from Mana Pool", options); String idx = TextUtil.split(chosen, '.')[0]; return manaChoices.get(Integer.parseInt(idx)-1); } @@ -769,14 +777,14 @@ public class PlayerControllerHuman extends PlayerController { Iterables.removeAll(types, invalidTypes); } if (isOptional) { - return SGuiChoose.oneOrNone("Choose a " + kindOfType.toLowerCase() + " type", types); + return getGui().oneOrNone("Choose a " + kindOfType.toLowerCase() + " type", types); } - return SGuiChoose.one("Choose a " + kindOfType.toLowerCase() + " type", types); + return getGui().one("Choose a " + kindOfType.toLowerCase() + " type", types); } @Override public Object vote(SpellAbility sa, String prompt, List options, ArrayListMultimap votes) { - return SGuiChoose.one(prompt, options); + return getGui().one(prompt, options); } /* (non-Javadoc) @@ -784,7 +792,7 @@ public class PlayerControllerHuman extends PlayerController { */ @Override public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question) { - return SGuiDialog.confirm(CardView.get(replacementEffect.getHostCard()), question); + return getGui().confirm(CardView.get(replacementEffect.getHostCard()), question); } @Override @@ -795,7 +803,7 @@ public class PlayerControllerHuman extends PlayerController { } @Override - public void declareAttackers(Player attackingPlayer, Combat combat) { + public void declareAttackers(final Player attackingPlayer, final Combat combat) { if (mayAutoPass()) { if (CombatUtil.validateAttackers(combat)) { return; //don't prompt to declare attackers if user chose to end the turn and not attacking is legal @@ -814,41 +822,13 @@ public class PlayerControllerHuman extends PlayerController { // This input should not modify combat object itself, but should return user choice final InputBlock inpBlock = new InputBlock(this, defender, combat); inpBlock.showAndWait(); - updateAutoPassPrompt(); + getGui().updateAutoPassPrompt(); } - public void updateAutoPassPrompt() { - if (mayAutoPass()) { - //allow user to cancel auto-pass - InputBase.cancelAwaitNextInput(); //don't overwrite prompt with awaiting opponent - PhaseType phase = getAutoPassUntilPhase(); - MatchUtil.getController().showPromptMessage(player.getView(), "Yielding until " + (phase == PhaseType.CLEANUP ? "end of turn" : phase.nameForUi.toString()) + - ".\nYou may cancel this yield to take an action."); - ButtonUtil.update(player.getView(), false, true, false); - } - } - - @Override - public void autoPassUntilEndOfTurn() { - super.autoPassUntilEndOfTurn(); - updateAutoPassPrompt(); - } - - @Override - public void autoPassCancel() { - if (getAutoPassUntilPhase() == null) { return; } - super.autoPassCancel(); - - //prevent prompt getting stuck on yielding message while actually waiting for next input opportunity - PlayerView playerView = getLocalPlayerView(); - MatchUtil.getController().showPromptMessage(playerView, ""); - ButtonUtil.update(playerView, false, false, false); - InputBase.awaitNextInput(this); - } @Override public List chooseSpellAbilityToPlay() { - MagicStack stack = game.getStack(); + final MagicStack stack = game.getStack(); if (mayAutoPass()) { //avoid prompting for input if current phase is set to be auto-passed @@ -856,7 +836,7 @@ public class PlayerControllerHuman extends PlayerController { int delay = 0; if (stack.isEmpty()) { //make sure to briefly pause at phases you're not set up to skip - if (!isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn(), game.getPhaseHandler().getPhase())) { + if (!getGui().isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn().getView(), game.getPhaseHandler().getPhase())) { delay = FControlGamePlayback.phasesDelay; } } @@ -876,13 +856,12 @@ public class PlayerControllerHuman extends PlayerController { } if (stack.isEmpty()) { - if (isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn(), game.getPhaseHandler().getPhase())) { + if (getGui().isUiSetToSkipPhase(game.getPhaseHandler().getPlayerTurn().getView(), game.getPhaseHandler().getPhase())) { return null; //avoid prompt for input if stack is empty and player is set to skip the current phase } - } - else if (!game.getDisableAutoYields()) { - SpellAbility ability = stack.peekAbility(); - if (ability != null && ability.isAbility() && shouldAutoYield(ability.toUnsuppressedString())) { + } else { + final SpellAbility ability = stack.peekAbility(); + if (ability != null && ability.isAbility() && getGui().shouldAutoYield(ability.toUnsuppressedString())) { //avoid prompt for input if top ability of stack is set to auto-yield try { Thread.sleep(FControlGamePlayback.resolveDelay); @@ -894,7 +873,7 @@ public class PlayerControllerHuman extends PlayerController { } } - InputPassPriority defaultInput = new InputPassPriority(this, player); + final InputPassPriority defaultInput = new InputPassPriority(this); defaultInput.showAndWait(); return defaultInput.getChosenSa(); } @@ -946,7 +925,7 @@ public class PlayerControllerHuman extends PlayerController { if (srcCards.isEmpty()) { return result; } - final List chosen = SGuiChoose.many("Choose cards to activate from opening hand and their order", "Activate first", -1, CardView.getCollection(srcCards), null); + final List chosen = getGui().many("Choose cards to activate from opening hand and their order", "Activate first", -1, CardView.getCollection(srcCards), null); for (final CardView view : chosen) { final Card c = game.getCard(view); for (SpellAbility sa : usableFromOpeningHand) { @@ -971,7 +950,7 @@ public class PlayerControllerHuman extends PlayerController { case PlayOrDraw: labels = new String[]{"Play", "Draw"}; break; default: labels = kindOfChoice.toString().split("Or"); } - return SGuiDialog.confirm(CardView.get(sa.getHostCard()), question, defaultVal == null || defaultVal.booleanValue(), labels); + return getGui().confirm(CardView.get(sa.getHostCard()), question, defaultVal == null || defaultVal.booleanValue(), labels); } @Override @@ -981,13 +960,13 @@ public class PlayerControllerHuman extends PlayerController { for (int i = 0; i < results.length; i++) { strResults[i] = labelsSrc[results[i] ? 0 : 1]; } - return SGuiChoose.one(sa.getHostCard().getName() + " - Choose a result", strResults).equals(labelsSrc[0]); + return getGui().one(sa.getHostCard().getName() + " - Choose a result", strResults).equals(labelsSrc[0]); } @Override public Card chooseProtectionShield(GameEntity entityBeingDamaged, List options, Map choiceMap) { String title = entityBeingDamaged + " - select which prevention shield to use"; - return choiceMap.get(SGuiChoose.one(title, options)); + return choiceMap.get(getGui().one(title, options)); } @Override @@ -998,12 +977,12 @@ public class PlayerControllerHuman extends PlayerController { } String counterChoiceTitle = "Choose a counter type on " + cardWithCounter; - final CounterType chosen = SGuiChoose.one(counterChoiceTitle, cardWithCounter.getCounters().keySet()); + final CounterType chosen = getGui().one(counterChoiceTitle, cardWithCounter.getCounters().keySet()); String putOrRemoveTitle = "What to do with that '" + chosen.getName() + "' counter "; final String putString = "Put another " + chosen.getName() + " counter on " + cardWithCounter; final String removeString = "Remove a " + chosen.getName() + " counter from " + cardWithCounter; - final String addOrRemove = SGuiChoose.one(putOrRemoveTitle, new String[]{putString,removeString}); + final String addOrRemove = getGui().one(putOrRemoveTitle, new String[]{putString,removeString}); return new ImmutablePair(chosen,addOrRemove); } @@ -1021,7 +1000,7 @@ public class PlayerControllerHuman extends PlayerController { } }; - List> chosen = SGuiChoose.getChoices(saSpellskite.getHostCard().getName(), 1, 1, allTargets, null, fnToString); + List> chosen = getGui().getChoices(saSpellskite.getHostCard().getName(), 1, 1, allTargets, null, fnToString); return Iterables.getFirst(chosen, null); } @@ -1031,7 +1010,7 @@ public class PlayerControllerHuman extends PlayerController { if (sa != null && sa.isManaAbility()) { game.getGameLog().add(GameLogEntryType.LAND, message); } else { - SGuiDialog.message(message, sa == null || sa.getHostCard() == null ? "" : CardView.get(sa.getHostCard()).toString()); + getGui().message(message, sa == null || sa.getHostCard() == null ? "" : CardView.get(sa.getHostCard()).toString()); } } @@ -1048,10 +1027,10 @@ public class PlayerControllerHuman extends PlayerController { for (int i = 0; i < num; i++) { AbilitySub a; if (i < min) { - a = SGuiChoose.one(modeTitle, choices); + a = getGui().one(modeTitle, choices); } else { - a = SGuiChoose.oneOrNone(modeTitle, choices); + a = getGui().oneOrNone(modeTitle, choices); } if (a == null) { break; @@ -1065,7 +1044,7 @@ public class PlayerControllerHuman extends PlayerController { @Override public List chooseColors(String message, SpellAbility sa, int min, int max, List options) { - return SGuiChoose.getChoices(message, min, max, options); + return getGui().getChoices(message, min, max, options); } @Override @@ -1099,9 +1078,9 @@ public class PlayerControllerHuman extends PlayerController { colorNames[i++] = MagicColor.toLongString(b); } if (colorNames.length > 2) { - return MagicColor.fromName(SGuiChoose.one(message, colorNames)); + return MagicColor.fromName(getGui().one(message, colorNames)); } - int idxChosen = SGuiDialog.confirm(CardView.get(c), message, colorNames) ? 0 : 1; + int idxChosen = getGui().confirm(CardView.get(c), message, colorNames) ? 0 : 1; return MagicColor.fromName(colorNames[idxChosen]); } @@ -1110,7 +1089,7 @@ public class PlayerControllerHuman extends PlayerController { Iterable cardsFromDb = FModel.getMagicDb().getCommonCards().getUniqueCards(); List cards = Lists.newArrayList(Iterables.filter(cardsFromDb, cpp)); Collections.sort(cards); - return SGuiChoose.one(message, cards); + return getGui().one(message, cards); } @Override @@ -1118,7 +1097,7 @@ public class PlayerControllerHuman extends PlayerController { if (options.size() <= 1) { return Iterables.getFirst(options, null); } - return SGuiChoose.one(prompt, options); + return getGui().one(prompt, options); } @Override @@ -1133,12 +1112,12 @@ public class PlayerControllerHuman extends PlayerController { if (possibleReplacers.size() == 1) { return possibleReplacers.get(0); } - return SGuiChoose.one(prompt, possibleReplacers); + return getGui().one(prompt, possibleReplacers); } @Override public String chooseProtectionType(String string, SpellAbility sa, List choices) { - return SGuiChoose.one(string, choices); + return getGui().one(string, choices); } @Override @@ -1151,7 +1130,7 @@ public class PlayerControllerHuman extends PlayerController { public void orderAndPlaySimultaneousSa(List activePlayerSAs) { List orderedSAs = activePlayerSAs; if (activePlayerSAs.size() > 1) { // give a dual list form to create instead of needing to do it one at a time - orderedSAs = SGuiChoose.order("Select order for Simultaneous Spell Abilities", "Resolve first", activePlayerSAs, null); + orderedSAs = getGui().order("Select order for Simultaneous Spell Abilities", "Resolve first", activePlayerSAs, null); } int size = orderedSAs.size(); for (int i = size - 1; i >= 0; i--) { @@ -1199,7 +1178,7 @@ public class PlayerControllerHuman extends PlayerController { final String p1Str = String.format("Pile 1 (%s cards)", pile1.size()); final String p2Str = String.format("Pile 2 (%s cards)", pile2.size()); final String[] possibleValues = { p1Str , p2Str }; - return SGuiDialog.confirm(CardView.get(sa.getHostCard()), "Choose a Pile", possibleValues); + return getGui().confirm(CardView.get(sa.getHostCard()), "Choose a Pile", possibleValues); } tempShowCards(pile1); @@ -1217,7 +1196,7 @@ public class PlayerControllerHuman extends PlayerController { // make sure Pile 1 or Pile 2 is clicked on boolean result; while (true) { - final CardView chosen = SGuiChoose.one("Choose a pile", cards); + final CardView chosen = getGui().one("Choose a pile", cards); if (chosen.equals(pileView1)) { result = true; break; @@ -1235,7 +1214,7 @@ public class PlayerControllerHuman extends PlayerController { @Override public void revealAnte(String message, Multimap removedAnteCards) { for (Player p : removedAnteCards.keySet()) { - SGuiChoose.reveal(message + " from " + Lang.getPossessedObject(MessageUtil.mayBeYou(player, p), "deck"), removedAnteCards.get(p)); + getGui().reveal(message + " from " + Lang.getPossessedObject(MessageUtil.mayBeYou(player, p), "deck"), removedAnteCards.get(p)); } } @@ -1248,12 +1227,12 @@ public class PlayerControllerHuman extends PlayerController { for (CardShields shield : c.getShields()) { shields.add(shield); } - return SGuiChoose.one("Choose a regeneration shield:", shields); + return getGui().one("Choose a regeneration shield:", shields); } @Override public List chooseCardsYouWonToAddToDeck(List losses) { - return SGuiChoose.many("Select cards to add to your deck", "Add these to my deck", 0, losses.size(), losses, null); + return getGui().many("Select cards to add to your deck", "Add these to my deck", 0, losses.size(), losses, null); } @Override @@ -1351,7 +1330,7 @@ public class PlayerControllerHuman extends PlayerController { FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { - SOptionPane.showMessageDialog("Cannot pass priority at this time."); + getGui().message("Cannot pass priority at this time."); } }); return false; @@ -1392,8 +1371,8 @@ public class PlayerControllerHuman extends PlayerController { public boolean canPlayUnlimitedLands() { return canPlayUnlimitedLands; } - private DevModeCheats cheats; - public DevModeCheats cheat() { + private IDevModeCheats cheats; + public IDevModeCheats cheat() { if (cheats == null) { cheats = new DevModeCheats(); //TODO: In Network game, inform other players that this player is cheating @@ -1403,25 +1382,37 @@ public class PlayerControllerHuman extends PlayerController { public boolean hasCheated() { return cheats != null; } - public class DevModeCheats { + public class DevModeCheats implements IDevModeCheats { private DevModeCheats() { } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#setCanPlayUnlimitedLands(boolean) + */ + @Override public void setCanPlayUnlimitedLands(boolean canPlayUnlimitedLands0) { canPlayUnlimitedLands = canPlayUnlimitedLands0; } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#setViewAllCards(boolean) + */ + @Override public void setViewAllCards(final boolean canViewAll) { mayLookAtAllCards = canViewAll; for (final Player p : game.getPlayers()) { - MatchUtil.updateCards(CardView.getCollection(p.getAllCards())); + getGui().updateCards(CardView.getCollection(p.getAllCards())); } } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#generateMana() + */ + @Override public void generateMana() { Player pPriority = game.getPhaseHandler().getPriorityPlayer(); if (pPriority == null) { - SGuiDialog.message("No player has priority at the moment, so mana cannot be added to their pool."); + getGui().message("No player has priority at the moment, so mana cannot be added to their pool."); return; } @@ -1444,12 +1435,16 @@ public class PlayerControllerHuman extends PlayerController { }; } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#dumpGameState() + */ + @Override public void dumpGameState() { final GameState state = createGameStateObject(); try { state.initFromGame(game); File f = GuiBase.getInterface().getSaveFile(new File(ForgeConstants.USER_GAMES_DIR, "state.txt")); - if (f != null && (!f.exists() || SOptionPane.showConfirmDialog("Overwrite existing file?"))) { + if (f != null && (!f.exists() || getGui().showConfirmDialog("Overwrite existing file?"))) { final BufferedWriter bw = new BufferedWriter(new FileWriter(f)); bw.write(state.toString()); bw.close(); @@ -1459,11 +1454,15 @@ public class PlayerControllerHuman extends PlayerController { if (e.getMessage() != null) { err += ": " + e.getMessage(); } - SOptionPane.showErrorDialog(err); + getGui().showErrorDialog(err); e.printStackTrace(); } } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#setupGameState() + */ + @Override public void setupGameState() { File gamesDir = new File(ForgeConstants.USER_GAMES_DIR); if (!gamesDir.exists()) { // if the directory does not exist, try to create it @@ -1491,16 +1490,20 @@ public class PlayerControllerHuman extends PlayerController { Player pPriority = game.getPhaseHandler().getPriorityPlayer(); if (pPriority == null) { - SGuiDialog.message("No player has priority at the moment, so game state cannot be setup."); + getGui().message("No player has priority at the moment, so game state cannot be setup."); return; } state.applyToGame(game); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#tutorForCard() + */ + @Override public void tutorForCard() { Player pPriority = game.getPhaseHandler().getPriorityPlayer(); if (pPriority == null) { - SGuiDialog.message("No player has priority at the moment, so their deck can't be tutored from."); + getGui().message("No player has priority at the moment, so their deck can't be tutored from."); return; } @@ -1519,20 +1522,28 @@ public class PlayerControllerHuman extends PlayerController { }); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#addCountersToPermanent() + */ + @Override public void addCountersToPermanent() { final CardCollectionView cards = game.getCardsIn(ZoneType.Battlefield); - final Card card = game.getCard(SGuiChoose.oneOrNone("Add counters to which card?", CardView.getCollection(cards))); + final Card card = game.getCard(getGui().oneOrNone("Add counters to which card?", CardView.getCollection(cards))); if (card == null) { return; } - final CounterType counter = SGuiChoose.oneOrNone("Which type of counter?", CounterType.values()); + final CounterType counter = getGui().oneOrNone("Which type of counter?", CounterType.values()); if (counter == null) { return; } - final Integer count = SGuiChoose.getInteger("How many counters?", 1, Integer.MAX_VALUE, 10); + final Integer count = getGui().getInteger("How many counters?", 1, Integer.MAX_VALUE, 10); if (count == null) { return; } card.addCounter(counter, count, false); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#tapPermanents() + */ + @Override public void tapPermanents() { game.getAction().invoke(new Runnable() { @Override @@ -1551,6 +1562,10 @@ public class PlayerControllerHuman extends PlayerController { }); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#untapPermanents() + */ + @Override public void untapPermanents() { game.getAction().invoke(new Runnable() { @Override @@ -1569,20 +1584,28 @@ public class PlayerControllerHuman extends PlayerController { }); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#setPlayerLife() + */ + @Override public void setPlayerLife() { - final Player player = game.getPlayer(SGuiChoose.oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player player = game.getPlayer(getGui().oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers()))); if (player == null) { return; } - final Integer life = SGuiChoose.getInteger("Set life to what?", 0); + final Integer life = getGui().getInteger("Set life to what?", 0); if (life == null) { return; } player.setLife(life, null); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#winGame() + */ + @Override public void winGame() { Input input = inputQueue.getInput(); if (!(input instanceof InputPassPriority)) { - SOptionPane.showMessageDialog("You must have priority to use this feature.", "Win Game", SOptionPane.INFORMATION_ICON); + getGui().message("You must have priority to use this feature.", "Win Game"); return; } @@ -1599,8 +1622,12 @@ public class PlayerControllerHuman extends PlayerController { input.selectButtonOK(); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#addCardToHand() + */ + @Override public void addCardToHand() { - final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player p = game.getPlayer(getGui().oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers()))); if (p == null) { return; } @@ -1609,7 +1636,7 @@ public class PlayerControllerHuman extends PlayerController { Collections.sort(cards); // use standard forge's list selection dialog - final IPaperCard c = SGuiChoose.oneOrNone("Name the card", cards); + final IPaperCard c = getGui().oneOrNone("Name the card", cards); if (c == null) { return; } @@ -1619,8 +1646,12 @@ public class PlayerControllerHuman extends PlayerController { }}); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#addCardToBattlefield() + */ + @Override public void addCardToBattlefield() { - final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers()))); + final Player p = game.getPlayer(getGui().oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers()))); if (p == null) { return; } @@ -1629,7 +1660,7 @@ public class PlayerControllerHuman extends PlayerController { Collections.sort(cards); // use standard forge's list selection dialog - final IPaperCard c = SGuiChoose.oneOrNone("Name the card", cards); + final IPaperCard c = getGui().oneOrNone("Name the card", cards); if (c == null) { return; } @@ -1654,7 +1685,7 @@ public class PlayerControllerHuman extends PlayerController { sa = choices.iterator().next(); } else { - sa = SGuiChoose.oneOrNone("Choose", (FCollection)choices); + sa = getGui().oneOrNone("Choose", (FCollection)choices); } if (sa == null) { return; // happens if cancelled @@ -1670,11 +1701,15 @@ public class PlayerControllerHuman extends PlayerController { }); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#riggedPlanarRoll() + */ + @Override public void riggedPlanarRoll() { - final Player player = game.getPlayer(SGuiChoose.oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers()))); + final Player player = game.getPlayer(getGui().oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers()))); if (player == null) { return; } - final PlanarDice res = SGuiChoose.oneOrNone("Choose result", PlanarDice.values()); + final PlanarDice res = getGui().oneOrNone("Choose result", PlanarDice.values()); if (res == null) { return; } System.out.println("Rigging planar dice roll: " + res.toString()); @@ -1687,6 +1722,10 @@ public class PlayerControllerHuman extends PlayerController { }); } + /* (non-Javadoc) + * @see forge.player.IDevModeCheats#planeswalkTo() + */ + @Override public void planeswalkTo() { if (!game.getRules().hasAppliedVariant(GameType.Planechase)) { return; } final Player p = game.getPhaseHandler().getPlayerTurn(); @@ -1700,7 +1739,7 @@ public class PlayerControllerHuman extends PlayerController { Collections.sort(allPlanars); // use standard forge's list selection dialog - final IPaperCard c = SGuiChoose.oneOrNone("Name the card", allPlanars); + final IPaperCard c = getGui().oneOrNone("Name the card", allPlanars); if (c == null) { return; } final Card forgeCard = Card.fromPaperCard(c, p); @@ -1714,4 +1753,36 @@ public class PlayerControllerHuman extends PlayerController { }); } } + + @Override + public void concede() { + this.player.concede(); + getGame().getAction().checkGameOverCondition(); + } + public boolean mayAutoPass() { + return getGui().mayAutoPass(getLocalPlayerView()); + } + public void autoPassUntilEndOfTurn() { + getGui().autoPassUntilEndOfTurn(getLocalPlayerView()); + } + @Override + public void autoPassCancel() { + getGui().autoPassCancel(getLocalPlayerView()); + } + public void awaitNextInput() { + getGui().awaitNextInput(); + } + public void cancelAwaitNextInput() { + getGui().cancelAwaitNextInput(); + } + + @Override + public void nextGameDecision(final NextGameDecision decision) { + game.fireEvent(new UiEventNextGameDecision(this, decision)); + } + + @Override + public String getActivateDescription(final CardView card) { + return getInputProxy().getActivateAction(card); + } } diff --git a/forge-gui/src/main/java/forge/player/TargetSelection.java b/forge-gui/src/main/java/forge/player/TargetSelection.java index 790c1890685..e68e54136f5 100644 --- a/forge-gui/src/main/java/forge/player/TargetSelection.java +++ b/forge-gui/src/main/java/forge/player/TargetSelection.java @@ -35,10 +35,8 @@ import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.TargetRestrictions; import forge.game.zone.Zone; import forge.game.zone.ZoneType; -import forge.match.MatchUtil; import forge.match.input.InputSelectTargets; import forge.util.Aggregates; -import forge.util.gui.SGuiChoose; /** *

@@ -137,12 +135,12 @@ public class TargetSelection { for (Card card : validTargets) { playersWithValidTargets.put(PlayerView.get(card.getController()), null); } - if (MatchUtil.getController().openZones(zone, playersWithValidTargets)) { + if (controller.getGui().openZones(zone, playersWithValidTargets)) { InputSelectTargets inp = new InputSelectTargets(controller, validTargets, ability, mandatory); inp.showAndWait(); choiceResult = !inp.hasCancelled(); bTargetingDone = inp.hasPressedOk(); - MatchUtil.getController().restoreOldZones(playersWithValidTargets); + controller.getGui().restoreOldZones(playersWithValidTargets); } else { // for every other case an all-purpose GuiChoose @@ -206,10 +204,10 @@ public class TargetSelection { Object chosen = null; if (!choices.isEmpty() && mandatory) { - chosen = SGuiChoose.one(getTgt().getVTSelection(), choicesFiltered); + chosen = controller.getGui().one(getTgt().getVTSelection(), choicesFiltered); } else { - chosen = SGuiChoose.oneOrNone(getTgt().getVTSelection(), choicesFiltered); + chosen = controller.getGui().oneOrNone(getTgt().getVTSelection(), choicesFiltered); } if (chosen == null) { return false; @@ -258,7 +256,7 @@ public class TargetSelection { return false; } else { - final Object madeChoice = SGuiChoose.oneOrNone(message, selectOptions); + final Object madeChoice = controller.getGui().oneOrNone(message, selectOptions); if (madeChoice == null) { return false; } diff --git a/forge-gui/src/main/java/forge/properties/ForgePreferences.java b/forge-gui/src/main/java/forge/properties/ForgePreferences.java index c45c6f71ac2..8a0636c0b2f 100644 --- a/forge-gui/src/main/java/forge/properties/ForgePreferences.java +++ b/forge-gui/src/main/java/forge/properties/ForgePreferences.java @@ -98,6 +98,7 @@ public class ForgePreferences extends PreferencesStore { ENFORCE_DECK_LEGALITY ("true"), DEV_MODE_ENABLED ("false"), + DEV_WORKSHOP_SYNTAX ("false"), DEV_LOG_ENTRY_TYPE (GameLogEntryType.DAMAGE.toString()), DECK_DEFAULT_CARD_LIMIT ("4"), diff --git a/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java b/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java index 10633dc036f..140c580537c 100644 --- a/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java +++ b/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java @@ -3,69 +3,56 @@ package forge.quest; import java.util.ArrayList; import java.util.List; +import forge.GuiBase; import forge.deck.Deck; import forge.deck.DeckGroup; import forge.deck.DeckSection; -import forge.game.Game; import forge.game.GameRules; import forge.game.GameType; -import forge.game.Match; import forge.game.player.RegisteredPlayer; -import forge.match.MatchUtil; +import forge.interfaces.IGuiGame; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.properties.ForgePreferences.FPref; import forge.util.storage.IStorage; public class QuestDraftUtils { - private static List matchups = new ArrayList(); + private static final List matchups = new ArrayList(); public static boolean matchInProgress = false; public static boolean aiMatchInProgress = false; private static boolean waitForUserInput = false; - public static void continueMatch(final Game lastGame) { - if (lastGame.getMatch().isMatchOver()) { - matchInProgress = false; - } - if (matchInProgress) { - MatchUtil.continueMatch(); - } - else { - MatchUtil.endCurrentGame(); + public static void completeDraft(final DeckGroup finishedDraft) { + + final List aiDecks = new ArrayList(finishedDraft.getAiDecks()); + finishedDraft.getAiDecks().clear(); + + for (int i = 0; i < aiDecks.size(); i++) { + final Deck oldDeck = aiDecks.get(i); + final Deck namedDeck = new Deck("AI Deck " + i); + namedDeck.putSection(DeckSection.Main, oldDeck.get(DeckSection.Main)); + namedDeck.putSection(DeckSection.Sideboard, oldDeck.get(DeckSection.Sideboard)); + finishedDraft.getAiDecks().add(namedDeck); } + + final IStorage draft = FModel.getQuest().getDraftDecks(); + draft.add(finishedDraft); + + FModel.getQuest().save(); + } - - public static void completeDraft(DeckGroup finishedDraft) { - List aiDecks = new ArrayList(finishedDraft.getAiDecks()); - finishedDraft.getAiDecks().clear(); + public static String getDeckLegality() { + final String message = GameType.QuestDraft.getDeckFormat().getDeckConformanceProblem(FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME).getHumanDeck()); + if (message != null && FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { + return message; + } + return null; + } - for (int i = 0; i < aiDecks.size(); i++) { - Deck oldDeck = aiDecks.get(i); - Deck namedDeck = new Deck("AI Deck " + i); - namedDeck.putSection(DeckSection.Main, oldDeck.get(DeckSection.Main)); - namedDeck.putSection(DeckSection.Sideboard, oldDeck.get(DeckSection.Sideboard)); - finishedDraft.getAiDecks().add(namedDeck); - } - - IStorage draft = FModel.getQuest().getDraftDecks(); - draft.add(finishedDraft); - - FModel.getQuest().save(); - - } - - public static String getDeckLegality() { - String message = GameType.QuestDraft.getDeckFormat().getDeckConformanceProblem(FModel.getQuest().getAssets().getDraftDeckStorage().get(QuestEventDraft.DECK_NAME).getHumanDeck()); - if (message != null && FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { - return message; - } - return null; - } - - public static void startNextMatch() { - + public static void startNextMatch(final IGuiGame gui) { if (matchups.size() > 0) { return; } @@ -127,7 +114,7 @@ public class QuestDraftUtils { } - update(); + update(gui); } @@ -148,9 +135,7 @@ public class QuestDraftUtils { } if (humanIndex > -1) { - - matchup.hasHumanPlayer = true; - matchup.matchStarter.add(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); + matchup.setHumanPlayer(new RegisteredPlayer(decks.getHumanDeck()).setPlayer(GamePlayerUtil.getGuiPlayer())); int aiName = Integer.parseInt(draft.getStandings()[aiIndex]) - 1; @@ -173,7 +158,7 @@ public class QuestDraftUtils { matchups.add(matchup); } - public static void update() { + public static void update(final IGuiGame gui) { if (matchups.isEmpty()) { if (!matchInProgress) { aiMatchInProgress = false; @@ -189,39 +174,45 @@ public class QuestDraftUtils { return; } - MatchUtil.getController().enableOverlay(); + gui.enableOverlay(); - DraftMatchup nextMatch = matchups.remove(0); - + final DraftMatchup nextMatch = matchups.remove(0); matchInProgress = true; - - if (!nextMatch.hasHumanPlayer) { - MatchUtil.getController().disableOverlay(); + + if (nextMatch.hasHumanPlayer()) { + waitForUserInput = true; + aiMatchInProgress = false; + } else { + gui.disableOverlay(); waitForUserInput = false; aiMatchInProgress = true; } - else { - waitForUserInput = true; - aiMatchInProgress = false; - } - - GameRules rules = new GameRules(GameType.QuestDraft); + + final GameRules rules = new GameRules(GameType.QuestDraft); rules.setPlayForAnte(false); rules.setMatchAnteRarity(false); rules.setGamesPerMatch(3); rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); - MatchUtil.getController().startNewMatch(new Match(rules, nextMatch.matchStarter)); + final HostedMatch newMatch = GuiBase.getInterface().hostMatch(); + newMatch.startMatch(rules, null, nextMatch.matchStarter, nextMatch.humanPlayer, gui); } - public static void continueMatches() { + public static void continueMatches(final IGuiGame gui) { waitForUserInput = false; - update(); + update(gui); } - private static class DraftMatchup { - private List matchStarter = new ArrayList(); - private boolean hasHumanPlayer = false; + private static final class DraftMatchup { + private final List matchStarter = new ArrayList(); + private RegisteredPlayer humanPlayer = null; + private void setHumanPlayer(final RegisteredPlayer humanPlayer) { + this.matchStarter.add(humanPlayer); + this.humanPlayer = humanPlayer; + } + private boolean hasHumanPlayer() { + return humanPlayer != null; + } } } diff --git a/forge-gui/src/main/java/forge/quest/QuestRewardCard.java b/forge-gui/src/main/java/forge/quest/QuestRewardCard.java index 2ee2689615f..1417d53bfa4 100644 --- a/forge-gui/src/main/java/forge/quest/QuestRewardCard.java +++ b/forge-gui/src/main/java/forge/quest/QuestRewardCard.java @@ -1,22 +1,21 @@ package forge.quest; +import java.util.ArrayList; +import java.util.List; + import com.google.common.base.Predicate; import com.google.common.base.Predicates; import forge.card.CardRules; import forge.item.IPaperCard; -import forge.item.InventoryItem; import forge.item.PaperCard; import forge.model.FModel; -import java.util.ArrayList; -import java.util.List; - /** * TODO: Write javadoc for this type. * */ -public abstract class QuestRewardCard implements InventoryItem, IQuestRewardCard { +public abstract class QuestRewardCard implements IQuestRewardCard { protected String buildDescription(final String [] input) { final String defaultDescription = "a card"; diff --git a/forge-gui/src/main/java/forge/quest/QuestRewardCardChooser.java b/forge-gui/src/main/java/forge/quest/QuestRewardCardChooser.java index 73243d7290a..8441b22ac9b 100644 --- a/forge-gui/src/main/java/forge/quest/QuestRewardCardChooser.java +++ b/forge-gui/src/main/java/forge/quest/QuestRewardCardChooser.java @@ -1,24 +1,23 @@ package forge.quest; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; - -import forge.item.InventoryItem; -import forge.item.PaperCard; -import forge.model.FModel; -import forge.util.ItemPool; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; + +import forge.item.PaperCard; +import forge.model.FModel; +import forge.util.ItemPool; + /** * Resolves a card chooser InventoryItem into a CardPrinted. * The initial version includes "duplicate", other type may be added later. * */ -public class QuestRewardCardChooser extends QuestRewardCard implements InventoryItem { +public class QuestRewardCardChooser extends QuestRewardCard { /** * Possible types for this object. */ diff --git a/forge-gui/src/main/java/forge/quest/QuestRewardCardFiltered.java b/forge-gui/src/main/java/forge/quest/QuestRewardCardFiltered.java index 0c8d9dceebf..4838a517922 100644 --- a/forge-gui/src/main/java/forge/quest/QuestRewardCardFiltered.java +++ b/forge-gui/src/main/java/forge/quest/QuestRewardCardFiltered.java @@ -14,7 +14,7 @@ import java.util.List; * Allows the player to choose a card from a predicate-filtered list of cards. * */ -public class QuestRewardCardFiltered extends QuestRewardCard implements IQuestRewardCard { +public class QuestRewardCardFiltered extends QuestRewardCard { private final String description; private final Predicate predicates; diff --git a/forge-gui/src/main/java/forge/quest/QuestUtil.java b/forge-gui/src/main/java/forge/quest/QuestUtil.java index 3b253ed69b6..7c7428d81ec 100644 --- a/forge-gui/src/main/java/forge/quest/QuestUtil.java +++ b/forge-gui/src/main/java/forge/quest/QuestUtil.java @@ -17,6 +17,13 @@ */ package forge.quest; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.ImmutablePair; + +import com.google.common.collect.ImmutableMap; + import forge.FThreads; import forge.GuiBase; import forge.LobbyPlayer; @@ -27,13 +34,13 @@ import forge.card.CardRules; import forge.deck.Deck; import forge.game.GameRules; import forge.game.GameType; -import forge.game.Match; import forge.game.card.Card; import forge.game.player.RegisteredPlayer; import forge.interfaces.IButton; +import forge.interfaces.IGuiGame; import forge.item.IPaperCard; import forge.item.PaperToken; -import forge.match.MatchUtil; +import forge.match.HostedMatch; import forge.model.FModel; import forge.player.GamePlayerUtil; import forge.properties.ForgePreferences.FPref; @@ -45,10 +52,6 @@ import forge.quest.data.QuestAssets; import forge.quest.data.QuestPreferences.QPref; import forge.util.gui.SGuiChoose; import forge.util.gui.SOptionPane; -import org.apache.commons.lang3.tuple.ImmutablePair; - -import java.util.ArrayList; -import java.util.List; /** *

@@ -540,8 +543,8 @@ public class QuestUtil { forceAnte = qc.isForceAnte(); } - RegisteredPlayer humanStart = new RegisteredPlayer(getDeckForNewGame()); - RegisteredPlayer aiStart = new RegisteredPlayer(event.getEventDeck()); + final RegisteredPlayer humanStart = new RegisteredPlayer(getDeckForNewGame()); + final RegisteredPlayer aiStart = new RegisteredPlayer(event.getEventDeck()); if (lifeHuman != null) { humanStart.setStartingLife(lifeHuman); @@ -555,34 +558,36 @@ public class QuestUtil { aiStart.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event)); } - List starter = new ArrayList<>(); + final List starter = new ArrayList<>(); starter.add(humanStart.setPlayer(GamePlayerUtil.getQuestPlayer())); - LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent()); - GuiBase.getInterface().setPlayerAvatar(aiPlayer, event); + final LobbyPlayer aiPlayer = GamePlayerUtil.createAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent()); starter.add(aiStart.setPlayer(aiPlayer)); - boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); - for(RegisteredPlayer rp : starter) { + final boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); + for (final RegisteredPlayer rp : starter) { rp.setRandomFoil(useRandomFoil); } boolean useAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE); - boolean matchAnteRarity = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY); - if(forceAnte != null) + final boolean matchAnteRarity = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY); + if (forceAnte != null) { useAnte = forceAnte; - GameRules rules = new GameRules(GameType.Quest); + } + final GameRules rules = new GameRules(GameType.Quest); rules.setPlayForAnte(useAnte); rules.setMatchAnteRarity(matchAnteRarity); rules.setGamesPerMatch(qData.getCharmState() ? 5 : 3); rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); - final Match mc = new Match(rules, starter); + final HostedMatch hostedMatch = GuiBase.getInterface().hostMatch(); + final IGuiGame gui = GuiBase.getInterface().getNewGuiGame(); FThreads.invokeInEdtNowOrLater(new Runnable(){ @Override public void run() { - MatchUtil.startGame(mc); + hostedMatch.startMatch(rules, null, starter, ImmutableMap.of(humanStart, gui)); } }); + gui.setPlayerAvatar(aiPlayer, event); } private static Deck getDeckForNewGame() { diff --git a/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java b/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java index d46b71f7a16..09bd055903b 100644 --- a/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java +++ b/forge-gui/src/main/java/forge/quest/io/QuestDataIO.java @@ -361,8 +361,7 @@ public class QuestDataIO { } @SuppressWarnings("unchecked") - private static T readAsset(final XStream xs, final Document doc, final String tagName, final Class clasz) - throws IllegalAccessException, NoSuchFieldException { + private static T readAsset(final XStream xs, final Document doc, final String tagName, final Class clasz) { final NodeList nn = doc.getElementsByTagName(tagName); final Node n = nn.item(0); diff --git a/forge-gui/src/main/java/forge/sound/EventVisualizer.java b/forge-gui/src/main/java/forge/sound/EventVisualizer.java index c7953bc3ad3..457688be546 100644 --- a/forge-gui/src/main/java/forge/sound/EventVisualizer.java +++ b/forge-gui/src/main/java/forge/sound/EventVisualizer.java @@ -6,6 +6,7 @@ import forge.LobbyPlayer; import forge.events.IUiEventVisitor; import forge.events.UiEventAttackerDeclared; import forge.events.UiEventBlockerAssigned; +import forge.events.UiEventNextGameDecision; import forge.game.card.Card; import forge.game.event.GameEvent; import forge.game.event.GameEventBlockersDeclared; @@ -214,6 +215,10 @@ public class EventVisualizer extends IGameEventVisitor.Base imp return null; } @Override + public SoundEffectType visit(UiEventNextGameDecision event) { + return null; + } + @Override public SoundEffectType visit(GameEventCardPhased event) { return SoundEffectType.Phasing; } diff --git a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java index cd5c25c9d3a..0bea4f2ddf4 100644 --- a/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java +++ b/forge-gui/src/main/java/forge/util/gui/SGuiChoose.java @@ -14,9 +14,10 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import forge.GuiBase; -import forge.game.card.CardView; public class SGuiChoose { + public static final String[] defaultConfirmOptions = { "Yes", "No" }; + /** * Convenience for getChoices(message, 0, 1, choices). * @@ -191,18 +192,18 @@ public class SGuiChoose { return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display); } - public static List many(final String title, final String topCaption, int cnt, final List sourceChoices, final CardView referenceCard) { - return many(title, topCaption, cnt, cnt, sourceChoices, referenceCard); + public static List many(final String title, final String topCaption, int cnt, final List sourceChoices) { + return many(title, topCaption, cnt, cnt, sourceChoices); } - public static List many(final String title, final String topCaption, int min, int max, final List sourceChoices, final CardView referenceCard) { + public static List many(final String title, final String topCaption, int min, int max, final List sourceChoices) { int m2 = min >= 0 ? sourceChoices.size() - min : -1; int m1 = max >= 0 ? sourceChoices.size() - max : -1; - return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false); + return order(title, topCaption, m1, m2, sourceChoices, null); } - public static List order(final String title, final String top, final List sourceChoices, final CardView referenceCard) { - return order(title, top, 0, 0, sourceChoices, null, referenceCard, false); + public static List order(final String title, final String top, final List sourceChoices) { + return order(title, top, 0, 0, sourceChoices, null); } /** @@ -216,17 +217,17 @@ public class SGuiChoose { * @return A shallow copy of the list of objects, with newItem inserted. */ public static List insertInList(final String title, final T newItem, final List oldItems) { - final T placeAfter = oneOrNone(title, oldItems); - final int indexAfter = (placeAfter == null ? 0 : oldItems.indexOf(placeAfter) + 1); - final List result = Lists.newArrayListWithCapacity(oldItems.size() + 1); - result.addAll(oldItems); - result.add(indexAfter, newItem); - return result; + final T placeAfter = oneOrNone(title, oldItems); + final int indexAfter = (placeAfter == null ? 0 : oldItems.indexOf(placeAfter) + 1); + final List result = Lists.newArrayListWithCapacity(oldItems.size() + 1); + result.addAll(oldItems); + result.add(indexAfter, newItem); + return result; } private static List order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax, - final List sourceChoices, final List destChoices, final CardView referenceCard, final boolean sideboardingMode) { - return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode); + final List sourceChoices, final List destChoices) { + return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices); } // If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine diff --git a/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java b/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java deleted file mode 100644 index 6033db114c8..00000000000 --- a/forge-gui/src/main/java/forge/util/gui/SGuiDialog.java +++ /dev/null @@ -1,39 +0,0 @@ -package forge.util.gui; - -import org.apache.commons.lang3.StringUtils; - -import forge.game.card.CardView; - -/** - * Holds player interactions using standard windows - * - */ -public class SGuiDialog { - private static final String[] defaultConfirmOptions = { "Yes", "No" }; - - public static boolean confirm(final CardView c, final String question) { - return SGuiDialog.confirm(c, question, true, null); - } - public static boolean confirm(final CardView c, final String question, final boolean defaultChoice) { - return SGuiDialog.confirm(c, question, defaultChoice, null); - } - public static boolean confirm(final CardView c, final String question, String[] options) { - return SGuiDialog.confirm(c, question, true, options); - } - - public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) { - final String title = c == null ? "Question" : c + " - Ability"; - String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question; - String[] opts = options == null ? defaultConfirmOptions : options; - int answer = SOptionPane.showCardOptionDialog(c, questionToUse, title, SOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1); - return answer == 0; - } - - public static void message(final String message) { - message(message, "Forge"); - } - - public static void message(final String message, final String title) { - SOptionPane.showMessageDialog(message, title, null); - } -} diff --git a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java index 09c5742fe13..efbb025e498 100644 --- a/forge-gui/src/main/java/forge/util/gui/SOptionPane.java +++ b/forge-gui/src/main/java/forge/util/gui/SOptionPane.java @@ -2,7 +2,6 @@ package forge.util.gui; import forge.GuiBase; import forge.assets.FSkinProp; -import forge.game.card.CardView; public class SOptionPane { public static final FSkinProp QUESTION_ICON = FSkinProp.ICO_QUESTION; @@ -60,10 +59,6 @@ public class SOptionPane { return GuiBase.getInterface().showOptionDialog(message, title, icon, options, defaultOption); } - public static int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption) { - return GuiBase.getInterface().showCardOptionDialog(card, message, title, icon, options, defaultOption); - } - public static String showInputDialog(String message, String title) { return showInputDialog(message, title, null, "", null); }