diff options
Diffstat (limited to 'internal/game/prompt.go')
| -rw-r--r-- | internal/game/prompt.go | 133 |
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 +} |
