2019-12-16 11:04:39 -05:00
|
|
|
package d2player
|
|
|
|
|
|
|
|
import (
|
2020-02-23 03:23:18 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
2020-02-22 20:44:30 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
2020-01-26 00:39:13 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
2020-02-01 18:55:56 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
2020-01-31 23:18:11 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
2020-02-01 18:55:56 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map"
|
2020-02-01 20:39:28 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
2020-02-22 20:44:30 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
2020-02-01 18:55:56 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
2019-12-16 11:04:39 -05:00
|
|
|
)
|
|
|
|
|
2019-12-28 23:32:53 -05:00
|
|
|
type Panel interface {
|
|
|
|
IsOpen() bool
|
|
|
|
Toggle()
|
|
|
|
Open()
|
|
|
|
Close()
|
|
|
|
}
|
|
|
|
|
2020-02-22 20:44:30 -05:00
|
|
|
// ID of missile to create when user right clicks.
|
|
|
|
var missileID = 59
|
|
|
|
|
2019-12-16 11:04:39 -05:00
|
|
|
type GameControls struct {
|
2020-06-18 14:11:04 -04:00
|
|
|
hero *d2map.Player
|
|
|
|
mapEngine *d2map.MapEngine
|
|
|
|
mapRenderer *d2map.MapRenderer
|
|
|
|
inventory *Inventory
|
|
|
|
heroStats *HeroStats
|
|
|
|
inputListener InputCallbackListener
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
// UI
|
2020-02-01 18:55:56 -05:00
|
|
|
globeSprite *d2ui.Sprite
|
|
|
|
mainPanel *d2ui.Sprite
|
|
|
|
menuButton *d2ui.Sprite
|
|
|
|
skillIcon *d2ui.Sprite
|
2019-12-16 11:04:39 -05:00
|
|
|
}
|
|
|
|
|
2020-06-18 14:11:04 -04:00
|
|
|
func NewGameControls(hero *d2map.Player, mapEngine *d2map.MapEngine, mapRenderer *d2map.MapRenderer, inputListener InputCallbackListener) *GameControls {
|
2020-02-22 20:44:30 -05:00
|
|
|
d2term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
|
|
|
missileID = id
|
|
|
|
})
|
|
|
|
|
2019-12-16 11:04:39 -05:00
|
|
|
return &GameControls{
|
2020-06-18 14:11:04 -04:00
|
|
|
hero: hero,
|
|
|
|
mapEngine: mapEngine,
|
|
|
|
inputListener: inputListener,
|
|
|
|
mapRenderer: mapRenderer,
|
|
|
|
inventory: NewInventory(),
|
|
|
|
heroStats: NewHeroStats(),
|
2019-12-16 11:04:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 23:28:21 -05:00
|
|
|
func (g *GameControls) OnKeyDown(event d2input.KeyEvent) bool {
|
|
|
|
if event.Key == d2input.KeyI {
|
|
|
|
g.inventory.Toggle()
|
2020-06-21 15:26:07 -04:00
|
|
|
g.updateLayout()
|
2020-01-25 23:28:21 -05:00
|
|
|
return true
|
2019-12-16 11:04:39 -05:00
|
|
|
}
|
2020-02-08 10:51:11 -05:00
|
|
|
if event.Key == d2input.KeyC {
|
|
|
|
g.heroStats.Toggle()
|
2020-06-21 15:26:07 -04:00
|
|
|
g.updateLayout()
|
2020-02-08 10:51:11 -05:00
|
|
|
return true
|
|
|
|
}
|
2019-12-16 11:04:39 -05:00
|
|
|
|
2020-01-25 23:28:21 -05:00
|
|
|
return false
|
|
|
|
}
|
2019-12-16 11:04:39 -05:00
|
|
|
|
2020-06-21 15:26:07 -04:00
|
|
|
func (g *GameControls) updateLayout() {
|
|
|
|
isRightPanelOpen := false
|
|
|
|
isLeftPanelOpen := false
|
|
|
|
|
|
|
|
// todo : add same logic when adding quest log and skill tree
|
|
|
|
isRightPanelOpen = g.inventory.isOpen || isRightPanelOpen
|
|
|
|
isLeftPanelOpen = g.heroStats.isOpen || isLeftPanelOpen
|
|
|
|
|
|
|
|
if isRightPanelOpen == isLeftPanelOpen {
|
|
|
|
g.mapRenderer.ViewportDefault()
|
|
|
|
} else if isRightPanelOpen == true {
|
|
|
|
g.mapRenderer.ViewportToLeft()
|
|
|
|
} else {
|
|
|
|
g.mapRenderer.ViewportToRight()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 23:28:21 -05:00
|
|
|
func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
2020-06-13 18:32:09 -04:00
|
|
|
px, py := g.mapRenderer.ScreenToWorld(event.X, event.Y)
|
2020-02-22 20:44:30 -05:00
|
|
|
px = float64(int(px*10)) / 10.0
|
|
|
|
py = float64(int(py*10)) / 10.0
|
|
|
|
|
2020-01-25 23:28:21 -05:00
|
|
|
if event.Button == d2input.MouseButtonLeft {
|
2020-06-18 14:11:04 -04:00
|
|
|
g.inputListener.OnPlayerMove(px, py)
|
2020-02-22 20:44:30 -05:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if event.Button == d2input.MouseButtonRight {
|
|
|
|
missile, err := d2map.CreateMissile(
|
|
|
|
int(g.hero.AnimatedComposite.LocationX),
|
|
|
|
int(g.hero.AnimatedComposite.LocationY),
|
|
|
|
d2datadict.Missiles[missileID],
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
2020-02-02 12:46:19 -05:00
|
|
|
}
|
2020-02-22 20:44:30 -05:00
|
|
|
|
2020-02-23 03:23:18 -05:00
|
|
|
rads := d2common.GetRadiansBetween(
|
|
|
|
g.hero.AnimatedComposite.LocationX,
|
|
|
|
g.hero.AnimatedComposite.LocationY,
|
|
|
|
px*5,
|
|
|
|
py*5,
|
|
|
|
)
|
|
|
|
missile.SetRadians(rads, func() {
|
2020-02-22 20:44:30 -05:00
|
|
|
g.mapEngine.RemoveEntity(missile)
|
|
|
|
})
|
|
|
|
|
|
|
|
g.mapEngine.AddEntity(missile)
|
2020-01-25 23:28:21 -05:00
|
|
|
return true
|
2019-12-28 23:32:53 -05:00
|
|
|
}
|
2020-02-22 20:44:30 -05:00
|
|
|
|
2020-01-25 23:28:21 -05:00
|
|
|
return false
|
2019-12-16 11:04:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GameControls) Load() {
|
2020-02-01 18:55:56 -05:00
|
|
|
animation, _ := d2asset.LoadAnimation(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
|
|
|
|
g.globeSprite, _ = d2ui.LoadSprite(animation)
|
2020-01-31 23:18:11 -05:00
|
|
|
|
2020-02-01 18:55:56 -05:00
|
|
|
animation, _ = d2asset.LoadAnimation(d2resource.GamePanels, d2resource.PaletteSky)
|
|
|
|
g.mainPanel, _ = d2ui.LoadSprite(animation)
|
2020-01-31 23:18:11 -05:00
|
|
|
|
2020-02-01 18:55:56 -05:00
|
|
|
animation, _ = d2asset.LoadAnimation(d2resource.MenuButton, d2resource.PaletteSky)
|
|
|
|
g.menuButton, _ = d2ui.LoadSprite(animation)
|
2020-01-31 23:18:11 -05:00
|
|
|
|
2020-02-01 18:55:56 -05:00
|
|
|
animation, _ = d2asset.LoadAnimation(d2resource.GenericSkills, d2resource.PaletteSky)
|
|
|
|
g.skillIcon, _ = d2ui.LoadSprite(animation)
|
2020-01-31 23:18:11 -05:00
|
|
|
|
2019-12-28 23:32:53 -05:00
|
|
|
g.inventory.Load()
|
2020-02-08 10:51:11 -05:00
|
|
|
g.heroStats.Load()
|
2019-12-16 11:04:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: consider caching the panels to single image that is reused.
|
2020-02-01 20:39:28 -05:00
|
|
|
func (g *GameControls) Render(target d2render.Surface) {
|
2019-12-28 23:32:53 -05:00
|
|
|
g.inventory.Render(target)
|
2020-02-08 10:51:11 -05:00
|
|
|
g.heroStats.Render(target)
|
2019-12-28 23:32:53 -05:00
|
|
|
|
2019-12-28 16:46:08 -05:00
|
|
|
width, height := target.GetSize()
|
2020-02-01 21:51:49 -05:00
|
|
|
offset := 0
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
// Left globe holder
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(0)
|
|
|
|
w, _ := g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
// Left globe
|
2019-12-21 20:53:18 -05:00
|
|
|
g.globeSprite.SetCurrentFrame(0)
|
2019-12-28 23:32:53 -05:00
|
|
|
g.globeSprite.SetPosition(offset+28, height-5)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.globeSprite.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Left skill
|
2019-12-21 20:53:18 -05:00
|
|
|
g.skillIcon.SetCurrentFrame(2)
|
|
|
|
w, _ = g.skillIcon.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.skillIcon.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.skillIcon.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Left skill selector
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(1)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Stamina
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(2)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Center menu button
|
2019-12-21 20:53:18 -05:00
|
|
|
g.menuButton.SetCurrentFrame(0)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
|
|
|
g.menuButton.SetPosition((width/2)-8, height-16)
|
|
|
|
g.menuButton.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
// Potions
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(3)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Right skill selector
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(4)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Right skill
|
2019-12-21 20:53:18 -05:00
|
|
|
g.skillIcon.SetCurrentFrame(10)
|
|
|
|
w, _ = g.skillIcon.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.skillIcon.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.skillIcon.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
offset += w
|
|
|
|
|
|
|
|
// Right globe holder
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.SetCurrentFrame(5)
|
|
|
|
w, _ = g.mainPanel.GetCurrentFrameSize()
|
2019-12-28 23:32:53 -05:00
|
|
|
g.mainPanel.SetPosition(offset, height)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.mainPanel.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
// Right globe
|
2019-12-21 20:53:18 -05:00
|
|
|
g.globeSprite.SetCurrentFrame(1)
|
2019-12-28 23:32:53 -05:00
|
|
|
g.globeSprite.SetPosition(offset+8, height-8)
|
2019-12-21 20:53:18 -05:00
|
|
|
g.globeSprite.Render(target)
|
2019-12-16 11:04:39 -05:00
|
|
|
|
|
|
|
}
|