You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.0 KiB
Go

package sim
4 years ago
import (
"time"
"github.com/jordanorelli/blammo"
)
// World is the entire simulated world. A world consists of many rooms.
type World struct {
4 years ago
*blammo.Log
Inbox chan Request
rooms []room
done chan bool
lastEntityID int
players map[string]*player
4 years ago
}
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),
}
4 years ago
return &World{
Log: log,
rooms: []room{foyer},
done: make(chan bool),
Inbox: make(chan Request),
players: make(map[string]*player),
4 years ago
}
}
func (w *World) Run(hz int) {
defer w.Info("simulation has exited run loop")
4 years ago
period := time.Second / time.Duration(hz)
w.Info("starting world with a tick rate of %dhz, frame duration of %v", hz, period)
ticker := time.NewTicker(period)
lastTick := time.Now()
4 years ago
for {
select {
case req := <-w.Inbox:
w.Info("read from inbox: %v", req)
if req.From == "" {
req.Wants.exec(w, "")
break
}
p, ok := w.players[req.From]
if !ok {
break
}
p.pending = append(p.pending, req)
4 years ago
case <-ticker.C:
w.tick(time.Since(lastTick))
lastTick = time.Now()
case <-w.done:
return
4 years ago
}
}
}
func (w *World) Stop() error {
w.Info("stopping simulation")
w.done <- true
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")
}
4 years ago
func (w *World) tick(d time.Duration) {
for _, r := range w.rooms {
r.update(d)
}
}