aboutsummaryrefslogtreecommitdiff
path: root/internal/game/prompt.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/prompt.go')
-rw-r--r--internal/game/prompt.go133
1 files changed, 133 insertions, 0 deletions
diff --git a/internal/game/prompt.go b/internal/game/prompt.go
new file mode 100644
index 0000000..2fc36ac
--- /dev/null
+++ b/internal/game/prompt.go
@@ -0,0 +1,133 @@
+package game
+
+import (
+ "fmt"
+ "strings"
+
+ "thirdcollapse/internal/color"
+ "thirdcollapse/internal/combat"
+ "thirdcollapse/internal/net"
+ "thirdcollapse/internal/player"
+)
+
+func (g *Game) promptStr(sess *net.Session) string {
+ prompt := "> "
+ if p, ok := sess.Player.(*player.Player); ok && p != nil {
+ if custom := p.OptionString("prompt"); custom != "" {
+ prompt = custom
+ }
+ }
+
+ prompt = g.expandPromptColors(sess, prompt)
+ prompt = g.expandPromptVars(sess, prompt)
+ return prompt
+}
+
+func (g *Game) expandPromptColors(sess *net.Session, text string) string {
+ mode := g.colorMode(sess)
+ for {
+ start := strings.Index(text, "{")
+ if start < 0 {
+ break
+ }
+
+ end := strings.Index(text[start+1:], "}")
+ if end < 0 {
+ break
+ }
+ end += start + 1
+ specStr := text[start+1 : end]
+
+ if specStr == "" || specStr == "/" {
+ break
+ }
+
+ spec := color.Parse(specStr)
+ if spec.Empty() {
+ break
+ }
+
+ closeStart := strings.Index(text[end+1:], "{/}")
+ if closeStart < 0 {
+ break
+ }
+ closeStart += end + 1
+ closeEnd := closeStart + 3
+
+ inner := text[end+1 : closeStart]
+ colored := color.Render(mode, spec, inner)
+
+ text = text[:start] + colored + text[closeEnd:]
+ }
+ return text
+}
+
+func (g *Game) expandPromptVars(sess *net.Session, text string) string {
+ p, ok := sess.Player.(*player.Player)
+ if !ok || p == nil {
+ return text
+ }
+
+ text = strings.ReplaceAll(text, "%%", "\x00")
+ text = strings.ReplaceAll(text, "%h", fmt.Sprint(p.HP))
+ text = strings.ReplaceAll(text, "%H", fmt.Sprint(p.MaxHP()))
+ text = strings.ReplaceAll(text, "%c", fmt.Sprint(p.Credits))
+ text = strings.ReplaceAll(text, "%i", fmt.Sprint(p.FreeSlots()))
+ text = strings.ReplaceAll(text, "%s", attackStyleShort(p.AttackStyle))
+ text = strings.ReplaceAll(text, "%S", attackStyleLong(p.AttackStyle))
+
+ mobHP, mobMaxHP := "", ""
+ if cs := combat.GetCombat(p.Name); cs != nil {
+ mob := g.MobStore.GetInstance(cs.MobID)
+ if mob != nil && mob.HP > 0 {
+ mobHP = fmt.Sprint(mob.HP)
+ mobMaxHP = fmt.Sprint(mob.MaxHP)
+ }
+ }
+ text = strings.ReplaceAll(text, "%m", mobHP)
+ text = strings.ReplaceAll(text, "%M", mobMaxHP)
+
+ for _, sk := range player.AllSkills {
+ tag := string(sk)
+ text = strings.ReplaceAll(text, "%X_"+tag, fmt.Sprint(p.Skills[sk]))
+ text = strings.ReplaceAll(text, "%x_"+tag, fmt.Sprint(xpToLevel(p, sk)))
+ }
+
+ text = strings.ReplaceAll(text, "\x00", "%")
+ return text
+}
+
+func attackStyleShort(s player.AttackStyle) string {
+ switch s {
+ case player.Accurate:
+ return "acc"
+ case player.Aggressive:
+ return "agg"
+ case player.Defensive:
+ return "def"
+ case player.Balanced:
+ return "bal"
+ }
+ return "acc"
+}
+
+func attackStyleLong(s player.AttackStyle) string {
+ switch s {
+ case player.Accurate:
+ return "accurate"
+ case player.Aggressive:
+ return "aggressive"
+ case player.Defensive:
+ return "defensive"
+ case player.Balanced:
+ return "balanced"
+ }
+ return "accurate"
+}
+
+func xpToLevel(p *player.Player, sk player.SkillName) int {
+ currentXP := p.Skills[sk]
+ currentLevel := p.Level(sk)
+ nextLevelXP := player.XPForLevel(currentLevel + 1)
+ return nextLevelXP - currentXP
+}