diff --git a/d2game/d2gamescreen/navigate.go b/d2common/d2interface/navigate.go similarity index 96% rename from d2game/d2gamescreen/navigate.go rename to d2common/d2interface/navigate.go index 422c1376..72e03538 100644 --- a/d2game/d2gamescreen/navigate.go +++ b/d2common/d2interface/navigate.go @@ -1,4 +1,4 @@ -package d2gamescreen +package d2interface import ( "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client/d2clientconnectiontype" diff --git a/d2core/d2gui/layout.go b/d2core/d2gui/layout.go index 88b4b99a..3092e537 100644 --- a/d2core/d2gui/layout.go +++ b/d2core/d2gui/layout.go @@ -268,6 +268,10 @@ func (l *Layout) getContentSize() (width, height int) { return width, height } +func (l *Layout) GetSize() (width, height int) { + return l.getSize() +} + func (l *Layout) getSize() (width, height int) { width, height = l.getContentSize() return d2math.MaxInt(width, l.width), d2math.MaxInt(height, l.height) diff --git a/d2game/d2gamescreen/character_select.go b/d2game/d2gamescreen/character_select.go index b5fff2f6..f2dfc225 100644 --- a/d2game/d2gamescreen/character_select.go +++ b/d2game/d2gamescreen/character_select.go @@ -54,12 +54,12 @@ type CharacterSelect struct { inputManager d2interface.InputManager audioProvider d2interface.AudioProvider renderer d2interface.Renderer - navigator Navigator + navigator d2interface.Navigator } // CreateCharacterSelect creates the character select screen and returns a pointer to it func CreateCharacterSelect( - navigator Navigator, + navigator d2interface.Navigator, asset *d2asset.AssetManager, renderer d2interface.Renderer, inputManager d2interface.InputManager, diff --git a/d2game/d2gamescreen/credits.go b/d2game/d2gamescreen/credits.go index a2f78da7..0cf4b100 100644 --- a/d2game/d2gamescreen/credits.go +++ b/d2game/d2gamescreen/credits.go @@ -41,12 +41,12 @@ type Credits struct { asset *d2asset.AssetManager renderer d2interface.Renderer - navigator Navigator + navigator d2interface.Navigator uiManager *d2ui.UIManager } // CreateCredits creates an instance of the credits screen -func CreateCredits(navigator Navigator, asset *d2asset.AssetManager, renderer d2interface.Renderer, +func CreateCredits(navigator d2interface.Navigator, asset *d2asset.AssetManager, renderer d2interface.Renderer, ui *d2ui.UIManager) *Credits { result := &Credits{ asset: asset, diff --git a/d2game/d2gamescreen/game.go b/d2game/d2gamescreen/game.go index f2f67120..2bf7b0d0 100644 --- a/d2game/d2gamescreen/game.go +++ b/d2game/d2gamescreen/game.go @@ -42,7 +42,7 @@ type Game struct { localPlayer *d2mapentity.Player lastRegionType d2enum.RegionIdType ticksSinceLevelCheck float64 - escapeMenu *EscapeMenu + escapeMenu *d2player.EscapeMenu soundEngine *d2audio.SoundEngine soundEnv d2audio.SoundEnvironment guiManager *d2gui.GuiManager @@ -55,7 +55,7 @@ type Game struct { // CreateGame creates the Gameplay screen and returns a pointer to it func CreateGame( - navigator Navigator, + navigator d2interface.Navigator, asset *d2asset.AssetManager, ui *d2ui.UIManager, renderer d2interface.Renderer, @@ -88,7 +88,7 @@ func CreateGame( ticksSinceLevelCheck: 0, mapRenderer: d2maprenderer.CreateMapRenderer(asset, renderer, gameClient.MapEngine, term, startX, startY), - escapeMenu: NewEscapeMenu(navigator, renderer, audioProvider, guiManager, asset), + escapeMenu: d2player.NewEscapeMenu(navigator, renderer, audioProvider, guiManager, asset), inputManager: inputManager, audioProvider: audioProvider, renderer: renderer, @@ -99,7 +99,7 @@ func CreateGame( } result.soundEnv = d2audio.NewSoundEnvironment(result.soundEngine) - result.escapeMenu.onLoad() + result.escapeMenu.OnLoad() if err := inputManager.BindHandler(result.escapeMenu); err != nil { fmt.Println("failed to add gameplay screen as event handler") @@ -219,7 +219,7 @@ func (v *Game) Render(screen d2interface.Surface) error { func (v *Game) Advance(elapsed float64) error { v.soundEngine.Advance(elapsed) - if (v.escapeMenu != nil && !v.escapeMenu.isOpen) || len(v.gameClient.Players) != 1 { + if (v.escapeMenu != nil && !v.escapeMenu.IsOpen()) || len(v.gameClient.Players) != 1 { v.gameClient.MapEngine.Advance(elapsed) // TODO: Hack } @@ -285,7 +285,7 @@ func (v *Game) bindGameControls() error { var err error v.gameControls, err = d2player.NewGameControls(v.asset, v.renderer, player, v.gameClient.MapEngine, - v.mapRenderer, v, v.terminal, v.uiManager, v.guiManager, v.gameClient.IsSinglePlayer()) + v.escapeMenu, v.mapRenderer, v, v.terminal, v.uiManager, v.guiManager, v.gameClient.IsSinglePlayer()) if err != nil { return err diff --git a/d2game/d2gamescreen/main_menu.go b/d2game/d2gamescreen/main_menu.go index b1405a8c..3ad79664 100644 --- a/d2game/d2gamescreen/main_menu.go +++ b/d2game/d2gamescreen/main_menu.go @@ -117,7 +117,7 @@ type MainMenu struct { renderer d2interface.Renderer audioProvider d2interface.AudioProvider scriptEngine *d2script.ScriptEngine - navigator Navigator + navigator d2interface.Navigator uiManager *d2ui.UIManager heroState *d2hero.HeroStateFactory @@ -126,7 +126,7 @@ type MainMenu struct { // CreateMainMenu creates an instance of MainMenu func CreateMainMenu( - navigator Navigator, + navigator d2interface.Navigator, asset *d2asset.AssetManager, renderer d2interface.Renderer, inputManager d2interface.InputManager, diff --git a/d2game/d2gamescreen/select_hero_class.go b/d2game/d2gamescreen/select_hero_class.go index 2c26a8e2..5da09ac1 100644 --- a/d2game/d2gamescreen/select_hero_class.go +++ b/d2game/d2gamescreen/select_hero_class.go @@ -297,12 +297,12 @@ type SelectHeroClass struct { audioProvider d2interface.AudioProvider renderer d2interface.Renderer - navigator Navigator + navigator d2interface.Navigator } // CreateSelectHeroClass creates an instance of a SelectHeroClass func CreateSelectHeroClass( - navigator Navigator, + navigator d2interface.Navigator, asset *d2asset.AssetManager, renderer d2interface.Renderer, audioProvider d2interface.AudioProvider, diff --git a/d2game/d2gamescreen/escape_menu.go b/d2game/d2player/escape_menu.go similarity index 98% rename from d2game/d2gamescreen/escape_menu.go rename to d2game/d2player/escape_menu.go index 04ab31fb..384e1a4d 100644 --- a/d2game/d2gamescreen/escape_menu.go +++ b/d2game/d2player/escape_menu.go @@ -1,4 +1,4 @@ -package d2gamescreen +package d2player import ( "fmt" @@ -71,7 +71,7 @@ type EscapeMenu struct { renderer d2interface.Renderer audioProvider d2interface.AudioProvider - navigator Navigator + navigator d2interface.Navigator guiManager *d2gui.GuiManager assetManager *d2asset.AssetManager } @@ -127,7 +127,7 @@ type actionableElement interface { } // NewEscapeMenu creates a new escape menu -func NewEscapeMenu(navigator Navigator, +func NewEscapeMenu(navigator d2interface.Navigator, renderer d2interface.Renderer, audioProvider d2interface.AudioProvider, guiManager *d2gui.GuiManager, @@ -351,7 +351,7 @@ func (m *EscapeMenu) addEnumLabel(l *layout, optID optionID, text string, values l.actionableElements = append(l.actionableElements, label) } -func (m *EscapeMenu) onLoad() { +func (m *EscapeMenu) OnLoad() { var err error m.selectSound, err = m.audioProvider.LoadSound(d2resource.SFXCursorSelect, false, false) if err != nil { @@ -359,12 +359,7 @@ func (m *EscapeMenu) onLoad() { } } -func (m *EscapeMenu) onEscKey() { - if !m.isOpen { - m.open() - return - } - +func (m *EscapeMenu) OnEscKey() { switch m.currentLayout { case optionsLayoutID: m.setLayout(mainLayoutID) @@ -466,11 +461,13 @@ func (m *EscapeMenu) onEnterKey() { m.layouts[m.currentLayout].actionableElements[m.layouts[m.currentLayout].currentEl].Trigger() } +func (m *EscapeMenu) IsOpen() bool { + return m.isOpen +} + // OnKeyDown defines the actions of the Escape Menu when a key is pressed func (m *EscapeMenu) OnKeyDown(event d2interface.KeyEvent) bool { switch event.Key() { - case d2enum.KeyEscape: - m.onEscKey() case d2enum.KeyUp: m.onUpKey() case d2enum.KeyDown: diff --git a/d2game/d2player/game_controls.go b/d2game/d2player/game_controls.go index 81974666..b7dad9f9 100644 --- a/d2game/d2player/game_controls.go +++ b/d2game/d2player/game_controls.go @@ -55,6 +55,7 @@ type GameControls struct { heroState *d2hero.HeroStateFactory mapEngine *d2mapengine.MapEngine mapRenderer *d2maprenderer.MapRenderer + escapeMenu *EscapeMenu ui *d2ui.UIManager inventory *Inventory heroStatsPanel *HeroStatsPanel @@ -122,11 +123,13 @@ func NewGameControls( renderer d2interface.Renderer, hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, + escapeMenu *EscapeMenu, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener, term d2interface.Terminal, ui *d2ui.UIManager, guiManager *d2gui.GuiManager, + isSinglePlayer bool, ) (*GameControls, error) { @@ -181,6 +184,7 @@ func NewGameControls( hero: hero, heroState: heroState, mapEngine: mapEngine, + escapeMenu: escapeMenu, inputListener: inputListener, mapRenderer: mapRenderer, inventory: NewInventory(asset, ui, inventoryRecord), @@ -293,13 +297,8 @@ func (g *GameControls) OnKeyRepeat(event d2interface.KeyEvent) bool { func (g *GameControls) OnKeyDown(event d2interface.KeyEvent) bool { switch event.Key() { case d2enum.KeyEscape: - if g.inventory.IsOpen() || g.heroStatsPanel.IsOpen() { - g.inventory.Close() - g.heroStatsPanel.Close() - g.updateLayout() - - break - } + g.onEscKey() + break case d2enum.KeyI: g.inventory.Toggle() g.updateLayout() @@ -330,6 +329,35 @@ func (g *GameControls) OnKeyUp(event d2interface.KeyEvent) bool { return false } +func (g *GameControls) onEscKey() { + // When escape is pressed: + // 1. If there was some overlay or panel open, close it + // 2. Otherwise, if the Escape Menu was open, let the Escape Menu handle it + // 3. If nothing was open, open the Escape Menu + + escHandled := false + if g.inventory.IsOpen() { + g.inventory.Close() + escHandled = true + } + if g.heroStatsPanel.IsOpen() { + g.heroStatsPanel.Close() + escHandled = true + } + if g.HelpOverlay.IsOpen() { + g.HelpOverlay.Toggle() + escHandled = true + } + + if escHandled { + g.updateLayout() + } else if g.escapeMenu.isOpen { + g.escapeMenu.OnEscKey() + } else { + g.escapeMenu.open() + } +} + // OnMouseButtonRepeat handles repeated mouse clicks func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool { px, py := g.mapRenderer.ScreenToWorld(event.X(), event.Y()) @@ -557,6 +585,10 @@ func (g *GameControls) isInActiveMenusRect(px, py int) bool { return true } + if g.escapeMenu.IsOpen() { + return true + } + if g.HelpOverlay.IsOpen() && g.HelpOverlay.IsInRect(px, py) { return true } diff --git a/d2game/d2player/help/help.go b/d2game/d2player/help/help.go index a16fc3e1..91f1aff1 100644 --- a/d2game/d2player/help/help.go +++ b/d2game/d2player/help/help.go @@ -56,11 +56,6 @@ func NewHelpOverlay( return h } -func (h *Overlay) onMouseDown() { - // If mouse over close button - // close() -} - func (h *Overlay) Toggle() { fmt.Print("Help overlay toggled\n") if h.isOpen { @@ -93,8 +88,9 @@ func (h *Overlay) IsOpen() bool { } func (h *Overlay) IsInRect(px, py int) bool { - ww, hh := h.closeButton.GetSize() - x, y := h.closeButton.GetPosition() + + ww, hh := h.layout.GetSize() + x, y := h.layout.GetPosition() if px >= x && px <= x+ww && py >= y && py <= y+hh { return true