1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-20 15:37:31 -05:00
OpenDiablo2/d2core/d2systems/game_config.go

150 lines
4.2 KiB
Go
Raw Normal View History

package d2systems
import (
2020-10-12 14:35:11 -07:00
"encoding/json"
2020-10-12 14:35:11 -07:00
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
2020-10-12 14:35:11 -07:00
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
)
// static check that the game config system implements the system interface
2020-10-12 14:35:11 -07:00
var _ akara.System = &GameConfigSystem{}
const (
loggerPrefixGameConfig = "Game Config"
)
// GameConfigSystem is responsible for game config configFileBootstrap procedure, as well as
// clearing the `Dirty` component of game configs. In the `configFileBootstrap` method of this system
2020-10-12 14:35:11 -07:00
// you can see that this system will add entities for the directories it expects config files
// to be found in, and it also adds an entity for the initial config file to be loaded.
//
// This system is dependant on the FileTypeResolver, FileSourceResolver, and
// FileHandleResolver sceneSystems because this system subscribes to entities
// with components created by these other sceneSystems. Nothing will break if these
// other sceneSystems are not present in the world, but no config files will be loaded by
2020-10-12 14:35:11 -07:00
// this system either...
type GameConfigSystem struct {
akara.BaseSubscriberSystem
*d2util.Logger
2020-10-12 14:35:11 -07:00
filesToCheck *akara.Subscription
gameConfigs *akara.Subscription
Components struct {
GameConfig d2components.GameConfigFactory
File d2components.FileFactory
FileType d2components.FileTypeFactory
FileHandle d2components.FileHandleFactory
FileSource d2components.FileSourceFactory
Dirty d2components.DirtyFactory
}
activeConfig *d2components.GameConfig
}
// Init the world with the necessary components related to game config files
2020-10-12 14:35:11 -07:00
func (m *GameConfigSystem) Init(world *akara.World) {
m.World = world
m.setupLogger()
changes to d2components, d2systems, d2ui, d2enum go.mod, go.sum: * updating akara, bugfix in akara.EntityManager.RemoveEntity d2core * adding d2core/d2label * adding d2core/d2bitmapfont d2ui * exporting some constants for use elsewhere d2components * added bitmap font component (for ui labels) * added FileLoaded tag component to simplify asset loading filters * added locale component * FilePath component renamed to File * sprite component now contains the sprite and palette path as strings * adding ui label component d2enum * added locale as file type for file "/data/local/use" d2systems * changed most info prints to debug prints * removed unused scene graph testing file (oops!) * terminal is now rendered above mouse cursor scene * adding ui widget system for use by the game object factory * adding test scene for ui labels created with the ui widget system d2systems/AppBootstrap * added command line args for profiler * `--testscene labels` launches the label test * now adds the local file for processing * game loop init logic now inside of Init method (the call to world.Update does this) d2systems/AssetLoader * loads the locale file and adds a locale component that other systems can use * adds a FileLoaded component after finished loading a file which other systems can use (like the loading scene) d2systems/FileSourceResolver * Now looks for and uses the locale for language/charset filepath substitution d2systems/GameClientBootstrap * game loop init moved to end of AppBootstrap.Init d2systems/GameObjectFactory * embedding UI widget factory system d2systems/BaseScene * made base scene a little more clear by breaking the process into more methods d2systems/LoadingScene * simplified the entity subscriptions by using the new FileLoaded component d2systems/SceneObjectFactory * adding method for adding labels, buttons to scenes (buttons still WIP) d2systems/SceneSpriteSystem * the sprite system now maintains a cache of rendered sprites
2020-12-08 10:42:19 -08:00
m.Debug("initializing ...")
m.setupFactories()
m.setupSubscriptions()
}
func (m *GameConfigSystem) setupLogger() {
m.Logger = d2util.NewLogger()
m.SetPrefix(loggerPrefixGameConfig)
}
func (m *GameConfigSystem) setupFactories() {
changes to d2components, d2systems, d2ui, d2enum go.mod, go.sum: * updating akara, bugfix in akara.EntityManager.RemoveEntity d2core * adding d2core/d2label * adding d2core/d2bitmapfont d2ui * exporting some constants for use elsewhere d2components * added bitmap font component (for ui labels) * added FileLoaded tag component to simplify asset loading filters * added locale component * FilePath component renamed to File * sprite component now contains the sprite and palette path as strings * adding ui label component d2enum * added locale as file type for file "/data/local/use" d2systems * changed most info prints to debug prints * removed unused scene graph testing file (oops!) * terminal is now rendered above mouse cursor scene * adding ui widget system for use by the game object factory * adding test scene for ui labels created with the ui widget system d2systems/AppBootstrap * added command line args for profiler * `--testscene labels` launches the label test * now adds the local file for processing * game loop init logic now inside of Init method (the call to world.Update does this) d2systems/AssetLoader * loads the locale file and adds a locale component that other systems can use * adds a FileLoaded component after finished loading a file which other systems can use (like the loading scene) d2systems/FileSourceResolver * Now looks for and uses the locale for language/charset filepath substitution d2systems/GameClientBootstrap * game loop init moved to end of AppBootstrap.Init d2systems/GameObjectFactory * embedding UI widget factory system d2systems/BaseScene * made base scene a little more clear by breaking the process into more methods d2systems/LoadingScene * simplified the entity subscriptions by using the new FileLoaded component d2systems/SceneObjectFactory * adding method for adding labels, buttons to scenes (buttons still WIP) d2systems/SceneSpriteSystem * the sprite system now maintains a cache of rendered sprites
2020-12-08 10:42:19 -08:00
m.Debug("setting up component factories")
m.InjectComponent(&d2components.File{}, &m.Components.File.ComponentFactory)
m.InjectComponent(&d2components.FileType{}, &m.Components.FileType.ComponentFactory)
m.InjectComponent(&d2components.FileHandle{}, &m.Components.FileHandle.ComponentFactory)
m.InjectComponent(&d2components.FileSource{}, &m.Components.FileSource.ComponentFactory)
m.InjectComponent(&d2components.GameConfig{}, &m.Components.GameConfig.ComponentFactory)
m.InjectComponent(&d2components.Dirty{}, &m.Components.Dirty.ComponentFactory)
}
func (m *GameConfigSystem) setupSubscriptions() {
changes to d2components, d2systems, d2ui, d2enum go.mod, go.sum: * updating akara, bugfix in akara.EntityManager.RemoveEntity d2core * adding d2core/d2label * adding d2core/d2bitmapfont d2ui * exporting some constants for use elsewhere d2components * added bitmap font component (for ui labels) * added FileLoaded tag component to simplify asset loading filters * added locale component * FilePath component renamed to File * sprite component now contains the sprite and palette path as strings * adding ui label component d2enum * added locale as file type for file "/data/local/use" d2systems * changed most info prints to debug prints * removed unused scene graph testing file (oops!) * terminal is now rendered above mouse cursor scene * adding ui widget system for use by the game object factory * adding test scene for ui labels created with the ui widget system d2systems/AppBootstrap * added command line args for profiler * `--testscene labels` launches the label test * now adds the local file for processing * game loop init logic now inside of Init method (the call to world.Update does this) d2systems/AssetLoader * loads the locale file and adds a locale component that other systems can use * adds a FileLoaded component after finished loading a file which other systems can use (like the loading scene) d2systems/FileSourceResolver * Now looks for and uses the locale for language/charset filepath substitution d2systems/GameClientBootstrap * game loop init moved to end of AppBootstrap.Init d2systems/GameObjectFactory * embedding UI widget factory system d2systems/BaseScene * made base scene a little more clear by breaking the process into more methods d2systems/LoadingScene * simplified the entity subscriptions by using the new FileLoaded component d2systems/SceneObjectFactory * adding method for adding labels, buttons to scenes (buttons still WIP) d2systems/SceneSpriteSystem * the sprite system now maintains a cache of rendered sprites
2020-12-08 10:42:19 -08:00
m.Debug("setting up component subscriptions")
// we are going to check entities that dont yet have loaded asset types
filesToCheck := m.NewComponentFilter().
Require(
changes to d2components, d2systems, d2ui, d2enum go.mod, go.sum: * updating akara, bugfix in akara.EntityManager.RemoveEntity d2core * adding d2core/d2label * adding d2core/d2bitmapfont d2ui * exporting some constants for use elsewhere d2components * added bitmap font component (for ui labels) * added FileLoaded tag component to simplify asset loading filters * added locale component * FilePath component renamed to File * sprite component now contains the sprite and palette path as strings * adding ui label component d2enum * added locale as file type for file "/data/local/use" d2systems * changed most info prints to debug prints * removed unused scene graph testing file (oops!) * terminal is now rendered above mouse cursor scene * adding ui widget system for use by the game object factory * adding test scene for ui labels created with the ui widget system d2systems/AppBootstrap * added command line args for profiler * `--testscene labels` launches the label test * now adds the local file for processing * game loop init logic now inside of Init method (the call to world.Update does this) d2systems/AssetLoader * loads the locale file and adds a locale component that other systems can use * adds a FileLoaded component after finished loading a file which other systems can use (like the loading scene) d2systems/FileSourceResolver * Now looks for and uses the locale for language/charset filepath substitution d2systems/GameClientBootstrap * game loop init moved to end of AppBootstrap.Init d2systems/GameObjectFactory * embedding UI widget factory system d2systems/BaseScene * made base scene a little more clear by breaking the process into more methods d2systems/LoadingScene * simplified the entity subscriptions by using the new FileLoaded component d2systems/SceneObjectFactory * adding method for adding labels, buttons to scenes (buttons still WIP) d2systems/SceneSpriteSystem * the sprite system now maintains a cache of rendered sprites
2020-12-08 10:42:19 -08:00
&d2components.File{},
&d2components.FileType{},
&d2components.FileHandle{},
).
Forbid(
&d2components.GameConfig{},
&d2components.StringTable{},
&d2components.DataDictionary{},
&d2components.Palette{},
&d2components.PaletteTransform{},
&d2components.Cof{},
&d2components.Dc6{},
&d2components.Dcc{},
&d2components.Ds1{},
&d2components.Dt1{},
&d2components.Wav{},
&d2components.AnimationData{},
).
Build()
// we are interested in actual game config instances, too
gameConfigs := m.NewComponentFilter().
Require(&d2components.GameConfig{}).
Build()
m.filesToCheck = m.AddSubscription(filesToCheck)
m.gameConfigs = m.AddSubscription(gameConfigs)
}
// Update checks for new config files
func (m *GameConfigSystem) Update() {
2020-10-12 14:35:11 -07:00
m.checkForNewConfig(m.filesToCheck.GetEntities())
}
func (m *GameConfigSystem) checkForNewConfig(entities []akara.EID) {
for _, eid := range entities {
fp, found := m.Components.File.Get(eid)
2020-10-12 14:35:11 -07:00
if !found {
continue
}
ft, found := m.Components.FileType.Get(eid)
2020-10-12 14:35:11 -07:00
if !found {
continue
}
2020-10-12 14:35:11 -07:00
if fp.Path != configFileName || ft.Type != d2enum.FileTypeJSON {
continue
}
m.Info("loading config file ...")
2020-10-12 14:35:11 -07:00
m.loadConfig(eid)
}
}
func (m *GameConfigSystem) loadConfig(eid akara.EID) {
fh, found := m.Components.FileHandle.Get(eid)
2020-10-12 14:35:11 -07:00
if !found {
return
}
gameConfig := m.Components.GameConfig.Add(eid)
2020-10-12 14:35:11 -07:00
if err := json.NewDecoder(fh.Data).Decode(gameConfig); err != nil {
m.RemoveEntity(eid)
2020-10-12 14:35:11 -07:00
}
m.activeConfig = gameConfig
}