diff --git a/roadmap.md b/roadmap.md index 821bc90..df3f10e 100644 --- a/roadmap.md +++ b/roadmap.md @@ -46,14 +46,16 @@ TODO draft something new - [x] grpc server - [x] session handling (opening/closing) - [x] verb handling -- [x] WITCH: initial setup +- [ ] build out some more default rooms - [x] DB: initial schema - [ ] DB: sundry error handling -- [ ] build out some more default rooms +- [ ] DB/WITCH: locking objects +- [x] WITCH: initial setup - [ ] WITCH: ability to send verbs outward - [ ] WITCH: transitive verb support - [ ] WITCH: provides function - [ ] WITCH: movement stuff (teleport, move) +- [ ] WITCH: bidirectional has() support - [ ] VERBS: create - [ ] VERBS: announce (for gods) - [ ] VERBS: movement diff --git a/server/db/db.go b/server/db/db.go index 1ad4cc1..77c2699 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -125,6 +125,42 @@ func (db *pgDB) Ensure() error { } } + pub, err := db.GetObject("system", "pub") + if err != nil { + // TODO actually check error. for now assuming it means does not exist + data := map[string]string{} + data["name"] = "pub" + data["description"] = "a warm pub constructed of hard wood and brass" + pub = &Object{ + Data: data, + Script: "", + // TODO default room script + } + if err = db.CreateObject(sysAcc, pub); err != nil { + return err + } + } + + oakDoor, err := db.GetObject("system", "oak door") + if err != nil { + // TODO actually check error. for now assuming it means does not exist + data := map[string]string{} + data["name"] = "oak door" + data["description"] = "a heavy oak door with a brass handle. an ornate sign says PUB." + oakDoor = &Object{ + Data: data, + Script: ` + go("north", function + tellMe("the heavy door swings forward with ease. It creaks gently") + moveSender("system", "pub") + end) + `, + } + if err = db.CreateObject(sysAcc, oakDoor); err != nil { + return err + } + } + sysAva, err := db.GetAccountAvatar(*sysAcc) if err != nil { return fmt.Errorf("could not find avatar for system account: %w", err) @@ -132,6 +168,7 @@ func (db *pgDB) Ensure() error { db.MoveInto(*sysAva, *foyer) db.MoveInto(*egg, *foyer) + db.MoveInto(*oakDoor, *foyer) return nil } @@ -474,7 +511,7 @@ func (db *pgDB) CreateObject(owner *Account, obj *Object) error { RETURNING id ` - obj.Script = hasInvocation(obj) + obj.Script = hasInvocation(obj) + obj.Script err := db.pool.QueryRow(ctx, stmt, obj.Avatar, obj.Bedroom, obj.Data, obj.Script, owner.ID).Scan( diff --git a/server/db/schema.sql b/server/db/schema.sql index 77ef624..ae72a3d 100644 --- a/server/db/schema.sql +++ b/server/db/schema.sql @@ -37,3 +37,11 @@ CREATE TABLE contains ( container integer REFERENCES objects ON DELETE RESTRICT, contained integer REFERENCES objects ON DELETE CASCADE ); + +CREATE TYPE heading AS ENUM ('north', 'south', 'east', 'west', 'above', 'below'); + +CREATE TABLE exits ( + startroom integer REFERENCES objects ON DELETE CASCADE, + endroom integer REFERENCES objects ON DELETE CASCADE, + direction heading NOT NULL +); diff --git a/server/witch/header.go b/server/witch/header.go index 3fb1713..730d895 100644 --- a/server/witch/header.go +++ b/server/witch/header.go @@ -23,6 +23,13 @@ func witchSees(l *lua.LState) int { return addHandler(l, "emote") } +func witchGo(l *lua.LState) int { + // TODO get the handler map + // - check if handler map has a Go handler already, exit early if so + // TODO register this object as an exit in DB + return addHandler(l, "go") +} + func witchDoes(ls *lua.LState) int { // TODO how to feed events back into the server? // it needs to behave like an event showing up in Commands stream diff --git a/server/witch/witch.go b/server/witch/witch.go index 28e2b25..dceea0e 100644 --- a/server/witch/witch.go +++ b/server/witch/witch.go @@ -54,11 +54,13 @@ func NewScriptContext(sAPI ServerAPI) (*ScriptContext, error) { for { vc = <-sc.incoming if vc.Target.Script != sc.script { + // TODO clear this object out of the exits table sc.script = vc.Target.Script l = lua.NewState() l.SetGlobal("has", l.NewFunction(witchHas)) l.SetGlobal("hears", l.NewFunction(witchHears)) l.SetGlobal("sees", l.NewFunction(witchSees)) + l.SetGlobal("go", l.NewFunction(witchGo)) l.SetGlobal("_handlers", l.NewTable()) if err := l.DoString(vc.Target.Script); err != nil { log.Printf("error parsing script %s: %s", vc.Target.Script, err.Error()) @@ -72,6 +74,12 @@ func NewScriptContext(sAPI ServerAPI) (*ScriptContext, error) { return 0 })) + l.SetGlobal("moveSender", l.NewFunction(func(l *lua.LState) int { + // TODO get sender + // TODO add another func to serverAPI for moving an object + return 0 + })) + l.SetGlobal("showMe", l.NewFunction(func(l *lua.LState) int { sender := l.GetGlobal("sender").(*lua.LTable) senderID := int(lua.LVAsNumber(sender.RawGetString("ID")))