openquell/systems/pair_system.go

139 lines
3.3 KiB
Go
Raw Permalink Normal View History

package systems
import (
"openquell/components"
. "openquell/components"
. "openquell/config"
"openquell/grid"
"openquell/observers"
"github.com/hajimehoshi/ebiten/v2"
"github.com/mlange-42/arche/ecs"
"github.com/mlange-42/arche/generic"
)
type PairSystem struct {
World *ecs.World
DoorSelector *generic.Filter4[Position, Renderable, Bond, Door]
SwitchSelector *generic.Filter4[Position, Renderable, Bond, Switch]
GridContainer *grid.GridContainer
DoorMapper generic.Map4[
components.Position,
components.Renderable,
components.Bond,
components.Door]
}
type ToggleDoor struct {
Entity ecs.Entity
Open bool
}
func NewPairSystem(world *ecs.World, gridcontainer *grid.GridContainer) System {
doormapper := generic.NewMap4[
components.Position,
components.Renderable,
components.Bond,
components.Door](world)
system := &PairSystem{
DoorSelector: generic.NewFilter4[Position, Renderable, Bond, Door](),
SwitchSelector: generic.NewFilter4[Position, Renderable, Bond, Switch](),
World: world,
GridContainer: gridcontainer,
DoorMapper: doormapper,
}
return system
}
func (system *PairSystem) Update() error {
observer := observers.GetGameObserver(system.World)
posID := ecs.ComponentID[components.Position](system.World)
veloID := ecs.ComponentID[components.Velocity](system.World)
query := system.SwitchSelector.Query(system.World)
relID := ecs.ComponentID[Bond](system.World)
EntitiesToSwitch := []*ToggleDoor{}
for query.Next() {
swpos, _, _, switcher := query.Get()
for _, player := range observer.GetPlayers() {
if !system.World.Alive(player) {
continue
}
playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, newpos := swpos.Intersects(playerposition, playervelocity)
if ok {
// player moved on top of the switch
switcher.Toggle()
// open door
door := system.World.Relations().Get(query.Entity(), relID)
EntitiesToSwitch = append(EntitiesToSwitch,
&ToggleDoor{Entity: door, Open: true})
playervelocity.Change(Stop)
playerposition.Set(newpos)
}
}
}
2024-03-29 18:54:47 +01:00
doorquery := system.DoorSelector.Query(system.World)
for doorquery.Next() {
doorpos, _, _, door := doorquery.Get()
for _, player := range observer.GetPlayers() {
if !system.World.Alive(player) {
continue
}
playerposition := (*Position)(system.World.Get(player, posID))
playervelocity := (*Velocity)(system.World.Get(player, veloID))
ok, newpos := doorpos.Intersects(playerposition, playervelocity)
if ok && !door.IsOpen {
playervelocity.Change(Stop)
playerposition.Set(newpos)
}
}
}
for _, toggle := range EntitiesToSwitch {
_, _, _, door := system.DoorMapper.Get(toggle.Entity)
door.Toggle()
}
return nil
}
func (system *PairSystem) Draw(screen *ebiten.Image) {
op := &ebiten.DrawImageOptions{}
query := system.SwitchSelector.Query(system.World)
for query.Next() {
pos, _, _, switcher := query.Get()
op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(switcher.Sprite(), op)
}
doorquery := system.DoorSelector.Query(system.World)
for doorquery.Next() {
pos, _, _, door := doorquery.Get()
op.GeoM.Reset()
op.GeoM.Translate(float64(pos.X), float64(pos.Y))
screen.DrawImage(door.Sprite(), op)
}
}