howwwwwwww do you put objects DOWN

master
Jordan Orelli 4 years ago
parent 505e4952f0
commit bf05df3292

@ -51,6 +51,9 @@ func (v *gameView) walkHandler(e *tcell.EventKey) change {
case 'p':
v.keyHandler = v.pickupHandler
v.statusLine = "(pickup)"
case 'P':
v.keyHandler = v.putdownHandler
v.statusLine = "(put down)"
}
}
return nil
@ -116,6 +119,12 @@ func (v *gameView) pickupHandler(e *tcell.EventKey) change {
return nil
}
func (v *gameView) putdownHandler(e *tcell.EventKey) change {
v.keyHandler = v.walkHandler
v.statusLine = "(walk)"
return nil
}
func (v *gameView) draw(img canvas, st *state) {
fill(img, tcell.StyleDefault.Background(tcell.NewRGBColor(0, 0, 12)))
v.drawHeader(img, st)

@ -16,11 +16,27 @@ type item struct {
}
type inventoryView struct {
highlight int
*inventory
}
func (v *inventoryView) handleEvent(e tcell.Event) change {
if k, ok := e.(*tcell.EventKey); ok {
if k.Key() == tcell.KeyESC {
switch t := e.(type) {
case *tcell.EventKey:
key := t.Key()
switch key {
case tcell.KeyEnter:
case tcell.KeyDown:
if len(v.items) > 0 {
v.highlight = (v.highlight + 1) % len(v.items)
}
case tcell.KeyUp:
if len(v.items) > 0 {
v.highlight = (v.highlight - 1 + len(v.items)) % len(v.items)
}
case tcell.KeyESC:
return changeFn(func(ui *UI) {
if ui.root == inGameView {
inGameView.focus(0)
@ -28,13 +44,18 @@ func (v *inventoryView) handleEvent(e tcell.Event) change {
})
}
}
return nil
}
func (v *inventoryView) draw(img canvas, st *state) {
v.inventory = &st.inventory
writeString(img, "Inventory", math.Vec{0, 0}, tcell.StyleDefault)
for i, item := range st.inventory.items {
line := fmt.Sprintf("- %s", item.name)
if i == v.highlight {
line = fmt.Sprintf("+ %s", item.name)
}
writeString(img, line, math.Vec{0, i + 2}, tcell.StyleDefault)
}
}

@ -45,3 +45,6 @@ func (v Vec) Unit() Vec {
}
return out
}
// MDist calculates the manhattan distance between two vectors.
func (v Vec) MDist(v2 Vec) int { return Abs(v.X-v2.X) + Abs(v.Y-v2.Y) }

@ -13,7 +13,7 @@ type door struct {
arrived int
}
func (d *door) update(time.Duration) {}
func (d *door) update(*entity, time.Duration) {}
func (d *door) exec(w *world, r *room, p *player, seq int) result {
p.Info("executing door to %q for player %s", d.to, p.name)

@ -79,9 +79,9 @@ func (e *entity) stopOverlap(e2 *entity) {
type behavior interface {
// update is the standard tick function
update(time.Duration)
update(*entity, time.Duration)
}
type doNothing struct{}
func (d doNothing) update(time.Duration) {}
func (d doNothing) update(*entity, time.Duration) {}

@ -165,7 +165,26 @@ func sendResponse(conn *websocket.Conn, res wire.Response) error {
return nil
}
func (p *player) update(dt time.Duration) {}
func (p *player) removeItem(id int) *entity {
for i, e := range p.inventory {
if e.ID == id {
p.inventory = append(p.inventory[:i], p.inventory[i+1:]...)
return e
}
}
return nil
}
func (p *player) peekItem(id int) *entity {
for _, e := range p.inventory {
if e.ID == id {
return e
}
}
return nil
}
func (p *player) update(*entity, time.Duration) {}
type spawnPlayer struct{}
@ -179,6 +198,16 @@ func (s spawnPlayer) exec(w *world, r *room, p *player, seq int) result {
}
p.avatar = &e
p.inventory = append(p.inventory, &entity{
ID: <-w.nextID,
Glyph: 'p',
solid: false,
name: "a potato",
description: "it's a potato, what more information could you need?",
pickupable: true,
behavior: &potato{},
})
for n, _ := range r.tiles {
t := &r.tiles[n]
x, y := n%r.Width, n/r.Width
@ -277,6 +306,41 @@ type Pickedup struct {
func (p Pickedup) NetTag() string { return "pickedup" }
type Putdown struct {
ID int `json:"id"`
Location math.Vec `json:"loc"`
}
func (pd *Putdown) exec(w *world, r *room, pl *player, seq int) result {
pos := pl.avatar.Position
if pos.MDist(pd.Location) > 1 {
return result{reply: wire.Errorf("destination tile %v is too far from your current location at %v", pd.Location, pos)}
}
nextTile := r.getTile(pd.Location)
if nextTile == nil {
return result{reply: wire.Errorf("no tile at location %v", pd.Location)}
}
item := pl.peekItem(pd.ID)
if item == nil {
return result{reply: wire.Errorf("you're not holding an item with ID %d", pd.ID)}
}
if item.solid {
for _, e := range nextTile.here {
if e.solid {
return result{reply: wire.Errorf("you can't put a %s on top of a %s", item.name, e.name)}
}
}
}
nextTile.addEntity(pl.removeItem(pd.ID))
return result{reply: wire.OK{}}
}
func (Putdown) NetTag() string { return "put-down" }
var lastEntityID = 0
func init() {
@ -285,4 +349,5 @@ func init() {
wire.Register(func() wire.Value { return new(LookAt) })
wire.Register(func() wire.Value { return new(Pickup) })
wire.Register(func() wire.Value { return new(Pickedup) })
wire.Register(func() wire.Value { return new(Putdown) })
}

@ -0,0 +1,38 @@
package sim
import (
"time"
)
type stageOfGrowth int
const (
unborn stageOfGrowth = iota
planted
sapling
unripe
ripe
overripe
rotting
dead
)
type potato struct {
planted time.Duration
stage stageOfGrowth
}
func (p *potato) update(e *entity, dt time.Duration) {
if p.stage > unborn {
p.planted += dt
}
}
type percent int
func (p *potato) progress() percent {
if p.stage <= unborn {
return 0
}
return 100
}

@ -62,7 +62,7 @@ func (t *tile) isOccupied() bool {
func (t *tile) update(d time.Duration) {
for _, e := range t.here {
e.update(d)
e.update(e, d)
}
}

@ -49,6 +49,26 @@ func newWorld(log *blammo.Log) *world {
behavior: doNothing{},
})
foyer.addEntity(&entity{
ID: -2,
Position: math.Vec{5, 5},
Glyph: 'o',
solid: true,
pickupable: true,
name: "another rock",
behavior: doNothing{},
})
foyer.addEntity(&entity{
ID: -3,
Position: math.Vec{5, 6},
Glyph: 'o',
solid: true,
pickupable: true,
name: "yet another rock (YAR)",
behavior: doNothing{},
})
foyer.addEntity(&entity{
ID: -4,
Position: math.Vec{9, 5},

Loading…
Cancel
Save