player spawninnnnnng into a room now

master
Jordan Orelli 4 years ago
parent 77682ac01e
commit 55d638c7f0

@ -108,7 +108,6 @@ func (s *Server) dropSession(sn *session) {
close(sn.done)
delete(s.sessions, sn.id)
s.world.DespawnPlayer(sn.entityID)
s.waitOnSessions.Add(-1)
s.Info("dropped session %d after %v time connected, %d sessions active", sn.id, time.Since(sn.start), len(s.sessions))

@ -96,17 +96,17 @@ func (sn *session) read() {
sn.Name = v.Name
sn.world.Inbox <- sim.Request{
From: sn.Name,
Wants: sim.SpawnPlayer{
Seq: req.Seq,
Wants: &sim.SpawnPlayer{
Outbox: sn.outbox,
},
}
sn.outbox <- wire.Response{req.Seq, wire.OK{}}
case sim.Effect:
sn.world.Inbox <- sim.Request{
From: sn.Name,
Seq: req.Seq,
Wants: v,
}
sn.outbox <- wire.Response{req.Seq, wire.OK{}}
default:
sn.outbox <- wire.ErrorResponse(req.Seq, "not sure how to handle that")
}

@ -4,5 +4,10 @@ import "github.com/jordanorelli/astro-domu/internal/wire"
type Effect interface {
wire.Value
exec(*World, string)
exec(*room, string, int) result
}
type result struct {
reply wire.Value
announce wire.Value
}

@ -10,8 +10,10 @@ import (
// player represents a player character in the simulation
type player struct {
*blammo.Log
sessionID int
*room
name string
outbox chan wire.Response
sessionID int
entityID int
pending []Request
}
@ -24,13 +26,41 @@ type Move [2]int
func (Move) NetTag() string { return "move" }
func (m *Move) exec(r *room, from *player, seq int) {
}
// SpawnPlayer is a request to spawn a player
type SpawnPlayer struct {
Outbox chan wire.Response
queued bool
}
func (s SpawnPlayer) exec(w *World, from string) {
w.Info("spawn player requested for: %s", from)
func (s *SpawnPlayer) exec(r *room, from string, seq int) result {
if !s.queued {
r.Info("spawn player requested for: %s", from)
if _, ok := r.players[from]; ok {
s.Outbox <- wire.ErrorResponse(seq, "a player is already logged in as %q", from)
return result{}
}
p := &player{
Log: r.Log.Child("players").Child(from),
room: r,
name: from,
outbox: s.Outbox,
pending: make([]Request, 0, 32),
}
p.pending = append(p.pending, Request{Seq: seq, From: from, Wants: s})
r.players[from] = p
s.queued = true
return result{}
}
return result{
reply: Welcome{Room: r.name},
}
}
func (SpawnPlayer) NetTag() string { return "player/spawn" }
@ -40,6 +70,13 @@ type PlayerSpawned struct {
Name string
}
type Welcome struct {
Room string `json:"room"`
}
func (Welcome) NetTag() string { return "player/welcome" }
func init() {
wire.Register(func() wire.Value { return new(Move) })
wire.Register(func() wire.Value { return new(Welcome) })
}

@ -2,5 +2,6 @@ package sim
type Request struct {
From string
Seq int
Wants Effect
}

@ -3,22 +3,46 @@ package sim
import (
"time"
"github.com/jordanorelli/astro-domu/internal/wire"
"github.com/jordanorelli/blammo"
)
type room struct {
*blammo.Log
name string
origin point
width int
height int
tiles []tile
name string
origin point
width int
height int
tiles []tile
players map[string]*player
}
func (r *room) update(dt time.Duration) {
// announcements := make([]result, 0, 8)
for _, p := range r.players {
for _, req := range p.pending {
res := req.Wants.exec(r, p.name, req.Seq)
p.outbox <- wire.Response{Re: req.Seq, Body: res.reply}
}
p.pending = p.pending[0:0]
}
for _, t := range r.tiles {
for _, e := range t.contents {
e.update(dt)
}
}
}
func (r *room) addPlayer(p *player) {
r.players[p.name] = p
}
func (r *room) removePlayer(name string) bool {
if _, ok := r.players[name]; ok {
delete(r.players, name)
return true
}
return false
}

@ -3,6 +3,7 @@ package sim
import (
"time"
"github.com/jordanorelli/astro-domu/internal/wire"
"github.com/jordanorelli/blammo"
)
@ -19,12 +20,13 @@ type World struct {
func NewWorld(log *blammo.Log) *World {
foyer := room{
Log: log.Child("foyer"),
name: "foyer",
origin: point{0, 0},
width: 10,
height: 10,
tiles: make([]tile, 100),
Log: log.Child("foyer"),
name: "foyer",
origin: point{0, 0},
width: 10,
height: 10,
tiles: make([]tile, 100),
players: make(map[string]*player),
}
return &World{
Log: log,
@ -47,14 +49,27 @@ func (w *World) Run(hz int) {
select {
case req := <-w.Inbox:
w.Info("read from inbox: %v", req)
if req.From == "" {
req.Wants.exec(w, "")
w.Error("request has no from: %v", req)
break
}
if spawn, ok := req.Wants.(*SpawnPlayer); ok {
if _, ok := w.players[req.From]; ok {
spawn.Outbox <- wire.ErrorResponse(req.Seq, "a player is already logged in as %q", req.From)
break
}
spawn.exec(&w.rooms[0], req.From, req.Seq)
break
}
p, ok := w.players[req.From]
if !ok {
break
w.Error("received non login request of type %T from unknown player %q", req.Wants, req.From)
}
break
p.pending = append(p.pending, req)
case <-ticker.C:
@ -73,32 +88,6 @@ func (w *World) Stop() error {
return nil
}
// func (w *World) SpawnPlayer(id int) int {
// w.lastEntityID++
// r := w.rooms[0]
// w.Info("spawning player with id: %d into room %q", id, r.name)
// t := &r.tiles[0]
// p := player{
// Log: w.Child("players").Child(strconv.Itoa(id)),
// entityID: w.lastEntityID,
// }
// t.addEntity(&p)
// return p.entityID
// }
func (w *World) DespawnPlayer(id int) {
w.Info("despawning player with id: %d", id)
for _, r := range w.rooms {
for _, t := range r.tiles {
if e := t.removeEntity(id); e != nil {
w.Info("player removed from room %q", r.name)
return
}
}
}
w.Error("player was not found in any room")
}
func (w *World) tick(d time.Duration) {
for _, r := range w.rooms {
r.update(d)

@ -118,7 +118,6 @@ func (ui *UI) handleUserInput() bool {
// someone else shut us down, so return false
return false
}
ui.Info("screen sees event: %v", e)
switch v := e.(type) {
case *tcell.EventKey:

Loading…
Cancel
Save