feat: room counter, taunt turns, item labels, shop gold display

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 13:45:19 +09:00
parent 1104c6e4e9
commit 9ed71eeccd
2 changed files with 40 additions and 4 deletions

View File

@@ -34,7 +34,17 @@ func renderMap(floor *dungeon.Floor) string {
return "" return ""
} }
headerStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true) headerStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
header := headerStyle.Render(fmt.Sprintf("── Catacombs B%d ──", floor.Number))
// Count explored rooms
explored := 0
for _, r := range floor.Rooms {
if r.Visited || r.Cleared {
explored++
}
}
total := len(floor.Rooms)
header := headerStyle.Render(fmt.Sprintf("── Catacombs B%d ── %d/%d Rooms ──", floor.Number, explored, total))
return header + "\n" + dungeon.RenderFloor(floor, floor.CurrentRoom, true) return header + "\n" + dungeon.RenderFloor(floor, floor.CurrentRoom, true)
} }
@@ -266,7 +276,7 @@ func renderEnemyPanel(monsters []*entity.Monster, targetCursor int) string {
hpBar := renderHPBar(m.HP, m.MaxHP, 12) hpBar := renderHPBar(m.HP, m.MaxHP, 12)
taunt := "" taunt := ""
if m.TauntTarget { if m.TauntTarget {
taunt = styleStatus.Render(" [TAUNTED]") taunt = styleStatus.Render(fmt.Sprintf(" [TAUNTED %dt]", m.TauntTurns))
} }
sb.WriteString(fmt.Sprintf(" %s[%d] %s %s %d/%d%s\n\n", sb.WriteString(fmt.Sprintf(" %s[%d] %s %s %d/%d%s\n\n",
marker, i, styleEnemy.Render(m.Name), hpBar, m.HP, m.MaxHP, taunt)) marker, i, styleEnemy.Render(m.Name), hpBar, m.HP, m.MaxHP, taunt))

View File

@@ -4,26 +4,52 @@ import (
"fmt" "fmt"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/tolelom/catacombs/entity"
"github.com/tolelom/catacombs/game" "github.com/tolelom/catacombs/game"
) )
func itemTypeLabel(item entity.Item) string {
switch item.Type {
case entity.ItemWeapon:
return fmt.Sprintf("[ATK+%d]", item.Bonus)
case entity.ItemArmor:
return fmt.Sprintf("[DEF+%d]", item.Bonus)
case entity.ItemConsumable:
return fmt.Sprintf("[HP+%d]", item.Bonus)
default:
return fmt.Sprintf("[+%d]", item.Bonus)
}
}
func renderShop(state game.GameState, width, height int, shopMsg string) string { func renderShop(state game.GameState, width, height int, shopMsg string) string {
headerStyle := lipgloss.NewStyle(). headerStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("226")). Foreground(lipgloss.Color("226")).
Bold(true) Bold(true)
goldStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("220"))
msgStyle := lipgloss.NewStyle(). msgStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("196")). Foreground(lipgloss.Color("196")).
Bold(true) Bold(true)
header := headerStyle.Render("── Shop ──") header := headerStyle.Render("── Shop ──")
// Show current player's gold
goldLine := ""
for _, p := range state.Players {
inventoryCount := len(p.Inventory)
goldLine += goldStyle.Render(fmt.Sprintf(" %s — Gold: %d Items: %d/10", p.Name, p.Gold, inventoryCount))
goldLine += "\n"
}
items := "" items := ""
for i, item := range state.ShopItems { for i, item := range state.ShopItems {
items += fmt.Sprintf(" [%d] %s (+%d) — %d gold\n", i+1, item.Name, item.Bonus, item.Price) label := itemTypeLabel(item)
items += fmt.Sprintf(" [%d] %s %s — %d gold\n", i+1, item.Name, label, item.Price)
} }
menu := "[1-3] Buy [Q] Leave Shop" menu := "[1-3] Buy [Q] Leave Shop"
parts := []string{header, "", items, "", menu} parts := []string{header, "", goldLine, items, "", menu}
if shopMsg != "" { if shopMsg != "" {
parts = append(parts, "", msgStyle.Render(shopMsg)) parts = append(parts, "", msgStyle.Render(shopMsg))
} }