1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-10 18:47:23 -05:00
OpenDiablo2/d2core/d2systems/scene_terminal.go

166 lines
3.4 KiB
Go
Raw Normal View History

package d2systems
import (
"image/color"
2020-12-04 03:11:19 -05:00
"time"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
)
const (
sceneKeyTerminal = "Terminal"
)
2020-12-04 03:11:19 -05:00
const (
viewportTerminal = iota + 1
)
// static check that TerminalScene implements the scene interface
var _ d2interface.Scene = &TerminalScene{}
// NewTerminalScene creates a new main menu scene. This is the first screen that the user
// will see when launching the game.
func NewTerminalScene() *TerminalScene {
scene := &TerminalScene{
BaseScene: NewBaseScene(sceneKeyTerminal),
}
2020-12-04 03:11:19 -05:00
scene.backgroundColor = color.Transparent
return scene
}
2020-12-04 03:11:19 -05:00
// TerminalScene represents the in-game terminal for typing commands
type TerminalScene struct {
*BaseScene
2020-12-04 03:11:19 -05:00
d2interface.Terminal
d2interface.InputManager
commandsToRegister *akara.Subscription
booted bool
}
2020-12-04 03:11:19 -05:00
// Init the terminal
func (s *TerminalScene) Init(world *akara.World) {
s.World = world
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 13:42:19 -05:00
s.Debug("initializing ...")
s.setupSubscriptions()
}
func (s *TerminalScene) 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 13:42:19 -05:00
s.Debug("setting up component subscriptions")
2020-12-04 03:11:19 -05:00
commandsToRegister := s.NewComponentFilter().
Require(
&d2components.CommandRegistration{},
&d2components.Dirty{},
).
Build()
s.commandsToRegister = s.World.AddSubscription(commandsToRegister)
}
func (s *TerminalScene) boot() {
if !s.BaseScene.booted {
s.BaseScene.boot()
return
}
2020-12-04 03:11:19 -05:00
s.createTerminal()
s.booted = true
}
2020-12-04 03:11:19 -05:00
// Update and render the terminal to the terminal viewport
func (s *TerminalScene) Update() {
for _, id := range s.Viewports {
s.Components.Priority.Add(id).Priority = scenePriorityTerminal
}
if s.Paused() {
return
}
if !s.booted {
s.boot()
}
2020-12-04 03:11:19 -05:00
if !s.booted {
return
}
s.processCommandRegistrations()
s.updateTerminal()
s.BaseScene.Update()
}
2020-12-04 03:11:19 -05:00
func (s *TerminalScene) processCommandRegistrations() {
for _, eid := range s.commandsToRegister.GetEntities() {
s.processCommand(eid)
}
}
func (s *TerminalScene) processCommand(eid akara.EID) {
reg, found := s.Components.CommandRegistration.Get(eid)
2020-12-04 03:11:19 -05:00
if !found {
return
}
s.Infof("Registering command `%s` - %s", reg.Name, reg.Description)
err := s.Terminal.BindAction(reg.Name, reg.Description, reg.Callback)
if err != nil {
s.Error(err.Error())
}
s.Components.Dirty.Remove(eid)
2020-12-04 03:11:19 -05:00
}
func (s *TerminalScene) createTerminal() {
inputManager := d2input.NewInputManager()
term, err := d2term.New(inputManager)
if err != nil {
panic(err)
}
s.InputManager = inputManager
s.Terminal = term
termVP := s.Add.Viewport(viewportTerminal, 800, 600)
texture, _ := s.Components.Texture.Get(termVP)
2020-12-04 03:11:19 -05:00
texture.Texture.Clear(color.Transparent)
alpha := s.Components.Alpha.Add(termVP)
2020-12-04 03:11:19 -05:00
alpha.Alpha = 0.5
vpFilter := s.Components.ViewportFilter.Add(termVP)
2020-12-04 03:11:19 -05:00
vpFilter.Set(viewportTerminal, true)
}
func (s *TerminalScene) updateTerminal() {
// this is a hack to use the old-style input manager and terminal
// stuff inside of this ECS implementation
_ = s.InputManager.Advance(s.TimeDelta.Seconds(), float64(time.Now().Second()))
_ = s.Terminal.Advance(s.TimeDelta.Seconds())
termVP := s.Viewports[viewportTerminal]
texture, _ := s.Components.Texture.Get(termVP)
2020-12-04 03:11:19 -05:00
texture.Texture.Clear(color.Transparent)
_ = s.Terminal.Render(texture.Texture)
}