diff --git a/internal/app/game_view.go b/internal/app/game_view.go index a390096..2d3b92a 100644 --- a/internal/app/game_view.go +++ b/internal/app/game_view.go @@ -10,12 +10,8 @@ import ( type gameView struct { *blammo.Log - roomName string - width int - height int - me wire.Entity - allRooms map[string]wire.Room - allEntities map[int]wire.Entity + room *wire.Room + me *wire.Entity } func (v *gameView) handleEvent(ui *UI, e tcell.Event) bool { @@ -40,59 +36,42 @@ func (v *gameView) handleEvent(ui *UI, e tcell.Event) bool { return true } -func (v *gameView) notify(wv wire.Value) { - v.Error("ignoring notifications at the moment: %v", wv) - switch z := wv.(type) { - case *wire.UpdateEntity: - if z.Room == v.roomName { - v.Info("we want to read this one: %v", z) - } - } -} - func (v *gameView) move(ui *UI, dx, dy int) { reply, err := ui.client.Send(sim.Move{dx, dy}) if err != nil { return } - e := reply.Body.(*wire.UpdateEntity) - // ughhhhhh - v.me = wire.Entity{ - ID: e.ID, - Position: e.Position, - Glyph: e.Glyph, - } - v.allEntities[e.ID] = v.me - // jfc this sucks - v.allRooms[v.roomName].Entities[e.ID] = v.me + e := reply.Body.(*wire.Entity) + v.room.Entities[e.ID] = e + v.me = e } func (v *gameView) draw(ui *UI) { offset := point{1, 1} // fill in background dots first - for x := 0; x < v.width; x++ { - for y := 0; y < v.height; y++ { + for x := 0; x < v.room.Width(); x++ { + for y := 0; y < v.room.Height(); y++ { ui.screen.SetContent(x+offset.x, y+offset.y, '·', nil, tcell.StyleDefault) } } // frame it ui.screen.SetContent(offset.x-1, offset.y-1, '┌', nil, tcell.StyleDefault) - ui.screen.SetContent(offset.x+v.width, offset.y-1, '┐', nil, tcell.StyleDefault) - ui.screen.SetContent(offset.x-1, offset.y+v.height, '└', nil, tcell.StyleDefault) - ui.screen.SetContent(offset.x+v.width, offset.y+v.height, '┘', nil, tcell.StyleDefault) - for x := 0; x < v.width; x++ { + ui.screen.SetContent(offset.x+v.room.Width(), offset.y-1, '┐', nil, tcell.StyleDefault) + ui.screen.SetContent(offset.x-1, offset.y+v.room.Height(), '└', nil, tcell.StyleDefault) + ui.screen.SetContent(offset.x+v.room.Width(), offset.y+v.room.Height(), '┘', nil, tcell.StyleDefault) + for x := 0; x < v.room.Width(); x++ { ui.screen.SetContent(x+offset.x, offset.y-1, '─', nil, tcell.StyleDefault) - ui.screen.SetContent(x+offset.x, offset.y+v.height, '─', nil, tcell.StyleDefault) + ui.screen.SetContent(x+offset.x, offset.y+v.room.Height(), '─', nil, tcell.StyleDefault) } - for y := 0; y < v.height; y++ { + for y := 0; y < v.room.Height(); y++ { ui.screen.SetContent(offset.x-1, y+offset.y, '│', nil, tcell.StyleDefault) - ui.screen.SetContent(offset.x+v.width, y+offset.y, '│', nil, tcell.StyleDefault) + ui.screen.SetContent(offset.x+v.room.Width(), y+offset.y, '│', nil, tcell.StyleDefault) } - for _, e := range v.allRooms[v.roomName].Entities { + for _, e := range v.room.Entities { pos := e.Position.Add(math.Vec{1, 1}) ui.screen.SetContent(pos.X, pos.Y, e.Glyph, nil, tcell.StyleDefault) } diff --git a/internal/app/ui.go b/internal/app/ui.go index ac02718..cba5cc7 100644 --- a/internal/app/ui.go +++ b/internal/app/ui.go @@ -14,6 +14,7 @@ type UI struct { PlayerName string screen tcell.Screen view view + room *wire.Room client *wire.Client } @@ -39,20 +40,11 @@ func (ui *UI) Run() { ui.Info("welcome: %v", welcome) meta := welcome.Players[ui.PlayerName] room := welcome.Rooms[meta.Room] - allEntities := make(map[int]wire.Entity) - for _, r := range welcome.Rooms { - for id, e := range r.Entities { - allEntities[id] = e - } - } + ui.room = &room ui.view = &gameView{ - Log: ui.Child("game-view"), - roomName: room.Name, - width: room.Width(), - height: room.Height(), - me: room.Entities[meta.Avatar], - allRooms: welcome.Rooms, - allEntities: allEntities, + Log: ui.Child("game-view"), + room: &room, + me: room.Entities[meta.Avatar], } ui.Info("running ui") @@ -107,10 +99,10 @@ func (ui *UI) clearTerminal() { func (ui *UI) handleNotifications(c <-chan wire.Response) { for n := range c { - ui.Info("ignoring notification: %v", n) - ui.view.notify(n.Body) - ui.view.draw(ui) - ui.screen.Show() + if ui.handleNotification(n.Body) { + ui.view.draw(ui) + ui.screen.Show() + } } ui.Info("notifications channel is closed so we must be done") ui.Info("clearing and finalizing screen from notifications goroutine") @@ -119,6 +111,19 @@ func (ui *UI) handleNotifications(c <-chan wire.Response) { ui.Info("screen finalized") } +func (ui *UI) handleNotification(v wire.Value) bool { + switch n := v.(type) { + + case *wire.Entity: + ui.room.Entities[n.ID] = n + return true + + default: + ui.Info("ignoring notification: %v", n) + return false + } +} + // writeString writes a string in the given style from left to right beginning // at the location (x, y). Writing of the screen just fails silently so don't // do that. diff --git a/internal/app/view.go b/internal/app/view.go index 65ae7c0..dec353e 100644 --- a/internal/app/view.go +++ b/internal/app/view.go @@ -2,11 +2,9 @@ package app import ( "github.com/gdamore/tcell/v2" - "github.com/jordanorelli/astro-domu/internal/wire" ) type view interface { handleEvent(*UI, tcell.Event) bool - notify(wire.Value) draw(*UI) } diff --git a/internal/server/sim/player.go b/internal/server/sim/player.go index b26af61..ce1add2 100644 --- a/internal/server/sim/player.go +++ b/internal/server/sim/player.go @@ -36,11 +36,10 @@ func (m *Move) exec(r *room, p *player, seq int) result { currentTile.here, nextTile.here = nil, p.avatar p.avatar.Position = target - e := wire.UpdateEntity{ - Room: r.name, + e := wire.Entity{ ID: p.avatar.ID, Position: p.avatar.Position, - Glyph: '@', + Glyph: p.avatar.Glyph, } return result{reply: e, announce: e} } @@ -89,9 +88,9 @@ func (s *SpawnPlayer) exec(r *room, _ *player, seq int) result { Rooms: make(map[string]wire.Room), Players: make(map[string]wire.Player), } - ents := make(map[int]wire.Entity) + ents := make(map[int]*wire.Entity) for id, e := range r.allEntities() { - ents[id] = wire.Entity{ + ents[id] = &wire.Entity{ ID: id, Position: e.Position, Glyph: e.Glyph, diff --git a/internal/server/sim/room.go b/internal/server/sim/room.go index 1f39882..912358e 100644 --- a/internal/server/sim/room.go +++ b/internal/server/sim/room.go @@ -22,11 +22,13 @@ func (r *room) update(dt time.Duration) { for _, req := range p.pending { res := req.Wants.exec(r, p, req.Seq) p.outbox <- wire.Response{Re: req.Seq, Body: res.reply} - for _, p2 := range r.players { - if p2 == p { - continue + if res.announce != nil { + for _, p2 := range r.players { + if p2 == p { + continue + } + p2.outbox <- wire.Response{Body: res.announce} } - p2.outbox <- wire.Response{Body: res.reply} } } p.pending = p.pending[0:0] diff --git a/internal/wire/entity.go b/internal/wire/entity.go index 17cb33b..b29947c 100644 --- a/internal/wire/entity.go +++ b/internal/wire/entity.go @@ -12,16 +12,6 @@ type Entity struct { func (Entity) NetTag() string { return "entity" } -type UpdateEntity struct { - Room string `json:"room"` - ID int `json:"id"` - Position math.Vec `json:"position"` - Glyph rune `json:"glyph"` -} - -func (UpdateEntity) NetTag() string { return "entity/updated" } - func init() { Register(func() Value { return new(Entity) }) - Register(func() Value { return new(UpdateEntity) }) } diff --git a/internal/wire/room.go b/internal/wire/room.go index 01706ee..6684aa3 100644 --- a/internal/wire/room.go +++ b/internal/wire/room.go @@ -6,9 +6,9 @@ import ( // Room represents a 2-dimensional coordinate space. type Room struct { - Name string `json:"name"` - Bounds math.Bounds `json:"bounds"` - Entities map[int]Entity `json:"entities"` + Name string `json:"name"` + Bounds math.Bounds `json:"bounds"` + Entities map[int]*Entity `json:"entities"` } func (r Room) Width() int { return r.Bounds.Width() }