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) } }