rendering items, pick up, iventory re-make in progress to aloow item drop/wear/whatever
This commit is contained in:
@ -3,11 +3,13 @@ package ecs
|
||||
// ECS system by jcerise, github.com/jcerise/gogue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
ctx context.Context
|
||||
systems map[string]System
|
||||
sortedSystems map[int][]System
|
||||
priorityKeys []int
|
||||
@ -21,8 +23,8 @@ type Controller struct {
|
||||
}
|
||||
|
||||
// NewController is a convenience/constructor method to properly initialize a new processor
|
||||
func NewController() *Controller {
|
||||
controller := Controller{}
|
||||
func NewController(ctx context.Context) *Controller {
|
||||
controller := Controller{ctx: ctx}
|
||||
controller.systems = make(map[string]System)
|
||||
controller.sortedSystems = make(map[int][]System)
|
||||
controller.priorityKeys = []int{}
|
||||
@ -78,7 +80,7 @@ func (c *Controller) GetMappedComponentClass(componentName string) Component {
|
||||
return c.componentMap[componentName]
|
||||
} else {
|
||||
// TODO: Add better (read: actual) error handling here
|
||||
fmt.Printf("Component[%s] not registered on Controller.\n", componentName)
|
||||
appctx.Logger(c.ctx).Warn().Msgf("Component[%s] not registered on Controller.\n", componentName)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -206,7 +208,7 @@ func (c *Controller) AddSystem(system System, priority int) {
|
||||
c.sortedSystems[priority] = append(c.sortedSystems[priority], system)
|
||||
sort.Ints(c.priorityKeys)
|
||||
} else {
|
||||
fmt.Printf("A system of type %v was already added to the controller %v!", systemType, c)
|
||||
appctx.Logger(c.ctx).Warn().Msgf("A system of type %v was already added to the controller %v!", systemType, c)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,7 @@ package ecs
|
||||
|
||||
// ECS system by jcerise, github.com/jcerise/gogue
|
||||
|
||||
const MobRenderSystem = "mobrender"
|
||||
const TerrainRenderSystem = "terrainrender"
|
||||
const TerrainRenderSystem = "levelrender"
|
||||
|
||||
type System interface {
|
||||
Process()
|
||||
|
160
engine/ecs/systems/level_render_system.go
Normal file
160
engine/ecs/systems/level_render_system.go
Normal file
@ -0,0 +1,160 @@
|
||||
package systems
|
||||
|
||||
import (
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
var fovRecompute = true
|
||||
var redraw = false
|
||||
|
||||
type LevelRenderSystem struct {
|
||||
Viewport *mainwindow.ViewPort
|
||||
Controller *ecs.Controller
|
||||
state *gamestate.GameState
|
||||
layer *mainwindow.Layer
|
||||
fov fov.Fov
|
||||
animateTiles *time.Ticker
|
||||
TorchRadius int
|
||||
}
|
||||
|
||||
func NewLevelRenderSystem(
|
||||
state *gamestate.GameState,
|
||||
controller *ecs.Controller,
|
||||
vp *mainwindow.ViewPort,
|
||||
layer *mainwindow.Layer,
|
||||
fov fov.Fov,
|
||||
) LevelRenderSystem {
|
||||
|
||||
trs := LevelRenderSystem{
|
||||
Viewport: vp,
|
||||
Controller: controller,
|
||||
layer: layer,
|
||||
state: state,
|
||||
fov: fov,
|
||||
}
|
||||
|
||||
trs.TorchRadius = 12 //fixme move to sight component
|
||||
|
||||
trs.animateTiles = time.NewTicker(time.Second / 12)
|
||||
|
||||
return trs
|
||||
}
|
||||
|
||||
//fixme add to screens/game Exit()
|
||||
func (trs LevelRenderSystem) Close() {
|
||||
trs.animateTiles.Stop()
|
||||
trs.animateTiles = nil //zero pointer to ticker
|
||||
}
|
||||
|
||||
func (trs LevelRenderSystem) Listen() {
|
||||
for {
|
||||
select {
|
||||
case <-trs.state.FovRecompute:
|
||||
fovRecompute = true
|
||||
case <-trs.state.Redraw:
|
||||
redraw = true
|
||||
case <-trs.animateTiles.C:
|
||||
redraw = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type priorityRenderable struct {
|
||||
types.Appearance
|
||||
types.Coords
|
||||
Priority int //with bigger are rendered last
|
||||
}
|
||||
|
||||
type prioritySorter []priorityRenderable
|
||||
|
||||
func (a prioritySorter) Len() int { return len(a) }
|
||||
func (a prioritySorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a prioritySorter) Less(i, j int) bool { return a[i].Priority < a[j].Priority }
|
||||
|
||||
func (trs LevelRenderSystem) Process() {
|
||||
playerCoords := trs.state.Controller.GetComponent(trs.state.Player, ecs.CoordsComponent).(types.Coords)
|
||||
|
||||
trs.Viewport.Move(trs.state, playerCoords)
|
||||
|
||||
if fovRecompute {
|
||||
trs.layer.ClearRect(trs.Viewport.Rect)
|
||||
trs.fov.ComputeFov(trs.state.Level, playerCoords, trs.TorchRadius)
|
||||
fovRecompute = false
|
||||
redraw = true
|
||||
}
|
||||
|
||||
if redraw {
|
||||
//terrain
|
||||
for y := 0; y < trs.Viewport.H; y++ {
|
||||
for x := 0; x < trs.Viewport.W; x++ {
|
||||
mapCoords := types.Coords{trs.Viewport.CameraCoords.X + x, trs.Viewport.CameraCoords.Y + y}
|
||||
|
||||
if trs.state.Level.InBounds(mapCoords) {
|
||||
tile := trs.state.Level.GetTile(mapCoords)
|
||||
if tile.Explored || tile.Visible {
|
||||
trs.layer.PutToBase(
|
||||
x+trs.Viewport.X,
|
||||
y+trs.Viewport.Y,
|
||||
tile.GetChar(),
|
||||
tile.GetRawColor(),
|
||||
tile.GetRawBgColor(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//mobs
|
||||
entToRender := make([]priorityRenderable, 0)
|
||||
for e := range trs.Controller.GetEntities() {
|
||||
if trs.Controller.HasComponent(e, ecs.CoordsComponent) &&
|
||||
trs.Controller.HasComponent(e, ecs.AppearanceComponent) {
|
||||
|
||||
pos := trs.Controller.GetComponent(e, ecs.CoordsComponent).(types.Coords)
|
||||
appearance := trs.Controller.GetComponent(e, ecs.AppearanceComponent).(types.Appearance)
|
||||
|
||||
//fixme fov check
|
||||
if !trs.state.Level.GetTile(pos).Visible {
|
||||
continue
|
||||
}
|
||||
|
||||
vpc, err := trs.Viewport.ToVPCoords(pos)
|
||||
if err != nil {
|
||||
continue //we cant see it? no problem.
|
||||
}
|
||||
//Костыль для приоритета отрисовки
|
||||
p := 0
|
||||
if trs.Controller.HasComponent(e, ecs.CarriedComponent) {
|
||||
p = 10
|
||||
}
|
||||
if trs.Controller.HasComponent(e, ecs.MoveableComponent) {
|
||||
p = 100
|
||||
}
|
||||
|
||||
entToRender = append(entToRender, priorityRenderable{
|
||||
Appearance: appearance,
|
||||
Coords: vpc,
|
||||
Priority: p,
|
||||
})
|
||||
}
|
||||
}
|
||||
sort.Sort(prioritySorter(entToRender))
|
||||
|
||||
for _, ree := range entToRender {
|
||||
trs.layer.WithRawColor(ree.Appearance.ColorSet.Fg.GetColor()).
|
||||
Put(ree.X, ree.Y, ree.Appearance.Glyph.GetGlyph())
|
||||
}
|
||||
entToRender = nil
|
||||
redraw = false
|
||||
}
|
||||
}
|
||||
|
||||
func (trs LevelRenderSystem) SystemType() string {
|
||||
return ecs.TerrainRenderSystem
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package systems
|
||||
|
||||
import (
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||
)
|
||||
|
||||
type MobRenderSystem struct {
|
||||
Controller *ecs.Controller
|
||||
Layer *mainwindow.Layer
|
||||
Viewport *mainwindow.ViewPort
|
||||
Fov fov.Fov
|
||||
*gamemap.Level
|
||||
}
|
||||
|
||||
func (mrs MobRenderSystem) Process() {
|
||||
//if redraw {
|
||||
for e := range mrs.Controller.GetEntities() {
|
||||
if mrs.Controller.HasComponent(e, ecs.CoordsComponent) &&
|
||||
mrs.Controller.HasComponent(e, ecs.AppearanceComponent) {
|
||||
|
||||
pos := mrs.Controller.GetComponent(e, ecs.CoordsComponent).(types.Coords)
|
||||
appearance := mrs.Controller.GetComponent(e, ecs.AppearanceComponent).(types.Appearance)
|
||||
|
||||
//fixme fov check
|
||||
//if !mrs.Fov.IsInFov(pos) {
|
||||
// continue
|
||||
//}
|
||||
|
||||
vpc, err := mrs.Viewport.ToVPCoords(pos)
|
||||
if err != nil {
|
||||
continue //we cant see it? no problem.
|
||||
}
|
||||
mrs.Layer.WithRawColor(appearance.ColorSet.Fg.GetColor()).Put(vpc.X, vpc.Y, appearance.Glyph.GetGlyph())
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
func (mrs MobRenderSystem) SystemType() string {
|
||||
return ecs.MobRenderSystem
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package systems
|
||||
|
||||
import (
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||
"time"
|
||||
)
|
||||
|
||||
var fovRecompute = true
|
||||
var redraw = false
|
||||
|
||||
|
||||
type TerrainRenderSystem struct {
|
||||
Viewport *mainwindow.ViewPort
|
||||
state *gamestate.GameState
|
||||
layer *mainwindow.Layer
|
||||
fov fov.Fov
|
||||
animateTiles *time.Ticker
|
||||
TorchRadius int
|
||||
}
|
||||
|
||||
func NewTerrainRenderSystem(
|
||||
state *gamestate.GameState,
|
||||
vp *mainwindow.ViewPort,
|
||||
layer *mainwindow.Layer,
|
||||
fov fov.Fov,
|
||||
) TerrainRenderSystem {
|
||||
|
||||
trs := TerrainRenderSystem{
|
||||
Viewport:vp,
|
||||
layer: layer,
|
||||
state: state,
|
||||
fov: fov,
|
||||
}
|
||||
|
||||
trs.TorchRadius = 12 //fixme move to sight component
|
||||
|
||||
trs.animateTiles = time.NewTicker(time.Second / 12)
|
||||
|
||||
|
||||
return trs
|
||||
}
|
||||
|
||||
//fixme add to screens/game Exit()
|
||||
func (trs TerrainRenderSystem) Close() {
|
||||
trs.animateTiles.Stop()
|
||||
trs.animateTiles = nil //zero pointer to ticker
|
||||
}
|
||||
|
||||
func (trs TerrainRenderSystem) Listen() {
|
||||
for {
|
||||
select {
|
||||
case <-trs.state.FovRecompute:
|
||||
fovRecompute = true
|
||||
case <-trs.state.Redraw:
|
||||
redraw = true
|
||||
case <-trs.animateTiles.C:
|
||||
redraw = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (trs TerrainRenderSystem) Process() {
|
||||
playerCoords := trs.state.Controller.GetComponent(trs.state.Player, ecs.CoordsComponent).(types.Coords)
|
||||
|
||||
trs.Viewport.Move(trs.state, playerCoords)
|
||||
|
||||
if fovRecompute {
|
||||
trs.layer.ClearRect(trs.Viewport.Rect)
|
||||
trs.fov.ComputeFov(trs.state.Level, playerCoords, trs.TorchRadius)
|
||||
fovRecompute = false
|
||||
redraw = true
|
||||
}
|
||||
|
||||
if redraw {
|
||||
//terrain
|
||||
for y := 0; y < trs.Viewport.H; y++ {
|
||||
for x := 0; x < trs.Viewport.W; x++ {
|
||||
mapCoords := types.Coords{trs.Viewport.CameraCoords.X + x, trs.Viewport.CameraCoords.Y + y}
|
||||
|
||||
if trs.state.Level.InBounds(mapCoords) {
|
||||
tile := trs.state.Level.GetTile(mapCoords)
|
||||
if tile.Explored || tile.Visible {
|
||||
trs.layer.PutToBase(
|
||||
x+trs.Viewport.X,
|
||||
y+trs.Viewport.Y,
|
||||
tile.GetChar(),
|
||||
tile.GetRawColor(),
|
||||
tile.GetRawBgColor(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
redraw = false
|
||||
}
|
||||
}
|
||||
|
||||
func (trs TerrainRenderSystem) SystemType() string {
|
||||
return ecs.TerrainRenderSystem
|
||||
}
|
Reference in New Issue
Block a user