1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-10 10:36:42 -05:00
OpenDiablo2/d2core/d2systems/game_config.go

145 lines
4.1 KiB
Go
Raw Normal View History

package d2systems
import (
2020-10-12 17:35:11 -04:00
"encoding/json"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
2020-10-12 17:35:11 -04: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 17:35:11 -04:00
var _ akara.System = &GameConfigSystem{}
const (
loggerPrefixGameConfig = "Game Config"
)
func NewGameConfigSystem() *GameConfigSystem {
2020-10-12 17:35:11 -04:00
// we are going to check entities that dont yet have loaded asset types
filesToCheck := akara.NewFilter().
2020-10-12 17:35:11 -04:00
Require(d2components.FilePath).
Require(d2components.FileType).
Require(d2components.FileHandle).
Forbid(d2components.GameConfig).
Forbid(d2components.StringTable).
Forbid(d2components.DataDictionary).
Forbid(d2components.Palette).
Forbid(d2components.PaletteTransform).
Forbid(d2components.Cof).
Forbid(d2components.Dc6).
Forbid(d2components.Dcc).
Forbid(d2components.Ds1).
Forbid(d2components.Dt1).
Forbid(d2components.Wav).
Forbid(d2components.AnimData).
Build()
2020-10-28 18:49:49 -04:00
// we are interested in actual game config instances, too
gameConfigs := akara.NewFilter().
Require(d2components.GameConfig).
Build()
2020-10-12 17:35:11 -04:00
gcs := &GameConfigSystem{
SubscriberSystem: akara.NewSubscriberSystem(filesToCheck, gameConfigs),
Logger: d2util.NewLogger(),
}
gcs.SetPrefix(loggerPrefixGameConfig)
return gcs
}
// 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 17:35:11 -04: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 systems because this system subscribes to entities
// with components created by these other systems. Nothing will break if these
// other systems are not present in the world, but no config files will be loaded by
// this system either...
type GameConfigSystem struct {
2020-10-12 17:35:11 -04:00
*akara.SubscriberSystem
*d2util.Logger
2020-10-12 17:35:11 -04:00
filesToCheck *akara.Subscription
gameConfigs *akara.Subscription
*d2components.GameConfigMap
*d2components.FilePathMap
*d2components.FileTypeMap
*d2components.FileHandleMap
*d2components.FileSourceMap
*d2components.DirtyMap
ActiveConfig *d2components.GameConfigComponent
}
2020-10-12 17:35:11 -04:00
func (m *GameConfigSystem) Init(world *akara.World) {
m.World = world
if world == nil {
m.SetActive(false)
return
}
m.Info("initializing ...")
for subIdx := range m.Subscriptions {
2020-10-28 18:49:49 -04:00
m.Subscriptions[subIdx] = m.AddSubscription(m.Subscriptions[subIdx].Filter)
}
2020-10-12 17:35:11 -04:00
m.filesToCheck = m.Subscriptions[0]
m.gameConfigs = m.Subscriptions[1]
// try to inject the components we require, then cast the returned
// abstract ComponentMap back to the concrete implementation
m.FilePathMap = world.InjectMap(d2components.FilePath).(*d2components.FilePathMap)
m.FileTypeMap = world.InjectMap(d2components.FileType).(*d2components.FileTypeMap)
m.FileHandleMap = world.InjectMap(d2components.FileHandle).(*d2components.FileHandleMap)
m.FileSourceMap = world.InjectMap(d2components.FileSource).(*d2components.FileSourceMap)
m.GameConfigMap = world.InjectMap(d2components.GameConfig).(*d2components.GameConfigMap)
m.DirtyMap = world.InjectMap(d2components.Dirty).(*d2components.DirtyMap)
}
func (m *GameConfigSystem) Update() {
2020-10-12 17:35:11 -04:00
m.checkForNewConfig(m.filesToCheck.GetEntities())
}
func (m *GameConfigSystem) checkForNewConfig(entities []akara.EID) {
for _, eid := range entities {
fp, found := m.GetFilePath(eid)
2020-10-12 17:35:11 -04:00
if !found {
continue
}
ft, found := m.GetFileType(eid)
2020-10-12 17:35:11 -04:00
if !found {
continue
}
2020-10-12 17:35:11 -04:00
if fp.Path != configFileName || ft.Type != d2enum.FileTypeJSON {
continue
}
m.Info("loading config file ...")
2020-10-12 17:35:11 -04:00
m.loadConfig(eid)
}
}
func (m *GameConfigSystem) loadConfig(eid akara.EID) {
fh, found := m.GetFileHandle(eid)
2020-10-12 17:35:11 -04:00
if !found {
return
}
gameConfig := m.AddGameConfig(eid)
2020-10-12 17:35:11 -04:00
if err := json.NewDecoder(fh.Data).Decode(gameConfig); err != nil {
m.GameConfigMap.Remove(eid)
2020-10-12 17:35:11 -04:00
}
m.ActiveConfig = gameConfig
}