aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_verbs.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-20 04:44:44 -0400
committerhistoria <[not public]>2026-06-20 04:44:44 -0400
commit704627c3410a1dcab12e35cf67628bd014b4b5d8 (patch)
tree4b298bfef86c43af970890c5450e8721aeac8a9d /internal/game/cmd_verbs.go
parentdde563e6810124a73de5ef12e92774c540f9d62e (diff)
downloadthehouseoficarus-704627c3410a1dcab12e35cf67628bd014b4b5d8.tar.gz
feat: added verbs command (probably janky)
Diffstat (limited to 'internal/game/cmd_verbs.go')
-rw-r--r--internal/game/cmd_verbs.go234
1 files changed, 234 insertions, 0 deletions
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(&sectionObjs, &seen, verb+" "+name)
+ }
+ }
+ }
+
+ if bt == "talk" {
+ addUnique(&sectionObjs, &seen, "talk "+name)
+ }
+
+ if bt == "use" {
+ addUnique(&sectionObjs, &seen, "use "+name)
+ }
+
+ for _, ui := range def.UseInteractions {
+ if ui.Item == "" && (ui.Condition == nil || g.checkCondition(sess, ui.Condition)) {
+ addUnique(&sectionObjs, &seen, "use "+name)
+ break
+ }
+ }
+
+ recipes := g.stationRecipes(p, def.ID)
+ if len(recipes) > 0 {
+ addUnique(&sectionObjs, &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(&sectionObjs, &seen, info.ActionType)
+ }
+ }
+ for _, c := range r.Consume {
+ for _, itemID := range c.Items {
+ if itemDef, err := g.ItemStore.Load(itemID); err == nil {
+ addUnique(&sectionObjs, &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(&sectionObjs, &seen, "use "+itemDef.Name+" on "+name)
+ }
+ }
+ }
+
+ if def.StealTable != "" {
+ addUnique(&sectionObjs, &seen, "steal "+name)
+ }
+
+ addUnique(&sectionObjs, &seen, "look "+name)
+ }
+
+ for _, m := range g.MobStore.MobsInRoom(p.RoomID) {
+ mName := strings.ToLower(m.Name)
+
+ if !m.Protected {
+ addUnique(&sectionMobs, &seen, "attack "+mName)
+ }
+ if m.IsTalkable() {
+ addUnique(&sectionMobs, &seen, "talk "+mName)
+ }
+ if m.StealTable != "" {
+ addUnique(&sectionMobs, &seen, "steal "+mName)
+ }
+ addUnique(&sectionMobs, &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(&sectionGround, &seen, "get "+def.Name)
+ }
+ }
+ addUnique(&sectionGround, &seen, "get all")
+ }
+
+ if info := g.CourseStore.GetObstacle(p.RoomID); info != nil {
+ addUnique(&sectionGround, &seen, info.Verb)
+ }
+
+ if g.canUseBank(p) {
+ addUnique(&sectionObjs, &seen, "bank")
+ }
+
+ if g.findTerminalInRoom(p.RoomID) != "" {
+ addUnique(&sectionObjs, &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)
+ }
+}