1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-15 12:10:49 +00:00
OpenDiablo2/d2game/d2gamescreen/game.go

429 lines
12 KiB
Go
Raw Normal View History

package d2gamescreen
import (
"errors"
"fmt"
"image/color"
2020-12-21 20:46:58 +00:00
"strconv"
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
2020-07-23 16:56:50 +00:00
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
2020-07-23 16:56:50 +00:00
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
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"
)
const hideZoneTextAfterSeconds = 2.0
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"
castErrStr = "failed to send CastSkill packet to the server, playerId: %s, skillId: %d, x: %g, x: %g\n"
spawnItemErrStr = "failed to send SpawnItem packet to the server: (%d, %d) %+v"
)
const (
black50alpha = 0x0000007f // rgba
)
// CreateGame creates the Gameplay screen and returns a pointer to it
func CreateGame(
navigator d2interface.Navigator,
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
asset *d2asset.AssetManager,
ui *d2ui.UIManager,
renderer d2interface.Renderer,
inputManager d2interface.InputManager,
audioProvider d2interface.AudioProvider,
gameClient *d2client.GameClient,
term d2interface.Terminal,
l d2util.LogLevel,
guiManager *d2gui.GuiManager,
) (*Game, error) {
// find the local player and its initial location
var startX, startY float64
2020-09-12 20:25:09 +00:00
for _, player := range gameClient.Players {
if player.ID() != gameClient.PlayerID {
continue
}
2020-09-12 20:25:09 +00:00
worldPosition := player.Position.World()
startX, startY = worldPosition.X(), worldPosition.Y()
2020-09-12 20:25:09 +00:00
break
}
keyMap := d2player.GetDefaultKeyMap(asset)
game := &Game{
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
asset: asset,
2020-06-19 06:19:27 +00:00
gameClient: gameClient,
gameControls: nil,
localPlayer: nil,
lastRegionType: d2enum.RegionNone,
2020-06-19 06:19:27 +00:00
ticksSinceLevelCheck: 0,
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
mapRenderer: d2maprenderer.CreateMapRenderer(asset, renderer,
gameClient.MapEngine, term, l, startX, startY),
escapeMenu: d2player.NewEscapeMenu(navigator, renderer, audioProvider, ui, guiManager, asset, l, keyMap),
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
inputManager: inputManager,
audioProvider: audioProvider,
renderer: renderer,
terminal: term,
soundEngine: d2audio.NewSoundEngine(audioProvider, asset, l, term),
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
uiManager: ui,
guiManager: guiManager,
keyMap: keyMap,
logLevel: l,
}
game.Logger = d2util.NewLogger()
game.Logger.SetLevel(l)
game.Logger.SetPrefix(logPrefix)
game.soundEnv = d2audio.NewSoundEnvironment(game.soundEngine)
game.escapeMenu.OnLoad()
if err := inputManager.BindHandler(game.escapeMenu); err != nil {
return nil, errors.New("failed to add gameplay screen as event handler")
}
return game, nil
}
// Game represents the Gameplay screen
type Game struct {
*d2mapentity.MapEntityFactory
asset *d2asset.AssetManager
gameClient *d2client.GameClient
mapRenderer *d2maprenderer.MapRenderer
uiManager *d2ui.UIManager
gameControls *d2player.GameControls
localPlayer *d2mapentity.Player
lastRegionType d2enum.RegionIdType
ticksSinceLevelCheck float64
escapeMenu *d2player.EscapeMenu
soundEngine *d2audio.SoundEngine
soundEnv d2audio.SoundEnvironment
guiManager *d2gui.GuiManager
keyMap *d2player.KeyMap
renderer d2interface.Renderer
inputManager d2interface.InputManager
audioProvider d2interface.AudioProvider
terminal d2interface.Terminal
*d2util.Logger
logLevel d2util.LogLevel
}
// OnLoad loads the resources for the Gameplay screen
func (v *Game) OnLoad(_ d2screen.LoadingState) {
2020-06-28 23:31:10 +00:00
v.audioProvider.PlayBGM("")
2020-12-21 20:46:58 +00:00
commands := []struct {
name string
desc string
args []string
fn func([]string) error
}{
{"spawnitem", "spawns an item at the local player position",
[]string{"code1", "code2", "code3", "code4", "code5"}, v.commandSpawnItem},
{"spawnitemat", "spawns an item at the x,y coordinates",
[]string{"x", "y", "code1", "code2", "code3", "code4", "code5"}, v.commandSpawnItemAt},
{"spawnmon", "spawn monster at the local player position", []string{"name"}, v.commandSpawnMon},
2020-09-12 20:25:09 +00:00
}
2020-12-21 20:46:58 +00:00
for _, cmd := range commands {
if err := v.terminal.Bind(cmd.name, cmd.desc, cmd.args, cmd.fn); err != nil {
v.Errorf(err.Error())
}
}
remove d2asset singleton (#726) * export d2asset singleton * add *d2asset.AssetManager to d2app - d2app now has a reference to an asset manager which it will use for loading - added asset loader methods to the asset manager - functions in d2asset are now wrappers for asset manager methods * add asset manager reference to audio provider - d2app asset manager reference is now passed to audio provider - asset manager is created in main.go for now to pass into audio provider - CreateSoundEffect is now a method, no longer exported, uses the asset manager reference * d2app passes asset manager refence to map engine test * in d2asset, all calls to LoadFile replaced with call to Singleton.Loadfile * blizzard intro and credits screen - d2app passes reference to the asset manager to these screens * asset manager for d2map - adding MapStampFactory, takes an asset manager reference - embedded MapStampFactory into the MapEngine - LoadStamp is now a method of the MapStampFactory * d2asset: removed LoadFileStream, LoadFile, and FileExists * d2gui changes - singleton now has an asset manager reference - calls to d2asset loader functions removed - createButton is now a method of LayoutManager - moved LayoutEntry to its own file * map entity factory - Map engine has an embedded map entity factory - Map stamp factory gets a reference to the map engine's entity factory - Stamps are given a reference to the map engine entity factory when created - Character select gets a map entity factory - Embedded the stamp factory into the MapEngine * asset manager for d2ui - d2ui is passed an asset manager reference when created - all calls to d2asset loader functions in d2ui now refer to the asset manager - d2gamescreen gets a ui manager when created - help overlay is now passed a ui manager when created * d2gamescreen + d2player: asset manager references added an asset manager reference to - inventory panel + inventory grid - mini panel - game controls - help overlay - character select - main menu - select hero class - hero stats panel * Removed d2asset.LoadAnimation all references to this function have been replaced with calls to the asset manager method * adding asset to help overlay, bugfix for 4d59c91 * Removed d2asset.LoadFont and d2asset.LoadAnimationWithEffect all references to these have been replaced with calls to the asset manager methods * MapRenderer now gets an asset manager reference * removed d2asset.LoadPalette all references have been replaced with calls to an asset manager instance * merged d2object with d2mapentity d2object was only being used to create objects in the map, so the provider function is now a method of the map entity factory. calls to d2asset have been removed. * removed d2asset.LoadComposite all calls are now made to the asset manager method * removed d2asset singleton all singleton references have been removed, a single instance of the asset manager is passed around the entire app * rename Initialize to NewAssetManager
2020-09-12 20:51:30 +00:00
2020-12-21 20:46:58 +00:00
if err := v.asset.BindTerminalCommands(v.terminal); err != nil {
v.Errorf(err.Error())
2020-09-12 20:25:09 +00:00
}
}
// OnUnload releases the resources of Gameplay screen
2020-02-09 02:02:37 +00:00
func (v *Game) OnUnload() error {
2020-12-21 20:46:58 +00:00
if err := v.gameControls.UnbindTerminalCommands(v.terminal); err != nil {
return err
}
// https://github.com/OpenDiablo2/OpenDiablo2/issues/792
if err := v.inputManager.UnbindHandler(v.gameControls); err != nil {
return err
}
// https://github.com/OpenDiablo2/OpenDiablo2/issues/792
if err := v.inputManager.UnbindHandler(v.escapeMenu); err != nil {
return err
}
2020-12-21 20:46:58 +00:00
if err := v.terminal.Unbind("spawnitemat", "spawnitem", "spawnmon"); err != nil {
2020-09-12 20:25:09 +00:00
return err
}
2020-12-21 20:46:58 +00:00
if err := v.OnPlayerSave(); err != nil {
2020-09-12 20:25:09 +00:00
return err
}
2020-12-21 20:46:58 +00:00
if err := v.gameClient.Close(); err != nil {
return err
}
2020-12-21 20:46:58 +00:00
if err := v.asset.UnbindTerminalCommands(v.terminal); err != nil {
return err
}
if err := v.mapRenderer.UnbindTerminalCommands(v.terminal); err != nil {
return err
}
if err := v.soundEngine.UnbindTerminalCommands(v.terminal); err != nil {
return err
}
v.soundEngine.Reset()
2020-02-09 02:02:37 +00:00
return nil
}
// Render renders the Gameplay screen
func (v *Game) Render(screen d2interface.Surface) {
2020-06-21 22:40:37 +00:00
if v.gameClient.RegenMap {
v.gameClient.RegenMap = false
v.mapRenderer.RegenerateTileCache()
v.gameClient.MapEngine.IsLoading = false
2020-06-21 22:40:37 +00:00
}
screen.Clear(color.Black)
v.mapRenderer.Render(screen)
if v.gameControls != nil {
if v.gameControls.HelpOverlay != nil && v.gameControls.HelpOverlay.IsOpen() {
screen.DrawRect(screenWidth, screenHeight, d2util.Color(black50alpha))
}
2020-07-26 18:52:54 +00:00
if err := v.gameControls.Render(screen); err != nil {
return
2020-07-26 18:52:54 +00:00
}
}
}
// Advance runs the update logic on the Gameplay screen
func (v *Game) Advance(elapsed float64) error {
v.soundEngine.Advance(elapsed)
if (v.escapeMenu != nil && !v.escapeMenu.IsOpen()) || len(v.gameClient.Players) != 1 {
v.gameClient.MapEngine.Advance(elapsed)
}
if v.gameControls != nil {
if err := v.gameControls.Advance(elapsed); err != nil {
return err
}
}
v.ticksSinceLevelCheck += elapsed
if v.ticksSinceLevelCheck > 1 {
2020-06-19 06:19:27 +00:00
v.ticksSinceLevelCheck = 0
if v.localPlayer != nil {
tilePosition := v.localPlayer.Position.Tile()
tile := v.gameClient.MapEngine.TileAt(int(tilePosition.X()), int(tilePosition.Y()))
2020-06-21 22:40:37 +00:00
if tile != nil {
Removing d2datadict singletons (#738) * Remove weapons, armor, misc, itemCommon, itemTyps datadict singletons - removed loader calls from d2app - removed the HeroObjects singleton from `d2core/d2inventory` - added an InventoryItemFactory in d2inventory - package-level functions that use data records are now methods of the InventoryItemFactory - renamed ItemGenerator in d2item to ItemFactory - package-level functions that use records are now methods of ItemFactory - d2map.MapEntityFactory now has an item factory instance for creating items - fixed a bug in unique item record loader where it loaded an empty record - added a PlayerStateFactory for creating a player state (uses the asset manager) - updated the test inventory/equipment code in d2player to handle errors from the ItemFactory - character select and character creation screens have a player state and inventory item factory - updated item tests to use the item factory * minor edit * Removed d2datadict.Experience singleton added a HeroStatsFactory, much like the other factories. The factory gets an asset manager reference in order to use data records. * removed d2datadict.AutoMagic singleton * removed d2datadict.AutoMap singleton * removed d2datadict.BodyLocations singleton * removed d2datadict.Books singleton * Removed singletons for level records - removed loader calls in d2app - changed type references from d2datadict to d2records - added a `MapGenerator` in d2mapgen which uses thew asset manager and map engine - package-level map generation functions are now MapGenerator methods - `d2datadict.GetLevelDetails(id int)` is now a method of the RecordManager * remove SkillCalc and MissileCalc singletons * Removed CharStats and ItemStatCost singletons - added an ItemStatFactory which uses the asset manager to create stats - package-level functions for stats in d2item are now StatFactory methods - changed type references from d2datadict to d2records - `d2player.GetAllPlayerStates` is now a method of the `PlayerStateFactory` * Removed DkillDesc and Skills singletons from d2datadict - removed loader calls from d2app - diablo2stats.Stat instances are given a reference to the factory for doing record lookups * update the stats test to use mock a asset manager and stat factory * fixed diablo2stats tests and diablo2item tests * removed CompCodes singleton from d2datadict * remove cubemain singleton from d2datadict * removed DifficultyLevels singleton from d2datadict * removed ElemTypes singleton from d2datadict * removed events.go loader from d2datadict (was unused) * removed Gems singleton from d2datadict * removed Hireling and Inventory singletons from d2datadict * removed MagicPrefix and MagicSuffix singletons from d2datadict * removed ItemRatios singleton from d2datadict * removed Missiles singleton from d2datadict * removed MonModes singleton * Removed all monster and npc singletons from d2datadict - MapStamp instances now get a reference to their factory for doing record lookups * removed SoundEntry and SoundEnviron singletons from d2datadict
2020-09-20 21:52:01 +00:00
levelDetails := v.asset.Records.Level.Details[int(tile.RegionType)]
v.soundEnv.SetEnv(levelDetails.SoundEnvironmentID)
// skip showing zone change text the first time we enter the world
if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType {
Removing d2datadict singletons (#738) * Remove weapons, armor, misc, itemCommon, itemTyps datadict singletons - removed loader calls from d2app - removed the HeroObjects singleton from `d2core/d2inventory` - added an InventoryItemFactory in d2inventory - package-level functions that use data records are now methods of the InventoryItemFactory - renamed ItemGenerator in d2item to ItemFactory - package-level functions that use records are now methods of ItemFactory - d2map.MapEntityFactory now has an item factory instance for creating items - fixed a bug in unique item record loader where it loaded an empty record - added a PlayerStateFactory for creating a player state (uses the asset manager) - updated the test inventory/equipment code in d2player to handle errors from the ItemFactory - character select and character creation screens have a player state and inventory item factory - updated item tests to use the item factory * minor edit * Removed d2datadict.Experience singleton added a HeroStatsFactory, much like the other factories. The factory gets an asset manager reference in order to use data records. * removed d2datadict.AutoMagic singleton * removed d2datadict.AutoMap singleton * removed d2datadict.BodyLocations singleton * removed d2datadict.Books singleton * Removed singletons for level records - removed loader calls in d2app - changed type references from d2datadict to d2records - added a `MapGenerator` in d2mapgen which uses thew asset manager and map engine - package-level map generation functions are now MapGenerator methods - `d2datadict.GetLevelDetails(id int)` is now a method of the RecordManager * remove SkillCalc and MissileCalc singletons * Removed CharStats and ItemStatCost singletons - added an ItemStatFactory which uses the asset manager to create stats - package-level functions for stats in d2item are now StatFactory methods - changed type references from d2datadict to d2records - `d2player.GetAllPlayerStates` is now a method of the `PlayerStateFactory` * Removed DkillDesc and Skills singletons from d2datadict - removed loader calls from d2app - diablo2stats.Stat instances are given a reference to the factory for doing record lookups * update the stats test to use mock a asset manager and stat factory * fixed diablo2stats tests and diablo2item tests * removed CompCodes singleton from d2datadict * remove cubemain singleton from d2datadict * removed DifficultyLevels singleton from d2datadict * removed ElemTypes singleton from d2datadict * removed events.go loader from d2datadict (was unused) * removed Gems singleton from d2datadict * removed Hireling and Inventory singletons from d2datadict * removed MagicPrefix and MagicSuffix singletons from d2datadict * removed ItemRatios singleton from d2datadict * removed Missiles singleton from d2datadict * removed MonModes singleton * Removed all monster and npc singletons from d2datadict - MapStamp instances now get a reference to their factory for doing record lookups * removed SoundEntry and SoundEnviron singletons from d2datadict
2020-09-20 21:52:01 +00:00
areaName := levelDetails.LevelDisplayName
areaChgStr := fmt.Sprintf("Entering The %s", areaName)
v.gameControls.SetZoneChangeText(areaChgStr)
v.gameControls.ShowZoneChangeText()
v.gameControls.HideZoneChangeTextAfter(hideZoneTextAfterSeconds)
}
v.lastRegionType = tile.RegionType
2020-06-19 06:19:27 +00:00
}
}
}
// Bind the game controls to the player once it exists
if v.gameControls == nil {
2020-07-26 18:52:54 +00:00
if err := v.bindGameControls(); err != nil {
return err
}
}
// Update the camera to focus on the player
if v.localPlayer != nil && !v.gameControls.FreeCam {
worldPosition := v.localPlayer.Position.World()
rx, ry := v.mapRenderer.WorldToOrtho(worldPosition.X(), worldPosition.Y())
position := d2vector.NewPosition(rx, ry)
v.mapRenderer.SetCameraTarget(&position)
}
v.soundEnv.Advance(elapsed)
2020-02-09 02:02:37 +00:00
return nil
}
2020-06-18 18:11:04 +00:00
2020-07-26 18:52:54 +00:00
func (v *Game) bindGameControls() error {
for _, player := range v.gameClient.Players {
if player.ID() != v.gameClient.PlayerID {
continue
}
v.localPlayer = player
2020-07-26 18:52:54 +00:00
var err error
v.gameControls, err = d2player.NewGameControls(v.asset, v.renderer, player, v.gameClient.MapEngine,
2020-12-16 14:08:39 +00:00
v.escapeMenu, v.mapRenderer, v, v.terminal, v.uiManager, v.keyMap, v.audioProvider, v.logLevel,
v.gameClient.IsSinglePlayer())
2020-07-26 18:52:54 +00:00
if err != nil {
return err
}
v.gameControls.Load()
if err := v.inputManager.BindHandler(v.gameControls); err != nil {
v.Error(bindControlsErrStr + player.ID())
}
break
}
2020-07-26 18:52:54 +00:00
return nil
}
// OnPlayerMove sends the player move action to the server
func (v *Game) OnPlayerMove(targetX, targetY float64) {
worldPosition := v.localPlayer.Position.World()
playerID, worldX, worldY := v.gameClient.PlayerID, worldPosition.X(), worldPosition.Y()
2020-11-23 17:07:51 +00:00
createMovePlayerPacket, err := d2netpacket.CreateMovePlayerPacket(playerID, worldX, worldY, targetX, targetY)
if err != nil {
v.Errorf("MovePlayerPacket: %v", err)
}
err = v.gameClient.SendPacketToServer(createMovePlayerPacket)
if err != nil {
v.Errorf(moveErrStr, v.gameClient.PlayerID, targetX, targetY)
}
2020-06-18 18:11:04 +00:00
}
// OnPlayerSave instructs the server to save our player data
func (v *Game) OnPlayerSave() error {
playerState := v.gameClient.Players[v.gameClient.PlayerID]
2020-11-23 17:07:51 +00:00
2020-11-25 10:48:23 +00:00
sp, err := d2netpacket.CreateSavePlayerPacket(playerState, d2enum.DifficultyNormal)
2020-11-23 17:07:51 +00:00
if err != nil {
return fmt.Errorf("SavePlayerPacket: %v", err)
}
err = v.gameClient.SendPacketToServer(sp)
if err != nil {
return err
}
return nil
}
// OnPlayerCast sends the casting skill action to the server
func (v *Game) OnPlayerCast(skillID int, targetX, targetY float64) {
2020-11-23 17:07:51 +00:00
cp, err := d2netpacket.CreateCastPacket(v.gameClient.PlayerID, skillID, targetX, targetY)
if err != nil {
v.Errorf("CastPacket: %v", err)
}
err = v.gameClient.SendPacketToServer(cp)
if err != nil {
v.Errorf(castErrStr, v.gameClient.PlayerID, skillID, targetX, targetY)
}
}
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) {
2020-11-23 17:07:51 +00:00
packet, err := d2netpacket.CreateSpawnItemPacket(x, y, codes...)
if err != nil {
v.Errorf("SpawnItemPacket: %v", err)
}
2020-09-12 20:25:09 +00:00
2020-11-23 17:07:51 +00:00
err = v.gameClient.SendPacketToServer(packet)
if err != nil {
v.Errorf(spawnItemErrStr, x, y, codes)
}
}
2020-12-21 20:46:58 +00:00
func (v *Game) commandSpawnItem(args []string) error {
v.debugSpawnItemAtPlayer(args...)
return nil
}
func (v *Game) commandSpawnItemAt(args []string) error {
x, err := strconv.Atoi(args[0])
if err != nil {
return fmt.Errorf("invalid argument")
}
y, err := strconv.Atoi(args[0])
if err != nil {
return fmt.Errorf("invalid argument")
}
v.debugSpawnItemAtLocation(x, y, args[2:]...)
return nil
}
func (v *Game) commandSpawnMon(args []string) error {
name := args[0]
x := int(v.localPlayer.Position.X())
y := int(v.localPlayer.Position.Y())
monstat := v.asset.Records.Monster.Stats[name]
if monstat == nil {
v.terminal.Errorf("no monstat entry for \"%s\"", name)
return nil
}
monster, npcErr := v.gameClient.MapEngine.NewNPC(x, y, monstat, 0)
if npcErr != nil {
v.terminal.Errorf("error generating monster \"%s\": %v", name, npcErr)
return nil
}
v.gameClient.MapEngine.AddEntity(monster)
return nil
}