i think i'm making it worse now

master
Jordan Orelli 4 years ago
parent 5ad36dbe69
commit cd96c66e6b

@ -2,6 +2,7 @@ package app
import (
"github.com/gdamore/tcell/v2"
"github.com/jordanorelli/astro-domu/internal/math"
"github.com/jordanorelli/astro-domu/internal/server/sim"
"github.com/jordanorelli/astro-domu/internal/wire"
"github.com/jordanorelli/blammo"
@ -9,9 +10,12 @@ import (
type gameView struct {
*blammo.Log
roomName string
width int
height int
// entities map[int]wire.Entity
me wire.Entity
allRooms map[string]wire.Room
allEntities map[int]wire.Entity
}
func (v *gameView) handleEvent(ui *UI, e tcell.Event) bool {
@ -38,18 +42,30 @@ func (v *gameView) handleEvent(ui *UI, e tcell.Event) bool {
func (v *gameView) notify(wv wire.Value) {
v.Error("ignoring notifications at the moment: %v", wv)
// if e, ok := v.(*wire.Entity); ok {
// m.entities[e.ID] = *e
// }
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) {
_, err := ui.client.Send(sim.Move{dx, dy})
reply, err := ui.client.Send(sim.Move{dx, dy})
if err != nil {
return
}
// e := reply.Body.(*wire.Entity)
// v.entities[e.ID] = *e
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
}
func (v *gameView) draw(ui *UI) {
@ -76,7 +92,8 @@ func (v *gameView) draw(ui *UI) {
ui.screen.SetContent(offset.x+v.width, y+offset.y, '│', nil, tcell.StyleDefault)
}
// for _, e := range v.entities {
// ui.screen.SetContent(e.Position[0]+offset.x, e.Position[1]+offset.y, e.Glyph, nil, tcell.StyleDefault)
// }
for _, e := range v.allRooms[v.roomName].Entities {
pos := e.Position.Add(math.Vec{1, 1})
ui.screen.SetContent(pos.X, pos.Y, e.Glyph, nil, tcell.StyleDefault)
}
}

@ -36,18 +36,25 @@ func (ui *UI) Run() {
ui.Error("unexpected initial message of type %t", res.Body)
return
}
ui.Info("spawned into room %s", welcome.Room)
// entities := make(map[int]sim.Entity, len(welcome.Contents))
// for _, e := range welcome.Contents {
// entities[e.ID] = e
// }
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.view = &gameView{
Log: ui.Child("game-view"),
width: welcome.Room.Width,
height: welcome.Room.Height,
// entities: entities,
roomName: room.Name,
width: room.Width(),
height: room.Height(),
me: room.Entities[meta.Avatar],
allRooms: welcome.Rooms,
allEntities: allEntities,
}
ui.Info("running ui")
if ui.handleUserInput() {
ui.Info("user requested close")

@ -0,0 +1,8 @@
package math
func Abs(n int) int {
if n >= 0 {
return n
}
return -n
}

@ -0,0 +1,35 @@
package math
import "encoding/json"
type Bounds struct {
Min Vec `json:"min"`
Max Vec `json:"max"`
}
func CreateBounds(width, height int) Bounds {
return Bounds{
Min: Vec{0, 0},
Max: Vec{width - 1, height - 1},
}
}
func (b Bounds) Width() int { return Abs(b.Max.X - b.Min.X) }
func (b Bounds) Height() int { return Abs(b.Max.Y - b.Min.Y) }
func (b Bounds) Area() int { return b.Width() * b.Height() }
func (b Bounds) Contains(v Vec) bool {
return v.X >= b.Min.X && v.X <= b.Max.X && v.Y >= b.Min.Y && v.Y <= b.Max.Y
}
func (b Bounds) MarshalJSON() ([]byte, error) { return json.Marshal([2]Vec{b.Min, b.Max}) }
func (b *Bounds) UnmarshalJSON(buf []byte) error {
var raw [2]Vec
if err := json.Unmarshal(buf, &raw); err != nil {
return err
}
b.Min = raw[0]
b.Max = raw[1]
return nil
}

@ -13,7 +13,7 @@ type player struct {
name string
outbox chan wire.Response
pending []Request
entity *entity
avatar *entity
}
type Move math.Vec
@ -21,24 +21,25 @@ type Move math.Vec
func (Move) NetTag() string { return "move" }
func (m *Move) exec(r *room, p *player, seq int) result {
pos := p.entity.Position
pos := p.avatar.Position
target := pos.Add(math.Vec(*m))
p.Info("running move for player %s from %v to %v", p.name, *m, target)
if target.X >= r.width || target.X < 0 {
if !p.room.bounds.Contains(target) {
return result{reply: wire.Errorf("target cell (%d, %d) is out of bounds", target.X, target.Y)}
}
if target.Y >= r.height || target.Y < 0 {
return result{reply: wire.Errorf("target cell (%d, %d) is out of bounds", target.X, target.Y)}
}
n := target.X*r.width + target.Y
if r.tiles[n].here != nil {
currentTile := r.getTile(pos)
nextTile := r.getTile(target)
if nextTile.here != nil {
return result{reply: wire.Errorf("target cell (%d, %d) is occupied", target.X, target.Y)}
}
r.tiles[p.entity.Position.X*r.width+p.entity.Position.Y].here = nil
p.entity.Position = target
r.tiles[n].here = p.entity
e := wire.Entity{
Position: p.entity.Position,
currentTile.here, nextTile.here = nil, p.avatar
p.avatar.Position = target
e := wire.UpdateEntity{
Room: r.name,
ID: p.avatar.ID,
Position: p.avatar.Position,
Glyph: '@',
}
return result{reply: e, announce: e}
@ -63,30 +64,51 @@ func (s *SpawnPlayer) exec(r *room, _ *player, seq int) result {
}
lastEntityID++
avatar := &entity{
ID: lastEntityID,
Position: math.Vec{0, 0},
Glyph: '@',
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),
entity: &entity{
ID: lastEntityID,
Position: math.Vec{0, 0},
Glyph: '@',
behavior: doNothing{},
},
avatar: avatar,
}
p.pending = append(p.pending, Request{Seq: seq, From: s.Name, Wants: s})
r.players[s.Name] = p
r.tiles[0].here = p.entity
r.tiles[0].here = p.avatar
s.queued = true
return result{}
}
var welcome wire.Welcome
welcome.Room.Width = r.width
welcome.Room.Height = r.height
welcome.Room.Origin = math.Vec{0, 0}
welcome := wire.Welcome{
Rooms: make(map[string]wire.Room),
Players: make(map[string]wire.Player),
}
ents := make(map[int]wire.Entity)
for id, e := range r.allEntities() {
ents[id] = wire.Entity{
ID: id,
Position: e.Position,
Glyph: e.Glyph,
}
}
welcome.Rooms[r.name] = wire.Room{
Name: r.name,
Bounds: r.bounds,
Entities: ents,
}
for _, p := range r.players {
welcome.Players[p.name] = wire.Player{
Name: p.name,
Avatar: p.avatar.ID,
Room: r.name,
}
}
return result{reply: welcome}
}
@ -102,5 +124,4 @@ func (PlayerSpawned) NetTag() string { return "player/spawned" }
func init() {
wire.Register(func() wire.Value { return new(Move) })
// wire.Register(func() wire.Value { return new(pawn) })
}

@ -3,6 +3,7 @@ package sim
import (
"time"
"github.com/jordanorelli/astro-domu/internal/math"
"github.com/jordanorelli/astro-domu/internal/wire"
"github.com/jordanorelli/blammo"
)
@ -11,8 +12,7 @@ type room struct {
*blammo.Log
name string
origin point
width int
height int
bounds math.Bounds
tiles []tile
players map[string]*player
}
@ -39,11 +39,12 @@ func (r *room) update(dt time.Duration) {
}
}
func (r *room) allEntities() []entity {
all := make([]entity, 0, 4)
func (r *room) allEntities() map[int]*entity {
all := make(map[int]*entity, 4)
for _, t := range r.tiles {
if t.here != nil {
all = append(all, *t.here)
e := t.here
all[e.ID] = e
}
}
return all
@ -60,3 +61,11 @@ func (r *room) removePlayer(name string) bool {
}
return false
}
func (r *room) getTile(pos math.Vec) *tile {
if !r.bounds.Contains(pos) {
return nil
}
n := pos.X*r.bounds.Width() + pos.Y
return &r.tiles[n]
}

@ -20,13 +20,13 @@ type World struct {
}
func NewWorld(log *blammo.Log) *World {
bounds := math.CreateBounds(10, 10)
foyer := room{
Log: log.Child("foyer"),
name: "foyer",
origin: point{0, 0},
width: 10,
height: 10,
tiles: make([]tile, 100),
bounds: bounds,
tiles: make([]tile, bounds.Area()),
players: make(map[string]*player),
}
foyer.tiles[55].here = &entity{

@ -5,12 +5,23 @@ import (
)
type Entity struct {
ID int `json:"id"`
Position math.Vec `json:"position"`
Glyph rune `json:"glyph"`
}
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) })
}

@ -0,0 +1,7 @@
package wire
type Player struct {
Name string `json:"name"`
Room string `json:"room"`
Avatar int `json:"avatar"`
}

@ -0,0 +1,15 @@
package wire
import (
"github.com/jordanorelli/astro-domu/internal/math"
)
// 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"`
}
func (r Room) Width() int { return r.Bounds.Width() }
func (r Room) Height() int { return r.Bounds.Height() }

@ -1,16 +1,8 @@
package wire
import (
"github.com/jordanorelli/astro-domu/internal/math"
)
type Welcome struct {
Room struct {
Origin math.Vec `json:"origin"`
Width int `json:"width"`
Height int `json:"height"`
} `json:"room"`
Entities map[int]Entity `json:"entities"`
Rooms map[string]Room `json:"rooms"`
Players map[string]Player `json:"players"`
}
func (Welcome) NetTag() string { return "welcome" }

Loading…
Cancel
Save