aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_color.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-16 01:59:27 -0400
committerhistoria <[not public]>2026-06-16 01:59:27 -0400
commit43f21aabae8924f35c12c8485e690aeefe0089fb (patch)
treeb5fbadb89df3cf4ffec86503bb8e2d7e52b27454 /internal/game/cmd_color.go
parent4cc1ddcd185509080b4b3e15d1646567edd51c9d (diff)
downloadthehouseoficarus-43f21aabae8924f35c12c8485e690aeefe0089fb.tar.gz
feat: overhauled ansi color, added prompt options
Diffstat (limited to 'internal/game/cmd_color.go')
-rw-r--r--internal/game/cmd_color.go168
1 files changed, 168 insertions, 0 deletions
diff --git a/internal/game/cmd_color.go b/internal/game/cmd_color.go
new file mode 100644
index 0000000..7a208a2
--- /dev/null
+++ b/internal/game/cmd_color.go
@@ -0,0 +1,168 @@
+package game
+
+import (
+ "fmt"
+ "strings"
+
+ "thirdcollapse/internal/color"
+ "thirdcollapse/internal/config"
+ "thirdcollapse/internal/net"
+ "thirdcollapse/internal/player"
+)
+
+func (g *Game) doColor(sess *net.Session, input string) {
+ if sess.Account == nil {
+ sess.WriteLine("\nYou must be logged into an account to set colors.")
+ return
+ }
+
+ if input == "" {
+ showColorTable(g, sess)
+ return
+ }
+
+ parts := strings.Fields(input)
+ target := strings.ToLower(parts[0])
+
+ if _, ok := config.DefaultColors()[target]; !ok {
+ sess.WriteLine(fmt.Sprintf("\nUnknown color target: %s", target))
+ sess.WriteLine("Available targets:")
+ for _, t := range colorCategoryOrder {
+ sess.WriteLine(fmt.Sprintf(" %s", t))
+ }
+ return
+ }
+
+ if len(parts) == 1 {
+ current := g.getCurrentColor(sess, target)
+ source := g.colorSource(sess, target)
+ sess.WriteLine(fmt.Sprintf("\n%s = %s [source: %s]", target, current, source))
+ return
+ }
+
+ value := strings.Join(parts[1:], " ")
+
+ if len(parts) == 2 && parts[1] == "reset" {
+ g.saveAccountColor(sess, target, "")
+ sess.WriteLine(fmt.Sprintf("\n%s reset to default (%s).", target, config.DefaultColors()[target]))
+ return
+ }
+
+ if value == "off" {
+ g.saveAccountColor(sess, target, "off")
+ sess.WriteLine(fmt.Sprintf("\n%s set to off.", target))
+ return
+ }
+
+ spec := color.Parse(value)
+ if spec.Empty() && value != "" {
+ sess.WriteLine(fmt.Sprintf("\nInvalid color string: %s", value))
+ sess.WriteLine("Format: fg=<color> bg=<color> bold dim italic underline")
+ sess.WriteLine("Example: fg=green bg=black bold")
+ return
+ }
+
+ g.saveAccountColor(sess, target, value)
+ sess.WriteLine(fmt.Sprintf("\n%s set to %s.", target, value))
+}
+
+func (g *Game) saveAccountColor(sess *net.Session, target, value string) {
+ if value == "" {
+ if sess.Account.Colors != nil {
+ delete(sess.Account.Colors, target)
+ }
+ } else {
+ if sess.Account.Colors == nil {
+ sess.Account.Colors = make(map[string]string)
+ }
+ sess.Account.Colors[target] = value
+ }
+
+ acc, err := g.AccountStore.LoadAccount(sess.Account.Name)
+ if err != nil {
+ sess.WriteLine("\nError loading account.")
+ return
+ }
+ if value == "" {
+ if acc.Colors != nil {
+ delete(acc.Colors, target)
+ }
+ } else {
+ if acc.Colors == nil {
+ acc.Colors = make(map[string]string)
+ }
+ acc.Colors[target] = value
+ }
+ g.AccountStore.SaveAccount(acc)
+}
+
+func (g *Game) getCurrentColor(sess *net.Session, category string) string {
+ if sess.Account != nil && sess.Account.Colors != nil {
+ if val, ok := sess.Account.Colors[category]; ok {
+ if val == "off" {
+ return "off"
+ }
+ if val != "" {
+ return val
+ }
+ }
+ }
+ if g.ColorConfig != nil {
+ if val, ok := (*g.ColorConfig)[category]; ok && val != "" {
+ return val
+ }
+ }
+ return config.DefaultColors()[category]
+}
+
+func (g *Game) colorSource(sess *net.Session, category string) string {
+ if sess.Account != nil && sess.Account.Colors != nil {
+ if _, ok := sess.Account.Colors[category]; ok {
+ return "account"
+ }
+ }
+ if g.ColorConfig != nil {
+ if _, ok := (*g.ColorConfig)[category]; ok {
+ return "default"
+ }
+ }
+ return "builtin"
+}
+
+var colorCategoryOrder = []string{
+ "room_name",
+ "room_number",
+ "room_desc",
+ "direction",
+ "exit_direction",
+ "exit_name",
+ "mob_name",
+ "friendly_npc",
+ "hostile_npc",
+ "damage",
+ "enemy_hp",
+ "character_hp",
+ "xp",
+ "level_up",
+ "item",
+ "player_name",
+ "death",
+ "victory",
+ "miss",
+ "error",
+}
+
+func showColorTable(g *Game, sess *net.Session) {
+ p := sess.Player.(*player.Player)
+ table := &Table{
+ Columns: []string{"Target", "Color", "Source"},
+ }
+ for _, cat := range colorCategoryOrder {
+ val := g.getCurrentColor(sess, cat)
+ source := g.colorSource(sess, cat)
+ table.Rows = append(table.Rows, []string{cat, val, source})
+ }
+ for _, line := range table.Render(p.OptionBool("unicode")) {
+ sess.WriteLine(line)
+ }
+}