2020-06-14 00:36:20 +00:00
|
|
|
package d2gamescreen
|
2019-11-12 04:48:55 +00:00
|
|
|
|
|
|
|
import (
|
2020-06-22 19:55:32 +00:00
|
|
|
"fmt"
|
2019-12-22 01:53:18 +00:00
|
|
|
"image/color"
|
|
|
|
|
2020-06-24 22:46:03 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
|
|
|
|
|
2020-06-22 19:55:32 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
2020-06-19 06:19:27 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
2020-06-13 22:32:09 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
2020-06-22 19:55:32 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
2020-02-02 01:39:28 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
2020-06-21 22:40:37 +00:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
|
2019-11-12 04:48:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Game struct {
|
2020-06-19 06:19:27 +00:00
|
|
|
gameClient *d2client.GameClient
|
2020-06-26 20:50:24 +00:00
|
|
|
MapRenderer *d2maprenderer.MapRenderer
|
2020-06-19 06:19:27 +00:00
|
|
|
gameControls *d2player.GameControls // TODO: Hack
|
2020-06-21 22:40:37 +00:00
|
|
|
localPlayer *d2mapentity.Player
|
2020-06-22 19:55:32 +00:00
|
|
|
lastRegionType d2enum.RegionIdType
|
2020-06-19 06:19:27 +00:00
|
|
|
ticksSinceLevelCheck float64
|
2020-06-25 14:16:17 +00:00
|
|
|
escapeMenu *EscapeMenu
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
|
|
|
|
2020-06-13 22:32:09 +00:00
|
|
|
func CreateGame(gameClient *d2client.GameClient) *Game {
|
2020-06-21 22:40:37 +00:00
|
|
|
result := &Game{
|
2020-06-19 06:19:27 +00:00
|
|
|
gameClient: gameClient,
|
|
|
|
gameControls: nil,
|
|
|
|
localPlayer: nil,
|
2020-06-22 19:55:32 +00:00
|
|
|
lastRegionType: d2enum.RegionNone,
|
2020-06-19 06:19:27 +00:00
|
|
|
ticksSinceLevelCheck: 0,
|
2020-06-26 20:50:24 +00:00
|
|
|
MapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
|
2020-06-25 14:16:17 +00:00
|
|
|
escapeMenu: NewEscapeMenu(),
|
2020-06-13 22:32:09 +00:00
|
|
|
}
|
2020-06-25 14:16:17 +00:00
|
|
|
result.escapeMenu.OnLoad()
|
|
|
|
d2input.BindHandler(result.escapeMenu)
|
2020-06-21 22:40:37 +00:00
|
|
|
return result
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:46:03 +00:00
|
|
|
func (v *Game) OnLoad(loading d2screen.LoadingState) {
|
2020-06-19 06:19:27 +00:00
|
|
|
d2audio.PlayBGM("")
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 02:02:37 +00:00
|
|
|
func (v *Game) OnUnload() error {
|
2020-06-13 22:32:09 +00:00
|
|
|
d2input.UnbindHandler(v.gameControls) // TODO: hack
|
2020-06-25 14:16:17 +00:00
|
|
|
v.gameClient.Close()
|
2020-02-09 02:02:37 +00:00
|
|
|
return nil
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 02:02:37 +00:00
|
|
|
func (v *Game) Render(screen d2render.Surface) error {
|
2020-06-21 22:40:37 +00:00
|
|
|
if v.gameClient.RegenMap {
|
|
|
|
v.gameClient.RegenMap = false
|
2020-06-26 20:50:24 +00:00
|
|
|
v.MapRenderer.RegenerateTileCache()
|
2020-06-21 22:40:37 +00:00
|
|
|
}
|
2020-06-25 04:39:09 +00:00
|
|
|
|
2020-06-26 20:50:24 +00:00
|
|
|
if v.MapRenderer != nil {
|
|
|
|
screen.Clear(color.Black)
|
|
|
|
v.MapRenderer.Render(screen)
|
|
|
|
}
|
2020-06-25 04:39:09 +00:00
|
|
|
|
2020-06-13 22:32:09 +00:00
|
|
|
if v.gameControls != nil {
|
|
|
|
v.gameControls.Render(screen)
|
|
|
|
}
|
2020-06-25 04:39:09 +00:00
|
|
|
|
2020-02-09 02:02:37 +00:00
|
|
|
return nil
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 20:50:24 +00:00
|
|
|
var zoneTextDuration = 2.0 // seconds
|
2020-06-22 19:55:32 +00:00
|
|
|
|
2020-02-09 02:02:37 +00:00
|
|
|
func (v *Game) Advance(tickTime float64) error {
|
2020-06-25 14:16:17 +00:00
|
|
|
if (v.escapeMenu != nil && !v.escapeMenu.IsOpen()) || len(v.gameClient.Players) != 1 {
|
2020-06-21 20:06:52 +00:00
|
|
|
v.gameClient.MapEngine.Advance(tickTime) // TODO: Hack
|
|
|
|
}
|
|
|
|
|
|
|
|
if v.gameControls != nil {
|
|
|
|
v.gameControls.Advance(tickTime)
|
|
|
|
}
|
2020-06-13 22:32:09 +00:00
|
|
|
|
2020-06-19 06:19:27 +00:00
|
|
|
v.ticksSinceLevelCheck += tickTime
|
2020-06-20 04:40:49 +00:00
|
|
|
if v.ticksSinceLevelCheck > 1.0 {
|
2020-06-19 06:19:27 +00:00
|
|
|
v.ticksSinceLevelCheck = 0
|
|
|
|
if v.localPlayer != nil {
|
2020-06-21 22:40:37 +00:00
|
|
|
tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY)
|
|
|
|
if tile != nil {
|
|
|
|
switch tile.RegionType {
|
2020-06-22 19:55:32 +00:00
|
|
|
case d2enum.RegionAct1Town: // Rogue encampent
|
2020-06-21 22:40:37 +00:00
|
|
|
v.localPlayer.SetIsInTown(true)
|
|
|
|
d2audio.PlayBGM("/data/global/music/Act1/town1.wav")
|
2020-06-22 19:55:32 +00:00
|
|
|
case d2enum.RegionAct1Wilderness: // Blood Moore
|
2020-06-21 22:40:37 +00:00
|
|
|
v.localPlayer.SetIsInTown(false)
|
|
|
|
d2audio.PlayBGM("/data/global/music/Act1/wild.wav")
|
2020-06-19 06:19:27 +00:00
|
|
|
}
|
2020-06-22 19:55:32 +00:00
|
|
|
|
|
|
|
// skip showing zone change text the first time we enter the world
|
2020-06-26 20:50:24 +00:00
|
|
|
notNone := v.lastRegionType != d2enum.RegionNone
|
|
|
|
differentTileType := v.lastRegionType != tile.RegionType
|
|
|
|
if notNone && differentTileType {
|
|
|
|
//TODO: Should not be using RegionType as an index - this
|
|
|
|
// will return incorrect LevelDetails record for most of the
|
|
|
|
// zones.
|
|
|
|
levelId := int(tile.RegionType)
|
|
|
|
levelDetails := d2datadict.LevelDetails[levelId]
|
|
|
|
str := "Entering The %s"
|
|
|
|
name := levelDetails.LevelDisplayName
|
|
|
|
v.gameControls.SetZoneChangeText(fmt.Sprintf(str, name))
|
2020-06-22 19:55:32 +00:00
|
|
|
v.gameControls.ShowZoneChangeText()
|
2020-06-26 20:50:24 +00:00
|
|
|
v.gameControls.HideZoneChangeTextAfter(zoneTextDuration)
|
2020-06-22 19:55:32 +00:00
|
|
|
}
|
|
|
|
v.lastRegionType = tile.RegionType
|
2020-06-19 06:19:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-13 22:32:09 +00:00
|
|
|
// Bind the game controls to the player once it exists
|
|
|
|
if v.gameControls == nil {
|
|
|
|
for _, player := range v.gameClient.Players {
|
|
|
|
if player.Id != v.gameClient.PlayerId {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
v.localPlayer = player
|
2020-06-26 20:50:24 +00:00
|
|
|
engine := v.gameClient.MapEngine
|
|
|
|
renderer := v.MapRenderer
|
|
|
|
v.gameControls = d2player.NewGameControls(player, engine, renderer, v)
|
2020-06-13 22:32:09 +00:00
|
|
|
v.gameControls.Load()
|
|
|
|
d2input.BindHandler(v.gameControls)
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the camera to focus on the player
|
2020-06-22 00:46:00 +00:00
|
|
|
if v.localPlayer != nil && !v.gameControls.FreeCam {
|
2020-06-26 20:50:24 +00:00
|
|
|
wx, wy := v.localPlayer.LocationX/5, v.localPlayer.LocationY/5
|
|
|
|
rx, ry := v.MapRenderer.WorldToOrtho(wx, wy)
|
|
|
|
v.MapRenderer.MoveCameraTo(rx, ry)
|
2020-06-13 22:32:09 +00:00
|
|
|
}
|
2020-02-09 02:02:37 +00:00
|
|
|
return nil
|
2019-11-12 04:48:55 +00:00
|
|
|
}
|
2020-06-18 18:11:04 +00:00
|
|
|
|
2020-06-26 20:50:24 +00:00
|
|
|
func (v *Game) OnPlayerMove(x2, y2 float64) {
|
|
|
|
id := v.gameClient.PlayerId
|
|
|
|
x1, y1 := v.localPlayer.LocationX/5.0, v.localPlayer.LocationY/5.0
|
|
|
|
movePacket := d2netpacket.CreateMovePlayerPacket(id, x1, y1, x2, y2)
|
|
|
|
v.gameClient.SendPacketToServer(movePacket)
|
2020-06-18 18:11:04 +00:00
|
|
|
}
|