1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-07-01 11:25:26 +00:00

Help and Escape Menu click through and close behavior (#761)

* Disallow clicking through the help menu to control the game

* Move Navigator and EscapeMenu up in package tree to be accessible by GameControls. Disallow GameControls input when EscapeMenu is open

* Make ESC key behavior more consistent with D2
This commit is contained in:
Josh Jordan 2020-10-07 21:20:05 -04:00 committed by GitHub
parent 2e42fcee15
commit b1cdb47302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 41 deletions

View File

@ -1,4 +1,4 @@
package d2gamescreen
package d2interface
import (
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client/d2clientconnectiontype"

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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:

View File

@ -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
}

View File

@ -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