diff --git a/internal/app/game_view.go b/internal/app/game_view.go index ab2a143..12a9582 100644 --- a/internal/app/game_view.go +++ b/internal/app/game_view.go @@ -2,37 +2,82 @@ package app import ( "github.com/gdamore/tcell/v2" + "github.com/jordanorelli/astro-domu/internal/math" "github.com/jordanorelli/astro-domu/internal/sim" "github.com/jordanorelli/blammo" ) type gameView struct { *blammo.Log - inFocus bool + inFocus bool + keyHandler func(*tcell.EventKey) change + statusLine string } func (v *gameView) handleEvent(e tcell.Event) change { + if v.keyHandler == nil { + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + } + switch t := e.(type) { case *tcell.EventKey: - key := t.Key() - if key == tcell.KeyRune { - switch t.Rune() { - case 'w': - return move{0, -1} - case 'a': - return move{-1, 0} - case 's': - return move{0, 1} - case 'd': - return move{1, 0} - } - } + return v.keyHandler(t) default: // ui.Debug("screen saw unhandled event of type %T", e) } return nil } +func (v *gameView) walkHandler(e *tcell.EventKey) change { + if e.Key() == tcell.KeyRune { + switch e.Rune() { + case 'w': + return move{0, -1} + case 'a': + return move{-1, 0} + case 's': + return move{0, 1} + case 'd': + return move{1, 0} + case 'l': + v.keyHandler = v.lookHandler + v.statusLine = "(look)" + } + } + return nil +} + +func (v *gameView) lookHandler(e *tcell.EventKey) change { + if e.Key() == tcell.KeyESC { + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + return nil + } + + if e.Key() == tcell.KeyRune { + switch e.Rune() { + case 'w': + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + return lookAt{0, -1} + case 'a': + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + return lookAt{-1, 0} + case 's': + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + return lookAt{0, 1} + case 'd': + v.keyHandler = v.walkHandler + v.statusLine = "(walk)" + return lookAt{1, 0} + } + } + return nil +} + func (v *gameView) draw(img canvas, st *state) { fill(img, tcell.StyleDefault.Background(tcell.NewRGBColor(0, 0, 12))) v.drawHeader(img, st) @@ -59,6 +104,7 @@ func (v *gameView) draw(img canvas, st *state) { pos := e.Position img.setTile(pos.X+1, pos.Y+2, tile{r: e.Glyph, style: tcell.StyleDefault}) } + writeString(img, v.statusLine, math.Vec{0, img.bounds().Height - 1}, tcell.StyleDefault) } func (v *gameView) drawHeader(img canvas, st *state) { @@ -89,3 +135,26 @@ type move struct { func (m move) exec(ui *UI) { go ui.client.Send(sim.Move{m.x, m.y}) } + +type lookAt struct { + x int + y int +} + +func (l lookAt) exec(ui *UI) { + go func() { + res, err := ui.client.Send(sim.LookAt{l.x, l.y}) + if err != nil { + ui.Error("look error: %v", err) + return + } + + look, ok := res.Body.(*sim.Look) + if !ok { + ui.Error("look response is not look: %v", res.Body) + return + } + + ui.Info("look: %v", look) + }() +} diff --git a/internal/app/ui.go b/internal/app/ui.go index a439ffb..fa0ac97 100644 --- a/internal/app/ui.go +++ b/internal/app/ui.go @@ -16,6 +16,7 @@ type UI struct { screen tcell.Screen client *wire.Client notifications <-chan wire.Response + misc chan func(*UI) state state root view @@ -24,6 +25,7 @@ type UI struct { func (ui *UI) Run() { ui.setupTerminal() defer ui.clearTerminal() + ui.misc = make(chan func(*UI)) ui.root = mainMenu @@ -131,6 +133,10 @@ func (ui *UI) handleNotification(v wire.Value) bool { ui.state.history = append(ui.state.history, *n) return true + case *sim.Look: + ui.Info("got look back: %v", n) + return true + default: ui.Info("ignoring notification: %v", n) return false diff --git a/internal/sim/entity.go b/internal/sim/entity.go index 8824962..16a22c8 100644 --- a/internal/sim/entity.go +++ b/internal/sim/entity.go @@ -7,11 +7,13 @@ import ( ) type entity struct { - ID int `json:"id"` - Position math.Vec `json:"pos"` - Glyph rune `json:"glyph"` - solid bool `json:"-"` - overlapped map[int]*entity + ID int `json:"id"` + Position math.Vec `json:"pos"` + Glyph rune `json:"glyph"` + name string + description string + solid bool `json:"-"` + overlapped map[int]*entity behavior } diff --git a/internal/sim/player.go b/internal/sim/player.go index 2061593..c4061ad 100644 --- a/internal/sim/player.go +++ b/internal/sim/player.go @@ -221,8 +221,37 @@ func (m *Move) exec(w *world, r *room, p *player, seq int) result { return result{reply: wire.OK{}} } +type LookAt math.Vec + +func (LookAt) NetTag() string { return "look-at" } + +func (l *LookAt) exec(w *world, r *room, p *player, seq int) result { + pos := p.avatar.Position + target := pos.Add(math.Vec(*l)) + nextTile := r.getTile(target) + p.Info("looked at: %v", nextTile) + + look := &Look{Here: make([]LookItem, 0, len(nextTile.here))} + for _, e := range nextTile.here { + look.Here = append(look.Here, LookItem{Name: e.name}) + } + return result{reply: look} +} + +type Look struct { + Here []LookItem `json:"here"` +} + +func (l Look) NetTag() string { return "look" } + +type LookItem struct { + Name string `json:"name"` +} + var lastEntityID = 0 func init() { wire.Register(func() wire.Value { return new(Move) }) + wire.Register(func() wire.Value { return new(Look) }) + wire.Register(func() wire.Value { return new(LookAt) }) } diff --git a/internal/sim/world.go b/internal/sim/world.go index d40ecc5..ab33dd6 100644 --- a/internal/sim/world.go +++ b/internal/sim/world.go @@ -42,29 +42,31 @@ func newWorld(log *blammo.Log) *world { foyer.addEntity(&entity{ ID: -1, Position: math.Vec{5, 4}, - Glyph: 'd', + Glyph: 'o', solid: true, + name: "a rock", behavior: doNothing{}, }) - foyer.addEntity(&entity{ - ID: -2, - Position: math.Vec{9, 0}, - Glyph: '+', - behavior: doNothing{}, - }) + // foyer.addEntity(&entity{ + // ID: -2, + // Position: math.Vec{9, 0}, + // Glyph: '+', + // behavior: doNothing{}, + // }) - foyer.addEntity(&entity{ - ID: -3, - Position: math.Vec{9, 1}, - Glyph: '-', - behavior: doNothing{}, - }) + // foyer.addEntity(&entity{ + // ID: -3, + // Position: math.Vec{9, 1}, + // Glyph: '-', + // behavior: doNothing{}, + // }) foyer.addEntity(&entity{ ID: -4, Position: math.Vec{9, 5}, Glyph: '◇', + name: "Door to Hall", behavior: &door{ Log: log.Child("door"), to: "hall", @@ -84,6 +86,7 @@ func newWorld(log *blammo.Log) *world { ID: -5, Position: math.Vec{0, 2}, Glyph: '◇', + name: "Door to Foyer", behavior: &door{ Log: log.Child("door"), to: "foyer", @@ -103,6 +106,7 @@ func newWorld(log *blammo.Log) *world { ID: -6, Position: math.Vec{9, 7}, Glyph: '◇', + name: "Door to Kitchen", behavior: &door{ Log: log.Child("door"), to: "kitchen", @@ -114,6 +118,7 @@ func newWorld(log *blammo.Log) *world { ID: -7, Position: math.Vec{0, 2}, Glyph: '◇', + name: "Door to Foyer", behavior: &door{ Log: log.Child("door"), to: "foyer",