diff --git a/internal/app/game_view.go b/internal/app/game_view.go index 7d479ce..507e0f1 100644 --- a/internal/app/game_view.go +++ b/internal/app/game_view.go @@ -37,14 +37,8 @@ func (v *gameView) handleEvent(ui *UI, e tcell.Event) bool { } 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.Entity) - v.room.Entities[e.ID] = e - v.me = e + // fuck lol + go ui.client.Send(sim.Move{dx, dy}) } func (v *gameView) draw(ui *UI) { diff --git a/internal/app/ui.go b/internal/app/ui.go index cba5cc7..28e20eb 100644 --- a/internal/app/ui.go +++ b/internal/app/ui.go @@ -22,6 +22,8 @@ func (ui *UI) Run() { ui.setupTerminal() defer ui.clearTerminal() + ui.room = new(wire.Room) + if err := ui.connect(); err != nil { return } @@ -44,7 +46,11 @@ func (ui *UI) Run() { ui.view = &gameView{ Log: ui.Child("game-view"), room: &room, - me: room.Entities[meta.Avatar], + me: &wire.Entity{ + ID: meta.Avatar, + Glyph: room.Entities[meta.Avatar].Glyph, + Position: room.Entities[meta.Avatar].Position, + }, } ui.Info("running ui") @@ -100,8 +106,10 @@ func (ui *UI) clearTerminal() { func (ui *UI) handleNotifications(c <-chan wire.Response) { for n := range c { if ui.handleNotification(n.Body) { - ui.view.draw(ui) - ui.screen.Show() + if ui.view != nil { + ui.view.draw(ui) + ui.screen.Show() + } } } ui.Info("notifications channel is closed so we must be done") @@ -115,7 +123,14 @@ func (ui *UI) handleNotification(v wire.Value) bool { switch n := v.(type) { case *wire.Entity: - ui.room.Entities[n.ID] = n + ui.room.Entities[n.ID] = *n + return true + + case *wire.Frame: + if ui.room == nil { + ui.room = new(wire.Room) + } + ui.room.Entities = n.Entities return true default: diff --git a/internal/server/sim/effect.go b/internal/server/sim/effect.go index 7600a44..8f7fce8 100644 --- a/internal/server/sim/effect.go +++ b/internal/server/sim/effect.go @@ -8,6 +8,5 @@ type Effect interface { } type result struct { - reply wire.Value - announce wire.Value + reply wire.Value } diff --git a/internal/server/sim/player.go b/internal/server/sim/player.go index 6dffe07..95ef8df 100644 --- a/internal/server/sim/player.go +++ b/internal/server/sim/player.go @@ -36,12 +36,7 @@ func (m *Move) exec(r *room, p *player, seq int) result { currentTile.here, nextTile.here = nil, p.avatar p.avatar.Position = target - e := wire.Entity{ - ID: p.avatar.ID, - Position: p.avatar.Position, - Glyph: p.avatar.Glyph, - } - return result{reply: e, announce: e} + return result{reply: wire.OK{}} } // SpawnPlayer is a request to spawn a player @@ -87,9 +82,9 @@ func (s *SpawnPlayer) exec(r *room, p *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, @@ -109,11 +104,6 @@ func (s *SpawnPlayer) exec(r *room, p *player, seq int) result { } return result{ reply: welcome, - announce: wire.Entity{ - ID: p.avatar.ID, - Position: p.avatar.Position, - Glyph: p.avatar.Glyph, - }, } } diff --git a/internal/server/sim/room.go b/internal/server/sim/room.go index c203c3a..2e5b486 100644 --- a/internal/server/sim/room.go +++ b/internal/server/sim/room.go @@ -25,14 +25,10 @@ func (r *room) update(dt time.Duration) { p.pending = nil res := req.Wants.exec(r, p, req.Seq) - p.outbox <- wire.Response{Re: req.Seq, Body: res.reply} - if res.announce != nil { - for _, p2 := range r.players { - if p2 == p { - continue - } - p2.outbox <- wire.Response{Body: res.announce} - } + if res.reply != nil { + p.outbox <- wire.Response{Re: req.Seq, Body: res.reply} + } else { + p.outbox <- wire.Response{Re: req.Seq, Body: wire.OK{}} } } @@ -41,19 +37,40 @@ func (r *room) update(dt time.Duration) { t.here.update(dt) } } + + frame := wire.Frame{ + Entities: r.allEntities(), + Players: r.playerAvatars(), + } + + for _, p := range r.players { + p.outbox <- wire.Response{Body: frame} + } } -func (r *room) allEntities() map[int]*entity { - all := make(map[int]*entity, 4) +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 - all[e.ID] = e + all[e.ID] = wire.Entity{ + ID: e.ID, + Position: e.Position, + Glyph: e.Glyph, + } } } return all } +func (r *room) playerAvatars() map[string]int { + all := make(map[string]int, len(r.players)) + for nick, p := range r.players { + all[nick] = p.avatar.ID + } + return all +} + func (r *room) addPlayer(p *player) { r.players[p.name] = p } diff --git a/internal/wire/frame.go b/internal/wire/frame.go new file mode 100644 index 0000000..f567121 --- /dev/null +++ b/internal/wire/frame.go @@ -0,0 +1,12 @@ +package wire + +type Frame struct { + Entities map[int]Entity `json:"entities"` + Players map[string]int `json:"players"` +} + +func (Frame) NetTag() string { return "frame" } + +func init() { + Register(func() Value { return new(Frame) }) +} diff --git a/internal/wire/room.go b/internal/wire/room.go index f47b850..deb1ef3 100644 --- a/internal/wire/room.go +++ b/internal/wire/room.go @@ -8,5 +8,5 @@ import ( type Room struct { Name string `json:"name"` math.Bounds `json:"bounds"` - Entities map[int]*Entity `json:"entities"` + Entities map[int]Entity `json:"entities"` }