package game import ( "strings" "thehouseoficarus/internal/net" ) func predictionUseTarget(input string) bool { switch strings.ToLower(strings.TrimSpace(input)) { case "predictions", "prediction", "market", "counter", "exchange", "prediction market", "prediction counter", "prediction exchange", "prediction market counter": return true } return false } var predictionVerbs = []string{"markets", "view", "find", "next", "prev", "back", "active", "closed", "holding", "buy", "sell", "collect", "refresh", "rules", "stop"} func (g *Game) openPredictionCounter(s *net.Session) { if !g.atPredictionCounter(s.Player) { s.WriteLine("There is no Prediction Exchange here.") return } if !g.leaveCasinoGames(s.Player) { s.WriteLine("Finish your current casino round before using the counter.") return } if s.PredictionActive { g.executePredictions(s, []string{"refresh"}, "") return } g.closeCryptoCounter(s) s.PredictionActive = true s.PredictionEpoch++ s.PredictionBusy = false s.PredictionSelected = "" s.PredictionScreen = "list" s.PredictionPage = 1 s.PredictionBoardPage = 1 s.PredictionSearch = "" s.PredictionUnavailable = false g.executePredictions(s, nil, "open") } func (g *Game) closePredictionCounter(s *net.Session) { if s.PredictionCancel != nil { s.PredictionCancel() s.PredictionCancel = nil } s.PredictionActive = false s.PredictionEpoch++ // Invalidate any download, including an in-flight trade. s.PredictionBusy = false s.PredictionSelected = "" } // Exact world commands keep their meaning unless explicitly part of this UI. // Abbreviations are scoped to the counter; no new global command is registered. func predictionVerb(cmd string) (string, bool) { switch cmd { case "list": return "markets", true case "table", "game": return "refresh", true case "status", "portfolio", "board": return "active", true case "help": return "help", true case "leave", "exit": return "stop", true } for _, v := range predictionVerbs { if cmd == v { return v, true } } if _, exists := commandRegistry[cmd]; exists { return "", false } found := "" for _, v := range predictionVerbs { if strings.HasPrefix(v, cmd) { if found != "" { return "", true } found = v } } return found, found != "" } func (g *Game) predictionInputOwned(s *net.Session, cmd string) bool { if !s.PredictionActive || !g.atPredictionCounter(s.Player) { return false } if isAllDigits(cmd) { return true } _, ok := predictionVerb(cmd) return ok } func (g *Game) handlePredictionInput(s *net.Session, cmd string, args []string) bool { if !s.PredictionActive { return false } if !g.atPredictionCounter(s.Player) { g.closePredictionCounter(s) return false } if cmd == "help" && len(args) > 0 { return false } if isAllDigits(cmd) { action := "view" if s.PredictionScreen == "active" || s.PredictionScreen == "closed" { action = "holding" } g.executePredictions(s, []string{action, cmd}, "") return true } verb, owned := predictionVerb(cmd) if !owned { if cmd == "use" && predictionUseTarget(strings.Join(args, " ")) { return false } switch cmd { case "play", "use", "bank", "quit", "logout": g.closePredictionCounter(s) } return false } if verb == "" { s.WriteLine("That shortcut is ambiguous. Choose a command below.") g.predictionHints(s) return true } if verb == "stop" { g.closePredictionCounter(s) s.WriteLine(g.colorize(s, "casino_action", "You step away from the Prediction Exchange. Your contracts stay with the house.")) return true } switch verb { case "markets": verb = "list" case "back": args = nil case "help": g.predictionHelp(s) return true case "rules": if s.PredictionScreen != "view" || s.PredictionSelected == "" { g.predictionHelp(s) return true } } g.executePredictions(s, append([]string{verb}, args...), "") return true }