From bfb399d89d182cc78d1753c6873e8d3d3f6b22d9 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Wed, 4 Nov 2020 05:24:42 +0000 Subject: [PATCH] a tile can have more than one entity now but there can only be one solid entity per tile --- internal/sim/entity.go | 1 + internal/sim/player.go | 28 ++++++++++++++-------------- internal/sim/room.go | 9 ++------- internal/sim/tile.go | 24 +++++++++++++++++++++++- internal/sim/world.go | 5 +++-- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/internal/sim/entity.go b/internal/sim/entity.go index 71c5ab7..5d481f8 100644 --- a/internal/sim/entity.go +++ b/internal/sim/entity.go @@ -10,6 +10,7 @@ type entity struct { ID int `json:"id"` Position math.Vec `json:"pos"` Glyph rune `json:"glyph"` + solid bool `json:"-"` behavior } diff --git a/internal/sim/player.go b/internal/sim/player.go index a45303a..1b155a0 100644 --- a/internal/sim/player.go +++ b/internal/sim/player.go @@ -155,18 +155,19 @@ func sendResponse(conn *websocket.Conn, res wire.Response) error { type spawnPlayer struct{} func (s spawnPlayer) exec(w *world, r *room, p *player, seq int) result { + e := entity{ + ID: <-w.nextID, + Glyph: '@', + solid: true, + behavior: doNothing{}, + } + p.avatar = &e + for n, t := range r.tiles { - if t.here == nil { - x, y := n%r.Width, n/r.Width - e := entity{ - ID: <-w.nextID, - Position: math.Vec{x, y}, - Glyph: '@', - behavior: doNothing{}, - } - p.avatar = &e - t.here = &e - break + x, y := n%r.Width, n/r.Width + e.Position = math.Vec{x, y} + if t.addEntity(&e) { + return result{} } } return result{} @@ -186,11 +187,10 @@ func (m *Move) exec(w *world, r *room, p *player, seq int) result { currentTile := r.getTile(pos) nextTile := r.getTile(target) - if nextTile.here != nil { + if !nextTile.addEntity(p.avatar) { return result{reply: wire.Errorf("target cell (%d, %d) is occupied", target.X, target.Y)} } - - currentTile.here, nextTile.here = nil, p.avatar + currentTile.removeEntity(p.avatar.ID) p.avatar.Position = target return result{reply: wire.OK{}} } diff --git a/internal/sim/room.go b/internal/sim/room.go index f89e5a8..5a1d68b 100644 --- a/internal/sim/room.go +++ b/internal/sim/room.go @@ -17,8 +17,7 @@ type room struct { func (r *room) allEntities() map[int]wire.Entity { all := make(map[int]wire.Entity, 4) for _, t := range r.tiles { - if t.here != nil { - e := t.here + for _, e := range t.here { all[e.ID] = wire.Entity{ ID: e.ID, Position: e.Position, @@ -42,11 +41,7 @@ func (r *room) addEntity(e *entity) bool { if t == nil { return false } - if t.here != nil { - return false - } - t.here = e - return true + return t.addEntity(e) } func (r *room) addPlayer(p *player) { diff --git a/internal/sim/tile.go b/internal/sim/tile.go index 1e5ad41..8c05353 100644 --- a/internal/sim/tile.go +++ b/internal/sim/tile.go @@ -2,5 +2,27 @@ package sim type tile struct { floor floor - here *entity + here []*entity +} + +func (t *tile) addEntity(e *entity) bool { + if e.solid { + for _, other := range t.here { + if other.solid { + return false + } + } + } + t.here = append(t.here, e) + return true +} + +func (t *tile) removeEntity(id int) { + here := t.here[:0] + for _, e := range t.here { + if e.ID != id { + here = append(here, e) + } + } + t.here = here } diff --git a/internal/sim/world.go b/internal/sim/world.go index f9bffca..127381c 100644 --- a/internal/sim/world.go +++ b/internal/sim/world.go @@ -43,6 +43,7 @@ func newWorld(log *blammo.Log) *world { ID: -1, Position: math.Vec{5, 5}, Glyph: 'd', + solid: true, behavior: doNothing{}, }) @@ -203,8 +204,8 @@ func (w *world) tick(d time.Duration) { // run all object effects for _, r := range w.rooms { for _, t := range r.tiles { - if t.here != nil { - t.here.update(d) + for _, e := range t.here { + e.update(d) } }