1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-18 10:26:02 -05:00
OpenDiablo2/d2game/d2gamescreen/game.go

140 lines
4.4 KiB
Go
Raw Normal View History

package d2gamescreen
import (
"fmt"
"image/color"
2020-06-28 19:31:10 -04:00
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
2020-06-21 18:40:37 -04:00
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client"
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket"
)
type Game struct {
2020-06-19 02:19:27 -04:00
gameClient *d2client.GameClient
mapRenderer *d2maprenderer.MapRenderer
2020-06-19 02:19:27 -04:00
gameControls *d2player.GameControls // TODO: Hack
2020-06-21 18:40:37 -04:00
localPlayer *d2mapentity.Player
lastRegionType d2enum.RegionIdType
2020-06-28 19:31:10 -04:00
audioProvider d2interface.AudioProvider
2020-06-19 02:19:27 -04:00
ticksSinceLevelCheck float64
escapeMenu *EscapeMenu
}
2020-06-28 19:31:10 -04:00
func CreateGame(audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient) *Game {
2020-06-21 18:40:37 -04:00
result := &Game{
2020-06-19 02:19:27 -04:00
gameClient: gameClient,
gameControls: nil,
localPlayer: nil,
lastRegionType: d2enum.RegionNone,
2020-06-19 02:19:27 -04:00
ticksSinceLevelCheck: 0,
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
2020-06-28 19:31:10 -04:00
escapeMenu: NewEscapeMenu(audioProvider),
audioProvider: audioProvider,
}
result.escapeMenu.OnLoad()
d2input.BindHandler(result.escapeMenu)
2020-06-21 18:40:37 -04:00
return result
}
func (v *Game) OnLoad(loading d2screen.LoadingState) {
2020-06-28 19:31:10 -04:00
v.audioProvider.PlayBGM("")
}
2020-02-08 21:02:37 -05:00
func (v *Game) OnUnload() error {
d2input.UnbindHandler(v.gameControls) // TODO: hack
v.gameClient.Close()
2020-02-08 21:02:37 -05:00
return nil
}
2020-02-08 21:02:37 -05:00
func (v *Game) Render(screen d2render.Surface) error {
2020-06-21 18:40:37 -04:00
if v.gameClient.RegenMap {
v.gameClient.RegenMap = false
v.mapRenderer.RegenerateTileCache()
2020-06-21 18:40:37 -04:00
}
screen.Clear(color.Black)
v.mapRenderer.Render(screen)
if v.gameControls != nil {
v.gameControls.Render(screen)
}
2020-02-08 21:02:37 -05:00
return nil
}
var hideZoneTextAfterSeconds = 2.0
2020-02-08 21:02:37 -05:00
func (v *Game) Advance(tickTime float64) error {
if (v.escapeMenu != nil && !v.escapeMenu.IsOpen()) || len(v.gameClient.Players) != 1 {
v.gameClient.MapEngine.Advance(tickTime) // TODO: Hack
}
if v.gameControls != nil {
v.gameControls.Advance(tickTime)
}
2020-06-19 02:19:27 -04:00
v.ticksSinceLevelCheck += tickTime
if v.ticksSinceLevelCheck > 1.0 {
2020-06-19 02:19:27 -04:00
v.ticksSinceLevelCheck = 0
if v.localPlayer != nil {
2020-06-21 18:40:37 -04:00
tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY)
if tile != nil {
2020-06-27 03:16:53 -04:00
musicInfo := d2common.GetMusicDef(tile.RegionType)
2020-06-28 19:31:10 -04:00
v.audioProvider.PlayBGM(musicInfo.MusicFile)
// skip showing zone change text the first time we enter the world
if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType {
//TODO: Should not be using RegionType as an index - this will return incorrect LevelDetails record for most of the zones.
v.gameControls.SetZoneChangeText(fmt.Sprintf("Entering The %s", d2datadict.LevelDetails[int(tile.RegionType)].LevelDisplayName))
v.gameControls.ShowZoneChangeText()
v.gameControls.HideZoneChangeTextAfter(hideZoneTextAfterSeconds)
}
v.lastRegionType = tile.RegionType
2020-06-19 02:19:27 -04: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
v.gameControls = d2player.NewGameControls(player, v.gameClient.MapEngine, v.mapRenderer, v)
v.gameControls.Load()
d2input.BindHandler(v.gameControls)
break
}
}
// Update the camera to focus on the player
if v.localPlayer != nil && !v.gameControls.FreeCam {
rx, ry := v.mapRenderer.WorldToOrtho(v.localPlayer.LocationX/5, v.localPlayer.LocationY/5)
v.mapRenderer.MoveCameraTo(rx, ry)
}
2020-02-08 21:02:37 -05:00
return nil
}
2020-06-18 14:11:04 -04:00
func (v *Game) OnPlayerMove(x, y float64) {
heroPosX := v.localPlayer.LocationX / 5.0
heroPosY := v.localPlayer.LocationY / 5.0
v.gameClient.SendPacketToServer(d2netpacket.CreateMovePlayerPacket(v.gameClient.PlayerId, heroPosX, heroPosY, x, y))
2020-06-18 14:11:04 -04:00
}
func (v *Game) OnPlayerCast(missleID int, targetX, targetY float64) {
v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerId, missleID, targetX, targetY))
}