package game import ( "fmt" "os" "path/filepath" "strings" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" "gopkg.in/yaml.v3" ) type HelpDef struct { Name string `yaml:"name"` Category string `yaml:"category"` Content string `yaml:"description"` } type cmdEntry struct { Name string Type string Desc string } var commandList = []cmdEntry{ {"alias", "Instant", "Create command shortcuts"}, {"attack / kill", "Active", "Attack a mob"}, {"burn", "Active", "Start a fire"}, {"chop / cut", "Active", "Chop trees (Woodcutting)"}, {"color / colors", "Instant", "Customize display colors"}, {"colortable", "Instant", "Display color reference chart"}, {"cook", "Active", "Cook raw food on a fire or range"}, {"description / desc", "Instant", "Set your character description"}, {"drop", "Active", "Drop items to the ground"}, {"eat", "Free", "Eat food to restore hitpoints"}, {"equipment / eq", "Instant", "Show equipped items"}, {"exits", "Instant", "List available exits"}, {"fish", "Active", "Fish at fishing spots (Fishing)"}, {"get / take / pick", "Active", "Pick up items from the ground"}, {"help", "Instant", "Show help topics"}, {"inventory / i / inv", "Instant", "Show your inventory"}, {"look / l", "Instant", "Look around or examine things"}, {"map", "Instant", "Display an ASCII map of the area"}, {"mine", "Active", "Mine rocks (Mining)"}, {"north / south / east / west / up / down", "Active", "Move in a direction"}, {"option / options", "Instant", "View or change settings"}, {"prompt", "Instant", "Set custom command prompt"}, {"pull / push", "Active", "Toggle levers and switches"}, {"queued", "Instant", "Show pending tick actions"}, {"quit", "Active", "Rest and disconnect"}, {"remove / unwear / unwield", "Free", "Unequip items"}, {"say", "Instant", "Chat with players in your room"}, {"score / sc", "Instant", "View your stats and skills"}, {"search", "Active", "Search items for loot"}, {"stoke", "Active", "Add logs to a fire"}, {"style", "Instant", "Change combat style"}, {"talk / speak / ask", "Active", "Talk to NPCs"}, {"unalias", "Instant", "Remove command shortcuts"}, {"use", "Active", "Use an object (crafting)"}, {"walk", "Active", "Pathfind to a room or multi-step walk"}, {"wear / wield", "Free", "Equip items"}, } func LoadHelp(dataDir string) ([]HelpDef, error) { dir := filepath.Join(dataDir, "help") entries, err := os.ReadDir(dir) if err != nil { return nil, err } var helps []HelpDef for _, entry := range entries { if entry.IsDir() || filepath.Ext(entry.Name()) != ".yaml" { continue } data, err := os.ReadFile(filepath.Join(dir, entry.Name())) if err != nil { continue } var h HelpDef if err := yaml.Unmarshal(data, &h); err != nil { continue } helps = append(helps, h) } return helps, nil } func (g *Game) doHelp(sess *net.Session, topic string) { if topic == "" { unicode := true if p, _ := sess.Player.(*player.Player); p != nil { unicode = p.OptionBool("unicode") } sess.WriteLine("") t := &Table{ Title: "Commands", Columns: []string{"Command", "Type", "Description"}, } for _, c := range commandList { t.Rows = append(t.Rows, []string{c.Name, c.Type, c.Desc}) } for _, line := range t.Render(unicode) { sess.WriteLine(line) } sess.WriteLine("") sess.WriteLine("Command types: Instant (runs immediately), Free (queued before active),") sess.WriteLine("Active (replaces current action, queued per tick).") sess.WriteLine("") sess.WriteLine("Use 'help ' for detailed usage of a specific command.") sess.WriteLine("Use 'option' to view and change settings, 'color' to customize colors.") return } helps, err := LoadHelp(g.dataDir) if err != nil || len(helps) == 0 { sess.WriteLine("No help available.") return } topic = strings.ToLower(topic) for _, h := range helps { if strings.ToLower(h.Name) == topic { sess.WriteLine(fmt.Sprintf("\n %s", h.Content)) return } } sess.WriteLine(fmt.Sprintf("No help found for '%s'.", topic)) } func firstLine(s string) string { if idx := strings.Index(s, "\n"); idx >= 0 { return s[:idx] } return s }