161 lines
3.9 KiB
Go
161 lines
3.9 KiB
Go
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{X: trs.Viewport.CameraCoords.X + x, Y: 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
|
|
}
|