diff --git a/internal/math/vec.go b/internal/math/vec.go index 0b439ee..8f23fdd 100644 --- a/internal/math/vec.go +++ b/internal/math/vec.go @@ -24,3 +24,21 @@ func (v *Vec) UnmarshalJSON(b []byte) error { } func (v Vec) Add(v2 Vec) Vec { return Vec{v.X + v2.X, v.Y + v2.Y} } + +func (v Vec) Unit() Vec { + var out Vec + switch { + case v.X < 0: + out.X = -1 + case v.X > 0: + out.X = 1 + } + + switch { + case v.Y < 0: + out.Y = -1 + case v.Y > 0: + out.Y = 1 + } + return out +} diff --git a/internal/server/session.go b/internal/server/session.go index bd619a5..ae9d273 100644 --- a/internal/server/session.go +++ b/internal/server/session.go @@ -86,7 +86,7 @@ func (sn *session) read() { var req wire.Request if err := json.Unmarshal(b, &req); err != nil { sn.Error("unable to parse request: %v", err) - sn.outbox <- wire.ErrorResponse(0, "unable to parse request: %v", err) + sn.outbox <- wire.ErrorResponse(req.Seq, "unable to parse request: %v", err) break } sn.Info("received message of type %T", req.Body) diff --git a/internal/server/sim/player.go b/internal/server/sim/player.go index cb9b9b1..fde03ee 100644 --- a/internal/server/sim/player.go +++ b/internal/server/sim/player.go @@ -12,7 +12,7 @@ type player struct { *room name string outbox chan wire.Response - pending []Request + pending *Request avatar *entity } @@ -70,14 +70,13 @@ func (s *SpawnPlayer) exec(r *room, p *player, seq int) result { behavior: doNothing{}, } p := &player{ - Log: r.Log.Child("players").Child(s.Name), - room: r, - name: s.Name, - outbox: s.Outbox, - pending: make([]Request, 0, 32), - avatar: avatar, + Log: r.Log.Child("players").Child(s.Name), + room: r, + name: s.Name, + outbox: s.Outbox, + avatar: avatar, } - p.pending = append(p.pending, Request{Seq: seq, From: s.Name, Wants: s}) + p.pending = &Request{Seq: seq, From: s.Name, Wants: s} r.players[s.Name] = p r.tiles[0].here = p.avatar s.queued = true diff --git a/internal/server/sim/room.go b/internal/server/sim/room.go index 912358e..adb66e7 100644 --- a/internal/server/sim/room.go +++ b/internal/server/sim/room.go @@ -19,19 +19,22 @@ type room struct { func (r *room) update(dt time.Duration) { for _, p := range r.players { - for _, req := range p.pending { - 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 p.pending == nil { + continue + } + req := p.pending + 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} } } - p.pending = p.pending[0:0] } for _, t := range r.tiles { diff --git a/internal/server/sim/world.go b/internal/server/sim/world.go index 3bddc5c..e0311a8 100644 --- a/internal/server/sim/world.go +++ b/internal/server/sim/world.go @@ -78,7 +78,11 @@ func (w *World) Run(hz int) { w.Error("received non login request of type %T from unknown player %q", req.Wants, req.From) } - p.pending = append(p.pending, req) + if p.pending == nil { + p.pending = &req + } else { + p.outbox <- wire.ErrorResponse(req.Seq, "you already have a request for this frame") + } case <-ticker.C: w.tick(time.Since(lastTick))