rendering items, pick up, iventory re-make in progress to aloow item drop/wear/whatever
This commit is contained in:
parent
685dfeeeb1
commit
0a6c642dc2
@ -85,7 +85,7 @@ func main() {
|
|||||||
|
|
||||||
//set up controller
|
//set up controller
|
||||||
|
|
||||||
controller := ecs.NewController()
|
controller := ecs.NewController(mainCtx)
|
||||||
|
|
||||||
controller.MapComponentClass(ecs.CoordsComponent, types.Coords{})
|
controller.MapComponentClass(ecs.CoordsComponent, types.Coords{})
|
||||||
controller.MapComponentClass(ecs.AppearanceComponent, types.Appearance{})
|
controller.MapComponentClass(ecs.AppearanceComponent, types.Appearance{})
|
||||||
@ -93,16 +93,21 @@ func main() {
|
|||||||
controller.MapComponentClass(ecs.MoveableComponent, movement.Moveable{})
|
controller.MapComponentClass(ecs.MoveableComponent, movement.Moveable{})
|
||||||
controller.MapComponentClass(ecs.CarriedComponent, movement.Moveable{})
|
controller.MapComponentClass(ecs.CarriedComponent, movement.Moveable{})
|
||||||
controller.MapComponentClass(ecs.UsableComponent, movement.Moveable{})
|
controller.MapComponentClass(ecs.UsableComponent, movement.Moveable{})
|
||||||
|
controller.MapComponentClass(ecs.BackpackComponent, items.Backpack{})
|
||||||
|
|
||||||
moveable := movement.Moveable{
|
moveable := movement.Moveable{
|
||||||
Controller: controller,
|
Controller: controller,
|
||||||
Level: level,
|
Level: level,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items.Init(controller)
|
||||||
|
|
||||||
|
bp := items.Backpack{MaxMass:100, MaxBulk:100}
|
||||||
|
|
||||||
//Set up Screen Manager
|
//Set up Screen Manager
|
||||||
screenMgr := types.NewScreenManager(mainCtx)
|
screenMgr := types.NewScreenManager(mainCtx)
|
||||||
screenMgr.AddScreen("title", screens.NewTitleScreen(mw, screenMgr))
|
screenMgr.AddScreen("title", screens.NewTitleScreen(mw, screenMgr))
|
||||||
screenMgr.AddScreen("game", screens.NewGameScreen(mw, &State, vp, controller, screenMgr))
|
screenMgr.AddScreen("game", screens.NewGameScreen(mainCtx, mw, &State, vp, controller, screenMgr))
|
||||||
screenMgr.AddScreen("help", screens.NewMenuScreen(
|
screenMgr.AddScreen("help", screens.NewMenuScreen(
|
||||||
mw,
|
mw,
|
||||||
screenMgr,
|
screenMgr,
|
||||||
@ -128,25 +133,20 @@ func main() {
|
|||||||
}).MakeList(),
|
}).MakeList(),
|
||||||
)
|
)
|
||||||
|
|
||||||
screenMgr.AddScreen("inventory", screens.NewMenuScreen(
|
screenMgr.AddScreen("inventory", screens.InventoryScreen{
|
||||||
mw,
|
MenuScreen: screens.NewMenuScreen(
|
||||||
screenMgr,
|
mw,
|
||||||
"Inventory",
|
screenMgr,
|
||||||
"Items in your backpack:",
|
"Inventory",
|
||||||
//"[color=yellow]Note[/color]: Many of these are not implemented yet",
|
"Items in your backpack:",
|
||||||
"",
|
//"[color=yellow]Note[/color]: Many of these are not implemented yet",
|
||||||
types.NewCenteredRect(mw.Rect, 70, 25),
|
"",
|
||||||
true, ).
|
types.NewCenteredRect(mw.Rect, 70, 25),
|
||||||
SetBgColor("#ef305c70").
|
true, ).
|
||||||
SetFgColor("white").
|
SetBgColor("#ef305c70").
|
||||||
SetItems([]interface{}{
|
SetFgColor("white").
|
||||||
`"Fish-eye" crafty shaded glasses`,
|
SetItems([]interface{}{}).MakeList()
|
||||||
"Xecutor's glowing visor",
|
},
|
||||||
"Kitschy goggles of many pathways",
|
|
||||||
"Ring of inexistence",
|
|
||||||
"Orb of omniscience",
|
|
||||||
"Wand of amnesia",
|
|
||||||
}).MakeList(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
screenMgr.AddScreen("devmenu", screens.NewDevmenuScreen(
|
screenMgr.AddScreen("devmenu", screens.NewDevmenuScreen(
|
||||||
@ -174,7 +174,9 @@ func main() {
|
|||||||
|
|
||||||
controller.AddComponent(player, rooms[0].Center) //implicit Coords
|
controller.AddComponent(player, rooms[0].Center) //implicit Coords
|
||||||
controller.AddComponent(player, moveable)
|
controller.AddComponent(player, moveable)
|
||||||
|
controller.AddComponent(player, bp)
|
||||||
|
|
||||||
|
//fixme adding items
|
||||||
potion := controller.CreateEntity([]ecs.Component{})
|
potion := controller.CreateEntity([]ecs.Component{})
|
||||||
controller.AddComponent(potion, types.Appearance{
|
controller.AddComponent(potion, types.Appearance{
|
||||||
Glyph: types.PlainGlyphHolder{"!"},
|
Glyph: types.PlainGlyphHolder{"!"},
|
||||||
@ -182,11 +184,24 @@ func main() {
|
|||||||
Fg: types.PlainColorHolder{255, 55, 255, 222},
|
Fg: types.PlainColorHolder{255, 55, 255, 222},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
controller.AddComponent(potion, rooms[1].Center) //implicit Coords
|
controller.AddComponent(potion, rooms[0].Center) //implicit Coords
|
||||||
controller.AddComponent(potion, items.Carried{})
|
controller.AddComponent(potion, items.Carried{Mass:5, Bulk:3})
|
||||||
controller.AddComponent(potion, items.Usable{})
|
controller.AddComponent(potion, items.Usable{})
|
||||||
controller.AddComponent(potion, items.Consumable{})
|
controller.AddComponent(potion, items.Consumable{})
|
||||||
|
|
||||||
|
potion2 := controller.CreateEntity([]ecs.Component{})
|
||||||
|
controller.AddComponent(potion2, types.Appearance{
|
||||||
|
Glyph: types.PlainGlyphHolder{"!"},
|
||||||
|
ColorSet: types.TileColorSet{
|
||||||
|
Fg: types.PlainColorHolder{255, 222, 255, 55},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
controller.AddComponent(potion2, rooms[1].Center) //implicit Coords
|
||||||
|
controller.AddComponent(potion2, items.Carried{Mass:5, Bulk:3})
|
||||||
|
controller.AddComponent(potion2, items.Usable{})
|
||||||
|
controller.AddComponent(potion2, items.Consumable{})
|
||||||
|
//fixme end setting up items
|
||||||
|
|
||||||
State.Player = player
|
State.Player = player
|
||||||
State.Controller = controller
|
State.Controller = controller
|
||||||
|
|
||||||
|
@ -3,11 +3,13 @@ package ecs
|
|||||||
// ECS system by jcerise, github.com/jcerise/gogue
|
// ECS system by jcerise, github.com/jcerise/gogue
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
|
ctx context.Context
|
||||||
systems map[string]System
|
systems map[string]System
|
||||||
sortedSystems map[int][]System
|
sortedSystems map[int][]System
|
||||||
priorityKeys []int
|
priorityKeys []int
|
||||||
@ -21,8 +23,8 @@ type Controller struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewController is a convenience/constructor method to properly initialize a new processor
|
// NewController is a convenience/constructor method to properly initialize a new processor
|
||||||
func NewController() *Controller {
|
func NewController(ctx context.Context) *Controller {
|
||||||
controller := Controller{}
|
controller := Controller{ctx: ctx}
|
||||||
controller.systems = make(map[string]System)
|
controller.systems = make(map[string]System)
|
||||||
controller.sortedSystems = make(map[int][]System)
|
controller.sortedSystems = make(map[int][]System)
|
||||||
controller.priorityKeys = []int{}
|
controller.priorityKeys = []int{}
|
||||||
@ -78,7 +80,7 @@ func (c *Controller) GetMappedComponentClass(componentName string) Component {
|
|||||||
return c.componentMap[componentName]
|
return c.componentMap[componentName]
|
||||||
} else {
|
} else {
|
||||||
// TODO: Add better (read: actual) error handling here
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +208,7 @@ func (c *Controller) AddSystem(system System, priority int) {
|
|||||||
c.sortedSystems[priority] = append(c.sortedSystems[priority], system)
|
c.sortedSystems[priority] = append(c.sortedSystems[priority], system)
|
||||||
sort.Ints(c.priorityKeys)
|
sort.Ints(c.priorityKeys)
|
||||||
} else {
|
} 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
|
// ECS system by jcerise, github.com/jcerise/gogue
|
||||||
|
|
||||||
const MobRenderSystem = "mobrender"
|
const TerrainRenderSystem = "levelrender"
|
||||||
const TerrainRenderSystem = "terrainrender"
|
|
||||||
|
|
||||||
type System interface {
|
type System interface {
|
||||||
Process()
|
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
|
|
||||||
}
|
|
@ -124,6 +124,7 @@ func (ps *precomputedShade) FindByCoords(c types.Coords) (int, *Cell, error) {
|
|||||||
|
|
||||||
func (ps *precomputedShade) IsInFov(coords types.Coords) bool {
|
func (ps *precomputedShade) IsInFov(coords types.Coords) bool {
|
||||||
rc := ps.fromLevelCoords(coords)
|
rc := ps.fromLevelCoords(coords)
|
||||||
|
if rc.X == 0 && rc.Y ==0 {return true}
|
||||||
_, cell, err := ps.FindByCoords(rc)
|
_, cell, err := ps.FindByCoords(rc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
@ -30,4 +30,8 @@ func (b *Backpack) HasFreeSpace(Bulk, Mass int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backpack) GetItems() []ecs.Entity {
|
||||||
|
return b.items
|
||||||
}
|
}
|
@ -50,6 +50,8 @@ func (c Carried) Pickup(who, what ecs.Entity) {
|
|||||||
//remove coords instead (does not exist on map anymore)
|
//remove coords instead (does not exist on map anymore)
|
||||||
Controller.RemoveComponent(what, ecs.CoordsComponent)
|
Controller.RemoveComponent(what, ecs.CoordsComponent)
|
||||||
bp.items = append(bp.items, what)
|
bp.items = append(bp.items, what)
|
||||||
|
//fuck that, we need to update constantly
|
||||||
|
Controller.UpdateComponent(who, ecs.BackpackComponent, bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Carried) Drop(who, what ecs.Entity) {
|
func (c Carried) Drop(who, what ecs.Entity) {
|
||||||
@ -87,11 +89,12 @@ func (c *Carried) GetBulk(what ecs.Entity) int {
|
|||||||
return c.Bulk
|
return c.Bulk
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindCarriedOnTile(coords types.Coords) []ecs.Entity {
|
func FindCarriedUnder(who ecs.Entity) []ecs.Entity {
|
||||||
|
coords := Controller.GetComponent(who, ecs.CoordsComponent).(types.Coords)
|
||||||
carrieds := Controller.GetEntitiesWithComponent(ecs.CarriedComponent)
|
carrieds := Controller.GetEntitiesWithComponent(ecs.CarriedComponent)
|
||||||
result := make([]ecs.Entity, 0)
|
result := make([]ecs.Entity, 0)
|
||||||
for _, ent := range carrieds {
|
for _, ent := range carrieds {
|
||||||
car := Controller.GetComponent(ent, ecs.CarriedComponent)
|
car := Controller.GetComponent(ent, ecs.CoordsComponent)
|
||||||
if car == coords {
|
if car == coords {
|
||||||
result = append(result, ent)
|
result = append(result, ent)
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ package items
|
|||||||
|
|
||||||
import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
import "lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||||
|
|
||||||
var Controller ecs.Controller
|
var Controller *ecs.Controller
|
||||||
|
|
||||||
func Init(ctrl ecs.Controller) {
|
func Init(ctrl *ecs.Controller) {
|
||||||
Controller = ctrl
|
Controller = ctrl
|
||||||
}
|
}
|
@ -1,45 +1,47 @@
|
|||||||
package screens
|
package screens
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/ecs/systems"
|
"lab.zaar.be/thefish/alchemyst-go/engine/ecs/systems"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
"lab.zaar.be/thefish/alchemyst-go/engine/fov"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade"
|
"lab.zaar.be/thefish/alchemyst-go/engine/fov/precomputed_shade"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/items"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
|
"lab.zaar.be/thefish/alchemyst-go/engine/mob/movement"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
"lab.zaar.be/thefish/alchemyst-go/ui/mainwindow"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/util/appctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GameScreen struct {
|
type GameScreen struct {
|
||||||
|
ctx context.Context
|
||||||
mw *mainwindow.MainWindow
|
mw *mainwindow.MainWindow
|
||||||
state *gamestate.GameState
|
state *gamestate.GameState
|
||||||
vp *mainwindow.ViewPort
|
vp *mainwindow.ViewPort
|
||||||
controller *ecs.Controller
|
controller *ecs.Controller
|
||||||
scm *types.ScreenManager
|
scm *types.ScreenManager
|
||||||
fov fov.Fov
|
fov fov.Fov
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGameScreen(mw *mainwindow.MainWindow, state *gamestate.GameState, viewPort *mainwindow.ViewPort, controller *ecs.Controller, scm *types.ScreenManager) *GameScreen {
|
func NewGameScreen(ctx context.Context, mw *mainwindow.MainWindow, state *gamestate.GameState, viewPort *mainwindow.ViewPort, controller *ecs.Controller, scm *types.ScreenManager) *GameScreen {
|
||||||
ts := &GameScreen{mw: mw, state: state, vp: viewPort, controller: controller, scm: scm}
|
ts := &GameScreen{
|
||||||
|
ctx: ctx,
|
||||||
|
mw: mw,
|
||||||
|
state: state,
|
||||||
|
vp: viewPort,
|
||||||
|
controller: controller,
|
||||||
|
scm: scm,
|
||||||
|
}
|
||||||
|
|
||||||
//fixme move this to fov system
|
//fixme move this to fov system
|
||||||
computedFov := precomputed_shade.NewPrecomputedShade(15)
|
computedFov := precomputed_shade.NewPrecomputedShade(15)
|
||||||
computedFov.Init()
|
computedFov.Init()
|
||||||
ts.fov = computedFov
|
ts.fov = computedFov
|
||||||
|
|
||||||
renderMobs := systems.MobRenderSystem{
|
renderLevel := systems.NewLevelRenderSystem(state, ts.controller, viewPort, ts.mw.GetLayer("base"), ts.fov)
|
||||||
Controller: ts.controller,
|
go renderLevel.Listen()
|
||||||
Layer: ts.mw.GetLayer("base"),
|
ts.controller.AddSystem(renderLevel, 50)
|
||||||
Viewport: ts.vp,
|
|
||||||
Level: state.Level,
|
|
||||||
Fov: ts.fov,
|
|
||||||
}
|
|
||||||
ts.controller.AddSystem(renderMobs, 10)
|
|
||||||
renderTerrain := systems.NewTerrainRenderSystem(state, viewPort, ts.mw.GetLayer("base"), ts.fov)
|
|
||||||
go renderTerrain.Listen()
|
|
||||||
ts.controller.AddSystem(renderTerrain, 5)
|
|
||||||
|
|
||||||
return ts
|
return ts
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +52,8 @@ func (ts *GameScreen) Enter() {
|
|||||||
Print(1, ts.mw.H-2, "Press [color=white]?[/color] for help")
|
Print(1, ts.mw.H-2, "Press [color=white]?[/color] for help")
|
||||||
}
|
}
|
||||||
func (ts *GameScreen) Exit() {
|
func (ts *GameScreen) Exit() {
|
||||||
//trs := ts.controller.GetSystem(ecs.TerrainRenderSystem)
|
//trs := ts.controller.GetSystem(ecs.LevelRenderSystem)
|
||||||
//trs.(systems.TerrainRenderSystem).Close()
|
//trs.(systems.LevelRenderSystem).Close()
|
||||||
ts.mw.GetLayer("overlay").ClearArea(0, ts.mw.H-3, 30, 3)
|
ts.mw.GetLayer("overlay").ClearArea(0, ts.mw.H-3, 30, 3)
|
||||||
//remove what we dont need
|
//remove what we dont need
|
||||||
}
|
}
|
||||||
@ -90,6 +92,23 @@ func (ts *GameScreen) HandleInput(input string) {
|
|||||||
ts.scm.SetScreenByName("devmenu")
|
ts.scm.SetScreenByName("devmenu")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case "g":
|
||||||
|
//get list of carriables on tile
|
||||||
|
carrieds := items.FindCarriedUnder(ts.state.Player)
|
||||||
|
if len(carrieds) == 0 {
|
||||||
|
break
|
||||||
|
} //do nothing
|
||||||
|
//select if there is more than 1
|
||||||
|
if len(carrieds) > 1 {
|
||||||
|
appctx.Logger(ts.ctx).Warn().Msg("Passing item list to inventory not implemented yet")
|
||||||
|
} else {
|
||||||
|
//call pickup in selected
|
||||||
|
cc := items.Controller.GetComponent(carrieds[0], ecs.CarriedComponent).(items.Carried)
|
||||||
|
items.Carried.Pickup(cc, ts.state.Player, carrieds[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case "i":
|
case "i":
|
||||||
ts.scm.SetScreenByName("inventory")
|
ts.scm.SetScreenByName("inventory")
|
||||||
break
|
break
|
||||||
@ -104,4 +123,4 @@ func (ts *GameScreen) HandleInput(input string) {
|
|||||||
func (ts *GameScreen) Render() {
|
func (ts *GameScreen) Render() {
|
||||||
//ts.vp.Render(ts.state)
|
//ts.vp.Render(ts.state)
|
||||||
ts.controller.Process([]string{})
|
ts.controller.Process([]string{})
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,99 @@
|
|||||||
package screens
|
package screens
|
||||||
|
|
||||||
type InventoryScreen struct {
|
import (
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
|
||||||
|
"lab.zaar.be/thefish/alchemyst-go/engine/types"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryScreen struct {
|
||||||
|
*MenuScreen
|
||||||
|
items []ecs.Entity
|
||||||
|
|
||||||
|
cursor int
|
||||||
|
offset int
|
||||||
|
pageSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *InventoryScreen) UseEcs() bool {return true}
|
func (is *InventoryScreen) MakeInverntory() *InventoryScreen {
|
||||||
func (ts *InventoryScreen) Enter() {}
|
is.drawFunc = is.InventoryRender
|
||||||
func (ts *InventoryScreen) HandleInput(input string) {}
|
is.inputFunc = is.HandleInput
|
||||||
func (ts *InventoryScreen) Exit() {}
|
return is
|
||||||
func (ts *InventoryScreen) Render() {}
|
}
|
||||||
|
|
||||||
|
func (is *InventoryScreen) SetItems(items []ecs.Entity) *InventoryScreen {
|
||||||
|
is.items = items
|
||||||
|
return is
|
||||||
|
}
|
||||||
|
|
||||||
|
func (is *InventoryScreen) HandleInput(input string) {
|
||||||
|
switch input {
|
||||||
|
case "PageUp":
|
||||||
|
is.offset = is.offset - 1
|
||||||
|
if is.offset < 0 {
|
||||||
|
is.offset = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "PageDown":
|
||||||
|
is.offset = is.offset + 1
|
||||||
|
if is.offset > len(is.items)-1 {
|
||||||
|
is.offset = len(is.items) - 1
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "enter":
|
||||||
|
//select current under cursor
|
||||||
|
break;
|
||||||
|
case "a","b","c","d","e","f","g","h","i","j","k","l":
|
||||||
|
//selct by letter
|
||||||
|
break;
|
||||||
|
case "Escape":
|
||||||
|
fallthrough
|
||||||
|
case "Space":
|
||||||
|
is.scm.SetScreen(is.scm.PreviousScreen)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (is *InventoryScreen) InventoryRender() {
|
||||||
|
menuLayer := is.mw.GetLayer("menu")
|
||||||
|
menuLayer.ClearRect(is.Rect)
|
||||||
|
bgLayer := is.mw.GetLayer("menubg")
|
||||||
|
bgLayer.ClearRect(is.Rect)
|
||||||
|
bgLayer.WithColor(is.bgColor).NewWindow(is.Rect).Splash()
|
||||||
|
menuLayer.WithColor(is.fgColor).NewWindow(is.Rect).DoubleBordered(is.title)
|
||||||
|
menuLayer.Print(is.X+(is.W/2)-7, is.Y+is.H-1, "╡"+"[color=green]Space[/color] to close"+"╞")
|
||||||
|
footerHeight := 0
|
||||||
|
if is.footer != "" {
|
||||||
|
_, footerHeight = menuLayer.PrintInside(is.Rect, is.footer, 9)
|
||||||
|
footerHeight = footerHeight + 2
|
||||||
|
}
|
||||||
|
_, headerHeight := menuLayer.PrintInside(is.Rect, is.header, blt.TK_ALIGN_LEFT)
|
||||||
|
itemField := types.Rect{is.X, is.Y + headerHeight + 1, is.W, is.H - headerHeight - footerHeight}
|
||||||
|
_ = itemField
|
||||||
|
var ilw, ilh int
|
||||||
|
if (len(is.items) > 0) {
|
||||||
|
//fixme itemfield object, scroller, inputhandler, current selected item
|
||||||
|
menuItems := make([]string, 0)
|
||||||
|
for i := is.offset; i < len(is.items); i++ {
|
||||||
|
if string(is.items[i].(string)) != "" {
|
||||||
|
menuItems = append(menuItems, is.items[i].(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ilw, ilh = menuLayer.PrintInside(itemField, strings.Join(menuItems, "\n"), blt.TK_ALIGN_LEFT)
|
||||||
|
}
|
||||||
|
if ilh < len(is.items) {
|
||||||
|
is.drawScrollBar(menuLayer, itemField)
|
||||||
|
}
|
||||||
|
if ilw > itemField.W-4 {
|
||||||
|
fmt.Printf("Excess width of item names found! Need h-scroll of certain names")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//func (ms *InventoryScreen) UseEcs() bool {return true}
|
||||||
|
//func (ms *InventoryScreen) Enter() {}
|
||||||
|
|
||||||
|
//func (ms *InventoryScreen) Exit() {}
|
||||||
|
//func (ms *InventoryScreen) Render() {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user