diff options
| author | historia <[not public]> | 2026-06-20 04:44:44 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-20 04:44:44 -0400 |
| commit | 704627c3410a1dcab12e35cf67628bd014b4b5d8 (patch) | |
| tree | 4b298bfef86c43af970890c5450e8721aeac8a9d /internal | |
| parent | dde563e6810124a73de5ef12e92774c540f9d62e (diff) | |
| download | thehouseoficarus-704627c3410a1dcab12e35cf67628bd014b4b5d8.tar.gz | |
feat: added verbs command (probably janky)
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/game/action.go | 24 | ||||
| -rw-r--r-- | internal/game/cmd_registry.go | 8 | ||||
| -rw-r--r-- | internal/game/cmd_verbs.go | 234 |
3 files changed, 243 insertions, 23 deletions
diff --git a/internal/game/action.go b/internal/game/action.go index 2f5dbaf..d6ef1bc 100644 --- a/internal/game/action.go +++ b/internal/game/action.go @@ -75,6 +75,7 @@ func (g *Game) startAction(sess *net.Session, verb, target string) { var obj *object.ObjectDef var mob *world.MobInstance + var chosen *world.ObjState if len(instances) > 0 { uniqueDefs := make(map[string]bool) @@ -86,7 +87,6 @@ func (g *Game) startAction(sess *net.Session, verb, target string) { return } - var chosen *world.ObjState if instanceIdx >= 0 && instanceIdx < len(instances) { chosen = &instances[instanceIdx] } else { @@ -163,29 +163,11 @@ func (g *Game) startAction(sess *net.Session, verb, target string) { switch bhType { case "gather": - if obj == nil { + if obj == nil || chosen == nil { sess.WriteLine(fmt.Sprintf("You can't %s that.", verb)) return } - chosenObj := g.World.FindObjInstances(p.RoomID, obj.ID) - sort.Slice(chosenObj, func(i, j int) bool { - return chosenObj[i].Index < chosenObj[j].Index - }) - var st *world.ObjState - for i := range chosenObj { - if !chosenObj[i].Depleted { - st = &chosenObj[i] - break - } - } - if st == nil && len(chosenObj) > 0 { - st = &chosenObj[0] - } - if st == nil { - sess.WriteLine(fmt.Sprintf("There's nothing here to %s.", verb)) - return - } - g.startGather(sess, p, obj, st) + g.startGather(sess, p, obj, chosen) case "talk": if mob != nil { g.startMobTalk(sess, p, mob) diff --git a/internal/game/cmd_registry.go b/internal/game/cmd_registry.go index db1ec81..5073b02 100644 --- a/internal/game/cmd_registry.go +++ b/internal/game/cmd_registry.go @@ -117,7 +117,11 @@ var commandRegistry = map[string]commandDef{ "remove": {(*Game).executeRemove, ClassFree}, "unwear": {(*Game).executeRemove, ClassFree}, "unwield": {(*Game).executeRemove, ClassFree}, - "aps": {(*Game).executeAps, ClassActive}, + "aps": {(*Game).executeAps, ClassActive}, + "verbs": {(*Game).executeVerbs, ClassInstant}, + "what": {(*Game).executeVerbs, ClassInstant}, + "syntax": {(*Game).executeVerbs, ClassInstant}, + "commands": {(*Game).executeVerbs, ClassInstant}, } func classifyCommand(cmd string) CommandClass { @@ -173,7 +177,7 @@ func (g *Game) executeCommand(sess *net.Session, cmd string, args []string, rawI } func (g *Game) executeGather(sess *net.Session, args []string, rawInput string) { - verb := strings.TrimSpace(rawInput) + verb := strings.Fields(rawInput)[0] p := sess.Player g.cancelAction(p) if len(args) == 0 { diff --git a/internal/game/cmd_verbs.go b/internal/game/cmd_verbs.go new file mode 100644 index 0000000..1ecd138 --- /dev/null +++ b/internal/game/cmd_verbs.go @@ -0,0 +1,234 @@ +package game + +import ( + "strings" + + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/world" +) + +var alwaysAvailable = []string{ + "look", "l", + "say", + "exits", + "map", + "walk", + "score", "stats", + "inventory", "inv", "i", + "equipment", "eq", "equip", "wear", "wield", + "remove", "unwear", "unwield", + "style", + "tech", "t", + "option", "options", + "color", "colors", "colortable", + "prompt", + "alias", "unalias", + "help", + "inspect", + "queued", + "aps", + "autotrigger", "auto", + "trigger", + "sneak", + "mods", "modules", "modlist", "mod", "module", + "id", "identify", + "eat", "drink", + "fletch", + "clean", + "burn", "stoke", + "search", + "get", "take", "grab", "pick", + "drop", +} + +func (g *Game) executeVerbs(sess *net.Session, args []string, rawInput string) { + p := sess.Player + showAll := len(args) == 1 && strings.ToLower(args[0]) == "all" + + seen := make(map[string]bool) + var sectionObjs []string + var sectionMobs []string + var sectionExits []string + var sectionGround []string + + for _, st := range g.World.AllObjInstances(p.RoomID) { + def, err := g.ObjectStore.Load(st.DefID) + if err != nil || def.Hidden { + continue + } + name := strings.ToLower(def.Name) + + bt := def.BehaviorType() + + if bt == "gather" && def.Gather != nil { + for verb, skill := range verbSkill { + if strings.EqualFold(def.Gather.Skill, skill) { + addUnique(§ionObjs, &seen, verb+" "+name) + } + } + } + + if bt == "talk" { + addUnique(§ionObjs, &seen, "talk "+name) + } + + if bt == "use" { + addUnique(§ionObjs, &seen, "use "+name) + } + + for _, ui := range def.UseInteractions { + if ui.Item == "" && (ui.Condition == nil || g.checkCondition(sess, ui.Condition)) { + addUnique(§ionObjs, &seen, "use "+name) + break + } + } + + recipes := g.stationRecipes(p, def.ID) + if len(recipes) > 0 { + addUnique(§ionObjs, &seen, "use "+name) + for _, r := range recipes { + if info, ok := productionTypes[r.Type]; ok { + if info.ActionType != "combine" && info.ActionType != "fletch" && info.ActionType != "mix" { + addUnique(§ionObjs, &seen, info.ActionType) + } + } + for _, c := range r.Consume { + for _, itemID := range c.Items { + if itemDef, err := g.ItemStore.Load(itemID); err == nil { + addUnique(§ionObjs, &seen, "use "+itemDef.Name+" on "+name) + } + } + } + } + } + + for _, ui := range def.UseInteractions { + if ui.Item != "" && (ui.Condition == nil || g.checkCondition(sess, ui.Condition)) { + if itemDef, err := g.ItemStore.Load(ui.Item); err == nil { + addUnique(§ionObjs, &seen, "use "+itemDef.Name+" on "+name) + } + } + } + + if def.StealTable != "" { + addUnique(§ionObjs, &seen, "steal "+name) + } + + addUnique(§ionObjs, &seen, "look "+name) + } + + for _, m := range g.MobStore.MobsInRoom(p.RoomID) { + mName := strings.ToLower(m.Name) + + if !m.Protected { + addUnique(§ionMobs, &seen, "attack "+mName) + } + if m.IsTalkable() { + addUnique(§ionMobs, &seen, "talk "+mName) + } + if m.StealTable != "" { + addUnique(§ionMobs, &seen, "steal "+mName) + } + addUnique(§ionMobs, &seen, "look "+mName) + } + + if room, err := g.World.LoadRoom(p.RoomID); err == nil { + var exitDirs []string + for _, dir := range world.ExitOrder { + if _, ok := room.Exits[dir]; ok { + exitDirs = append(exitDirs, string(dir)) + } + } + if len(exitDirs) > 0 { + sectionExits = append(sectionExits, strings.Join(exitDirs, ", ")) + } + } + + ground := g.World.GroundItems(p.RoomID) + if len(ground) > 0 { + for itemID := range ground { + if def, err := g.ItemStore.Load(itemID); err == nil { + addUnique(§ionGround, &seen, "get "+def.Name) + } + } + addUnique(§ionGround, &seen, "get all") + } + + if info := g.CourseStore.GetObstacle(p.RoomID); info != nil { + addUnique(§ionGround, &seen, info.Verb) + } + + if g.canUseBank(p) { + addUnique(§ionObjs, &seen, "bank") + } + + if g.findTerminalInRoom(p.RoomID) != "" { + addUnique(§ionObjs, &seen, "jack") + } + + hasRoomCmds := len(sectionObjs) > 0 || len(sectionMobs) > 0 || len(sectionExits) > 0 || len(sectionGround) > 0 + + if hasRoomCmds { + if len(sectionObjs) > 0 { + sess.WriteLine("Objects:") + writeCmdLines(sess, sectionObjs) + } + if len(sectionMobs) > 0 { + sess.WriteLine("Mobs:") + writeCmdLines(sess, sectionMobs) + } + if len(sectionExits) > 0 { + sess.WriteLine("Exits:") + writeCmdLines(sess, sectionExits) + } + if len(sectionGround) > 0 { + sess.WriteLine("Ground:") + writeCmdLines(sess, sectionGround) + } + } else { + sess.WriteLine("There is nothing notable to interact with here.") + } + + if showAll { + sess.WriteLine("") + sess.WriteLine("Always available:") + writeCmdLineStrings(sess, alwaysAvailable) + } else { + sess.WriteLine("") + sess.WriteLine(`Type "verbs all" to see all available commands.`) + } +} + +func addUnique(list *[]string, seen *map[string]bool, cmd string) { + if (*seen)[cmd] { + return + } + (*seen)[cmd] = true + *list = append(*list, cmd) +} + +func writeCmdLines(sess *net.Session, cmds []string) { + wrapCmdLines(sess, cmds, " ") +} + +func writeCmdLineStrings(sess *net.Session, cmds []string) { + wrapCmdLines(sess, cmds, " ") +} + +func wrapCmdLines(sess *net.Session, cmds []string, prefix string) { + const width = 70 + var current string + for _, cmd := range cmds { + if current == "" { + current = prefix + cmd + } else if len(current)+len(cmd)+2 <= width { + current += ", " + cmd + } else { + sess.WriteLine(current) + current = prefix + cmd + } + } + if current != "" { + sess.WriteLine(current) + } +} |
