2020-06-13 20:36:20 -04:00
|
|
|
package d2gamescreen
|
2019-11-11 23:48:55 -05:00
|
|
|
|
|
|
|
import (
|
2020-07-11 11:24:04 -04:00
|
|
|
"fmt"
|
2020-08-25 09:10:26 -04:00
|
|
|
"image/color"
|
|
|
|
|
2020-09-12 16:51:30 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
2020-09-18 16:10:52 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
2020-09-12 16:51:30 -04:00
|
|
|
|
2020-07-23 12:56:50 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
2020-09-26 11:14:34 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
2020-08-06 10:30:23 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
2020-07-23 12:56:50 -04:00
|
|
|
|
2020-06-22 15:55:32 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
2020-07-11 11:24:04 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
2020-07-30 16:17:26 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
2020-06-22 15:55:32 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
2020-07-11 11:24:04 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
|
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"
|
2019-11-11 23:48:55 -05:00
|
|
|
)
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
const hideZoneTextAfterSeconds = 2.0
|
|
|
|
|
2020-07-18 09:54:10 -04:00
|
|
|
const (
|
|
|
|
moveErrStr = "failed to send MovePlayer packet to the server, playerId: %s, x: %g, x: %g\n"
|
|
|
|
bindControlsErrStr = "failed to add gameControls as input handler for player: %s\n"
|
2020-09-20 11:55:44 -04:00
|
|
|
castErrStr = "failed to send CastSkill packet to the server, playerId: %s, skillId: %d, x: %g, x: %g\n"
|
2020-07-30 15:04:05 -04:00
|
|
|
spawnItemErrStr = "failed to send SpawnItem packet to the server: (%d, %d) %+v"
|
2020-07-18 09:54:10 -04:00
|
|
|
)
|
|
|
|
|
2020-10-25 03:42:31 -04:00
|
|
|
const (
|
|
|
|
black50alpha = 0x0000007f // rgba
|
|
|
|
)
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// Game represents the Gameplay screen
|
2019-11-11 23:48:55 -05:00
|
|
|
type Game struct {
|
2020-09-12 16:51:30 -04:00
|
|
|
*d2mapentity.MapEntityFactory
|
|
|
|
asset *d2asset.AssetManager
|
2020-06-19 02:19:27 -04:00
|
|
|
gameClient *d2client.GameClient
|
2020-06-26 17:12:19 -04:00
|
|
|
mapRenderer *d2maprenderer.MapRenderer
|
2020-08-06 10:30:23 -04:00
|
|
|
uiManager *d2ui.UIManager
|
2020-10-25 10:21:14 -04:00
|
|
|
gameControls *d2player.GameControls
|
2020-06-21 18:40:37 -04:00
|
|
|
localPlayer *d2mapentity.Player
|
2020-06-22 15:55:32 -04:00
|
|
|
lastRegionType d2enum.RegionIdType
|
2020-06-19 02:19:27 -04:00
|
|
|
ticksSinceLevelCheck float64
|
2020-10-07 21:20:05 -04:00
|
|
|
escapeMenu *d2player.EscapeMenu
|
2020-07-30 16:17:26 -04:00
|
|
|
soundEngine *d2audio.SoundEngine
|
|
|
|
soundEnv d2audio.SoundEnvironment
|
2020-09-18 16:10:52 -04:00
|
|
|
guiManager *d2gui.GuiManager
|
2020-07-03 14:00:56 -04:00
|
|
|
|
|
|
|
renderer d2interface.Renderer
|
2020-07-13 20:29:17 -04:00
|
|
|
inputManager d2interface.InputManager
|
2020-07-03 14:00:56 -04:00
|
|
|
audioProvider d2interface.AudioProvider
|
|
|
|
terminal d2interface.Terminal
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// CreateGame creates the Gameplay screen and returns a pointer to it
|
2020-07-18 09:54:10 -04:00
|
|
|
func CreateGame(
|
2020-10-07 21:20:05 -04:00
|
|
|
navigator d2interface.Navigator,
|
2020-09-12 16:51:30 -04:00
|
|
|
asset *d2asset.AssetManager,
|
|
|
|
ui *d2ui.UIManager,
|
2020-07-18 09:54:10 -04:00
|
|
|
renderer d2interface.Renderer,
|
|
|
|
inputManager d2interface.InputManager,
|
|
|
|
audioProvider d2interface.AudioProvider,
|
|
|
|
gameClient *d2client.GameClient,
|
|
|
|
term d2interface.Terminal,
|
2020-09-18 16:10:52 -04:00
|
|
|
guiManager *d2gui.GuiManager,
|
2020-07-18 09:54:10 -04:00
|
|
|
) *Game {
|
2020-07-25 09:36:15 -04:00
|
|
|
// find the local player and its initial location
|
|
|
|
var startX, startY float64
|
2020-09-12 16:25:09 -04:00
|
|
|
|
2020-07-25 09:36:15 -04:00
|
|
|
for _, player := range gameClient.Players {
|
2020-08-05 21:27:45 -04:00
|
|
|
if player.ID() != gameClient.PlayerID {
|
2020-07-25 09:36:15 -04:00
|
|
|
continue
|
|
|
|
}
|
2020-09-12 16:25:09 -04:00
|
|
|
|
2020-07-25 09:36:15 -04:00
|
|
|
worldPosition := player.Position.World()
|
|
|
|
startX, startY = worldPosition.X(), worldPosition.Y()
|
2020-09-12 16:25:09 -04:00
|
|
|
|
2020-07-25 09:36:15 -04:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2020-06-21 18:40:37 -04:00
|
|
|
result := &Game{
|
2020-09-12 16:51:30 -04:00
|
|
|
asset: asset,
|
2020-06-19 02:19:27 -04:00
|
|
|
gameClient: gameClient,
|
|
|
|
gameControls: nil,
|
|
|
|
localPlayer: nil,
|
2020-06-22 15:55:32 -04:00
|
|
|
lastRegionType: d2enum.RegionNone,
|
2020-06-19 02:19:27 -04:00
|
|
|
ticksSinceLevelCheck: 0,
|
2020-09-12 16:51:30 -04:00
|
|
|
mapRenderer: d2maprenderer.CreateMapRenderer(asset, renderer,
|
|
|
|
gameClient.MapEngine, term, startX, startY),
|
2020-10-07 21:20:05 -04:00
|
|
|
escapeMenu: d2player.NewEscapeMenu(navigator, renderer, audioProvider, guiManager, asset),
|
2020-09-12 16:51:30 -04:00
|
|
|
inputManager: inputManager,
|
|
|
|
audioProvider: audioProvider,
|
|
|
|
renderer: renderer,
|
|
|
|
terminal: term,
|
2020-09-20 17:52:01 -04:00
|
|
|
soundEngine: d2audio.NewSoundEngine(audioProvider, asset, term),
|
2020-09-12 16:51:30 -04:00
|
|
|
uiManager: ui,
|
2020-09-18 16:10:52 -04:00
|
|
|
guiManager: guiManager,
|
2020-06-13 18:32:09 -04:00
|
|
|
}
|
2020-07-30 16:17:26 -04:00
|
|
|
result.soundEnv = d2audio.NewSoundEnvironment(result.soundEngine)
|
|
|
|
|
2020-10-07 21:20:05 -04:00
|
|
|
result.escapeMenu.OnLoad()
|
2020-07-06 20:13:55 -04:00
|
|
|
|
2020-07-13 20:29:17 -04:00
|
|
|
if err := inputManager.BindHandler(result.escapeMenu); err != nil {
|
2020-07-06 20:13:55 -04:00
|
|
|
fmt.Println("failed to add gameplay screen as event handler")
|
|
|
|
}
|
2020-07-02 13:55:43 -04:00
|
|
|
|
2020-06-21 18:40:37 -04:00
|
|
|
return result
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// OnLoad loads the resources for the Gameplay screen
|
2020-07-03 14:00:56 -04:00
|
|
|
func (v *Game) OnLoad(_ d2screen.LoadingState) {
|
2020-06-28 19:31:10 -04:00
|
|
|
v.audioProvider.PlayBGM("")
|
2020-07-30 15:04:05 -04:00
|
|
|
|
2020-09-12 16:25:09 -04:00
|
|
|
err := v.terminal.BindAction(
|
2020-07-30 15:04:05 -04:00
|
|
|
"spawnitem",
|
|
|
|
"spawns an item at the local player position",
|
|
|
|
func(code1, code2, code3, code4, code5 string) {
|
|
|
|
codes := []string{code1, code2, code3, code4, code5}
|
|
|
|
v.debugSpawnItemAtPlayer(codes...)
|
|
|
|
},
|
|
|
|
)
|
2020-09-12 16:25:09 -04:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("failed to bind the '%s' action, err: %v\n", "spawnitem", err)
|
|
|
|
}
|
2020-07-30 15:04:05 -04:00
|
|
|
|
2020-09-12 16:25:09 -04:00
|
|
|
err = v.terminal.BindAction(
|
2020-07-30 15:04:05 -04:00
|
|
|
"spawnitemat",
|
|
|
|
"spawns an item at the x,y coordinates",
|
|
|
|
func(x, y int, code1, code2, code3, code4, code5 string) {
|
|
|
|
codes := []string{code1, code2, code3, code4, code5}
|
|
|
|
v.debugSpawnItemAtLocation(x, y, codes...)
|
|
|
|
},
|
|
|
|
)
|
2020-09-12 16:25:09 -04:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("failed to bind the '%s' action, err: %v\n", "spawnitemat", err)
|
|
|
|
}
|
2020-08-01 19:03:09 -04:00
|
|
|
|
2020-09-12 16:25:09 -04:00
|
|
|
err = v.terminal.BindAction(
|
2020-08-01 19:03:09 -04:00
|
|
|
"spawnmon",
|
|
|
|
"spawn monster at the local player position",
|
|
|
|
func(name string) {
|
|
|
|
x := int(v.localPlayer.Position.X())
|
|
|
|
y := int(v.localPlayer.Position.Y())
|
2020-09-20 17:52:01 -04:00
|
|
|
monstat := v.asset.Records.Monster.Stats[name]
|
2020-08-01 19:03:09 -04:00
|
|
|
if monstat == nil {
|
|
|
|
v.terminal.OutputErrorf("no monstat entry for \"%s\"", name)
|
|
|
|
return
|
|
|
|
}
|
2020-09-12 16:51:30 -04:00
|
|
|
|
2020-10-25 10:21:14 -04:00
|
|
|
monster, npcErr := v.gameClient.MapEngine.NewNPC(x, y, monstat, 0)
|
|
|
|
if npcErr != nil {
|
|
|
|
v.terminal.OutputErrorf("error generating monster \"%s\": %v", name, npcErr)
|
2020-08-01 19:03:09 -04:00
|
|
|
return
|
|
|
|
}
|
2020-09-12 16:51:30 -04:00
|
|
|
|
2020-08-01 19:03:09 -04:00
|
|
|
v.gameClient.MapEngine.AddEntity(monster)
|
|
|
|
},
|
|
|
|
)
|
2020-09-12 16:25:09 -04:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("failed to bind the '%s' action, err: %v\n", "spawnmon", err)
|
|
|
|
}
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// OnUnload releases the resources of Gameplay screen
|
2020-02-08 21:02:37 -05:00
|
|
|
func (v *Game) OnUnload() error {
|
2020-10-25 10:21:14 -04:00
|
|
|
// https://github.com/OpenDiablo2/OpenDiablo2/issues/792
|
|
|
|
if err := v.inputManager.UnbindHandler(v.gameControls); err != nil {
|
2020-07-06 20:13:55 -04:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-10-25 10:21:14 -04:00
|
|
|
// https://github.com/OpenDiablo2/OpenDiablo2/issues/792
|
|
|
|
if err := v.inputManager.UnbindHandler(v.escapeMenu); err != nil {
|
2020-07-06 20:13:55 -04:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-09-12 16:25:09 -04:00
|
|
|
if err := v.terminal.UnbindAction("spawnItemAt"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := v.terminal.UnbindAction("spawnItem"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-30 15:04:05 -04:00
|
|
|
|
2020-10-31 14:30:08 -04:00
|
|
|
if err := v.OnPlayerSave(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
if err := v.gameClient.Close(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-02 13:55:43 -04:00
|
|
|
|
2020-07-30 16:17:26 -04:00
|
|
|
v.soundEngine.Reset()
|
|
|
|
|
2020-02-08 21:02:37 -05:00
|
|
|
return nil
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// Render renders the Gameplay screen
|
2020-10-28 14:17:42 -04:00
|
|
|
func (v *Game) Render(screen d2interface.Surface) {
|
2020-06-21 18:40:37 -04:00
|
|
|
if v.gameClient.RegenMap {
|
|
|
|
v.gameClient.RegenMap = false
|
2020-06-26 17:12:19 -04:00
|
|
|
v.mapRenderer.RegenerateTileCache()
|
2020-10-10 18:47:51 -04:00
|
|
|
v.gameClient.MapEngine.IsLoading = false
|
2020-06-21 18:40:37 -04:00
|
|
|
}
|
2020-06-25 00:39:09 -04:00
|
|
|
|
2020-10-28 14:17:42 -04:00
|
|
|
screen.Clear(color.Black)
|
2020-06-26 17:12:19 -04:00
|
|
|
v.mapRenderer.Render(screen)
|
2020-06-25 00:39:09 -04:00
|
|
|
|
2020-06-13 18:32:09 -04:00
|
|
|
if v.gameControls != nil {
|
2020-09-26 11:14:34 -04:00
|
|
|
if v.gameControls.HelpOverlay != nil && v.gameControls.HelpOverlay.IsOpen() {
|
2020-10-25 03:42:31 -04:00
|
|
|
screen.DrawRect(screenWidth, screenHeight, d2util.Color(black50alpha))
|
2020-09-26 11:14:34 -04:00
|
|
|
}
|
2020-10-22 01:12:06 -04:00
|
|
|
|
2020-07-26 14:52:54 -04:00
|
|
|
if err := v.gameControls.Render(screen); err != nil {
|
2020-10-28 14:17:42 -04:00
|
|
|
return
|
2020-07-26 14:52:54 -04:00
|
|
|
}
|
2020-06-13 18:32:09 -04:00
|
|
|
}
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// Advance runs the update logic on the Gameplay screen
|
2020-07-18 23:37:35 -04:00
|
|
|
func (v *Game) Advance(elapsed float64) error {
|
2020-07-30 16:17:26 -04:00
|
|
|
v.soundEngine.Advance(elapsed)
|
|
|
|
|
2020-10-07 21:20:05 -04:00
|
|
|
if (v.escapeMenu != nil && !v.escapeMenu.IsOpen()) || len(v.gameClient.Players) != 1 {
|
2020-10-25 10:21:14 -04:00
|
|
|
v.gameClient.MapEngine.Advance(elapsed)
|
2020-06-21 16:06:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if v.gameControls != nil {
|
2020-07-18 23:37:35 -04:00
|
|
|
if err := v.gameControls.Advance(elapsed); err != nil {
|
2020-07-06 20:13:55 -04:00
|
|
|
return err
|
|
|
|
}
|
2020-06-21 16:06:52 -04:00
|
|
|
}
|
2020-06-13 18:32:09 -04:00
|
|
|
|
2020-07-18 23:37:35 -04:00
|
|
|
v.ticksSinceLevelCheck += elapsed
|
2020-10-25 03:42:31 -04:00
|
|
|
if v.ticksSinceLevelCheck > 1 {
|
2020-06-19 02:19:27 -04:00
|
|
|
v.ticksSinceLevelCheck = 0
|
|
|
|
if v.localPlayer != nil {
|
2020-07-13 09:06:50 -04:00
|
|
|
tilePosition := v.localPlayer.Position.Tile()
|
|
|
|
tile := v.gameClient.MapEngine.TileAt(int(tilePosition.X()), int(tilePosition.Y()))
|
|
|
|
|
2020-06-21 18:40:37 -04:00
|
|
|
if tile != nil {
|
2020-09-20 17:52:01 -04:00
|
|
|
levelDetails := v.asset.Records.Level.Details[int(tile.RegionType)]
|
|
|
|
v.soundEnv.SetEnv(levelDetails.SoundEnvironmentID)
|
2020-06-22 15:55:32 -04:00
|
|
|
|
|
|
|
// skip showing zone change text the first time we enter the world
|
2020-06-26 17:12:19 -04:00
|
|
|
if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType {
|
2020-09-20 17:52:01 -04:00
|
|
|
areaName := levelDetails.LevelDisplayName
|
2020-07-18 09:54:10 -04:00
|
|
|
areaChgStr := fmt.Sprintf("Entering The %s", areaName)
|
|
|
|
v.gameControls.SetZoneChangeText(areaChgStr)
|
2020-06-22 15:55:32 -04:00
|
|
|
v.gameControls.ShowZoneChangeText()
|
2020-06-26 17:12:19 -04:00
|
|
|
v.gameControls.HideZoneChangeTextAfter(hideZoneTextAfterSeconds)
|
2020-06-22 15:55:32 -04:00
|
|
|
}
|
2020-07-02 13:55:43 -04:00
|
|
|
|
2020-06-22 15:55:32 -04:00
|
|
|
v.lastRegionType = tile.RegionType
|
2020-06-19 02:19:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-13 18:32:09 -04:00
|
|
|
// Bind the game controls to the player once it exists
|
|
|
|
if v.gameControls == nil {
|
2020-07-26 14:52:54 -04:00
|
|
|
if err := v.bindGameControls(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-13 18:32:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update the camera to focus on the player
|
2020-06-21 20:46:00 -04:00
|
|
|
if v.localPlayer != nil && !v.gameControls.FreeCam {
|
2020-07-13 09:06:50 -04:00
|
|
|
worldPosition := v.localPlayer.Position.World()
|
|
|
|
rx, ry := v.mapRenderer.WorldToOrtho(worldPosition.X(), worldPosition.Y())
|
2020-07-18 23:37:35 -04:00
|
|
|
position := d2vector.NewPosition(rx, ry)
|
|
|
|
v.mapRenderer.SetCameraTarget(&position)
|
2020-06-13 18:32:09 -04:00
|
|
|
}
|
2020-07-02 13:55:43 -04:00
|
|
|
|
2020-07-30 16:17:26 -04:00
|
|
|
v.soundEnv.Advance(elapsed)
|
|
|
|
|
2020-02-08 21:02:37 -05:00
|
|
|
return nil
|
2019-11-11 23:48:55 -05:00
|
|
|
}
|
2020-06-18 14:11:04 -04:00
|
|
|
|
2020-07-26 14:52:54 -04:00
|
|
|
func (v *Game) bindGameControls() error {
|
2020-07-06 20:13:55 -04:00
|
|
|
for _, player := range v.gameClient.Players {
|
2020-08-05 21:27:45 -04:00
|
|
|
if player.ID() != v.gameClient.PlayerID {
|
2020-07-06 20:13:55 -04:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
v.localPlayer = player
|
2020-07-26 14:52:54 -04:00
|
|
|
|
|
|
|
var err error
|
2020-09-18 16:10:52 -04:00
|
|
|
v.gameControls, err = d2player.NewGameControls(v.asset, v.renderer, player, v.gameClient.MapEngine,
|
2020-10-07 21:20:05 -04:00
|
|
|
v.escapeMenu, v.mapRenderer, v, v.terminal, v.uiManager, v.guiManager, v.gameClient.IsSinglePlayer())
|
2020-07-26 14:52:54 -04:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
v.gameControls.Load()
|
|
|
|
|
2020-07-13 20:29:17 -04:00
|
|
|
if err := v.inputManager.BindHandler(v.gameControls); err != nil {
|
2020-08-05 21:27:45 -04:00
|
|
|
fmt.Printf(bindControlsErrStr, player.ID())
|
2020-07-06 20:13:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
break
|
|
|
|
}
|
2020-07-26 14:52:54 -04:00
|
|
|
|
|
|
|
return nil
|
2020-07-06 20:13:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// OnPlayerMove sends the player move action to the server
|
2020-07-18 09:54:10 -04:00
|
|
|
func (v *Game) OnPlayerMove(targetX, targetY float64) {
|
2020-07-13 09:06:50 -04:00
|
|
|
worldPosition := v.localPlayer.Position.World()
|
2020-07-06 20:13:55 -04:00
|
|
|
|
2020-07-18 09:54:10 -04:00
|
|
|
playerID, worldX, worldY := v.gameClient.PlayerID, worldPosition.X(), worldPosition.Y()
|
2020-10-31 14:30:08 -04:00
|
|
|
createMovePlayerPacket := d2netpacket.CreateMovePlayerPacket(playerID, worldX, worldY, targetX, targetY)
|
|
|
|
err := v.gameClient.SendPacketToServer(createMovePlayerPacket)
|
2020-07-18 09:54:10 -04:00
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
if err != nil {
|
2020-07-18 09:54:10 -04:00
|
|
|
fmt.Printf(moveErrStr, v.gameClient.PlayerID, targetX, targetY)
|
2020-07-06 20:13:55 -04:00
|
|
|
}
|
2020-06-18 14:11:04 -04:00
|
|
|
}
|
2020-06-26 20:03:00 -04:00
|
|
|
|
2020-10-31 14:30:08 -04:00
|
|
|
// OnPlayerSave instructs the server to save our player data
|
|
|
|
func (v *Game) OnPlayerSave() error {
|
|
|
|
playerState := v.gameClient.Players[v.gameClient.PlayerID]
|
|
|
|
err := v.gameClient.SendPacketToServer(d2netpacket.CreateSavePlayerPacket(playerState))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-07-06 20:13:55 -04:00
|
|
|
// OnPlayerCast sends the casting skill action to the server
|
2020-09-20 11:55:44 -04:00
|
|
|
func (v *Game) OnPlayerCast(skillID int, targetX, targetY float64) {
|
|
|
|
err := v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerID, skillID, targetX, targetY))
|
2020-07-06 20:13:55 -04:00
|
|
|
if err != nil {
|
2020-09-20 11:55:44 -04:00
|
|
|
fmt.Printf(castErrStr, v.gameClient.PlayerID, skillID, targetX, targetY)
|
2020-07-06 20:13:55 -04:00
|
|
|
}
|
2020-06-26 20:03:00 -04:00
|
|
|
}
|
2020-07-30 15:04:05 -04:00
|
|
|
|
|
|
|
func (v *Game) debugSpawnItemAtPlayer(codes ...string) {
|
|
|
|
if v.localPlayer == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
pos := v.localPlayer.GetPosition()
|
|
|
|
tile := pos.Tile()
|
|
|
|
x, y := int(tile.X()), int(tile.Y())
|
|
|
|
|
|
|
|
v.debugSpawnItemAtLocation(x, y, codes...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v *Game) debugSpawnItemAtLocation(x, y int, codes ...string) {
|
|
|
|
packet := d2netpacket.CreateSpawnItemPacket(x, y, codes...)
|
2020-09-12 16:25:09 -04:00
|
|
|
|
2020-07-30 15:04:05 -04:00
|
|
|
err := v.gameClient.SendPacketToServer(packet)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf(spawnItemErrStr, x, y, codes)
|
|
|
|
}
|
|
|
|
}
|