mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Adv 2.0 Phase L2 step 6: arena render reads → DnDCharacter
renderArenaStreakEntry now takes *DnDCharacter and reads c.Level instead of AdventureCharacter.CombatLevel. renderArenaStatus drops its unused *AdventureCharacter arg. Callers in handleArenaMenu / handleArenaStatus updated; menu path uses ensureCharForDnDCmd to fetch (or auto-migrate) the sheet. Tests switched accordingly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,7 +101,11 @@ func (p *AdventurePlugin) handleArenaMenu(ctx MessageContext) error {
|
|||||||
|
|
||||||
stats := loadArenaPersonalStats(ctx.Sender)
|
stats := loadArenaPersonalStats(ctx.Sender)
|
||||||
monster := arenaGetMonster(1, 1)
|
monster := arenaGetMonster(1, 1)
|
||||||
text := renderArenaStreakEntry(char, stats, tier, monster)
|
dndChar, err := p.ensureCharForDnDCmd(ctx.Sender, char)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendDM(ctx.Sender, "Failed to load character sheet.")
|
||||||
|
}
|
||||||
|
text := renderArenaStreakEntry(dndChar, stats, tier, monster)
|
||||||
return p.SendDM(ctx.Sender, text)
|
return p.SendDM(ctx.Sender, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,8 +301,7 @@ func (p *AdventurePlugin) handleArenaBail(ctx MessageContext) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdventurePlugin) handleArenaStatus(ctx MessageContext) error {
|
func (p *AdventurePlugin) handleArenaStatus(ctx MessageContext) error {
|
||||||
char, err := loadAdvCharacter(ctx.Sender)
|
if _, err := loadAdvCharacter(ctx.Sender); err != nil {
|
||||||
if err != nil {
|
|
||||||
return p.SendDM(ctx.Sender, "No adventurer found.")
|
return p.SendDM(ctx.Sender, "No adventurer found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +310,7 @@ func (p *AdventurePlugin) handleArenaStatus(ctx MessageContext) error {
|
|||||||
return p.SendDM(ctx.Sender, "No active arena run. Start one with `!arena`.")
|
return p.SendDM(ctx.Sender, "No active arena run. Start one with `!arena`.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.SendDM(ctx.Sender, renderArenaStatus(run, char))
|
return p.SendDM(ctx.Sender, renderArenaStatus(run))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdventurePlugin) handleArenaStats(ctx MessageContext) error {
|
func (p *AdventurePlugin) handleArenaStats(ctx MessageContext) error {
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ import (
|
|||||||
|
|
||||||
// ── Arena Tier Menu ─────────────────────────────────────────────────────────
|
// ── Arena Tier Menu ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func renderArenaStreakEntry(char *AdventureCharacter, stats *ArenaPersonalStats, tier *ArenaTier, firstMonster *ArenaMonster) string {
|
func renderArenaStreakEntry(c *DnDCharacter, stats *ArenaPersonalStats, tier *ArenaTier, firstMonster *ArenaMonster) string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
b.WriteString("⚔️ **THE ARENA**\n\n")
|
b.WriteString("⚔️ **THE ARENA**\n\n")
|
||||||
b.WriteString("The Arena is a streak. You start at Tier 1 and fight your way down.\n")
|
b.WriteString("The Arena is a streak. You start at Tier 1 and fight your way down.\n")
|
||||||
b.WriteString("After each tier, you have 30 seconds to bail or you auto-advance.\n")
|
b.WriteString("After each tier, you have 30 seconds to bail or you auto-advance.\n")
|
||||||
b.WriteString("Death forfeits all accumulated rewards.\n\n")
|
b.WriteString("Death forfeits all accumulated rewards.\n\n")
|
||||||
|
|
||||||
b.WriteString(fmt.Sprintf("Combat Level: %d\n\n", char.CombatLevel))
|
b.WriteString(fmt.Sprintf("Level: %d\n\n", c.Level))
|
||||||
|
|
||||||
for i := range arenaTiers {
|
for i := range arenaTiers {
|
||||||
t := &arenaTiers[i]
|
t := &arenaTiers[i]
|
||||||
eligible := char.CombatLevel >= t.MinLevel
|
eligible := c.Level >= t.MinLevel
|
||||||
icon := "🔒"
|
icon := "🔒"
|
||||||
if eligible {
|
if eligible {
|
||||||
icon = "⬚"
|
icon = "⬚"
|
||||||
@@ -91,7 +91,7 @@ func renderArenaDeath(tier *ArenaTier, round int, monster *ArenaMonster, lostEar
|
|||||||
|
|
||||||
// ── Status ──────────────────────────────────────────────────────────────────
|
// ── Status ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func renderArenaStatus(run *ArenaRun, char *AdventureCharacter) string {
|
func renderArenaStatus(run *ArenaRun) string {
|
||||||
tier := arenaGetTier(run.Tier)
|
tier := arenaGetTier(run.Tier)
|
||||||
if tier == nil {
|
if tier == nil {
|
||||||
return "No active arena run."
|
return "No active arena run."
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ func TestArenaDeathChance_Components(t *testing.T) {
|
|||||||
// ── Render Tests ────────────────────────────────────────────────────────────
|
// ── Render Tests ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
func TestRenderArenaStreakEntry(t *testing.T) {
|
func TestRenderArenaStreakEntry(t *testing.T) {
|
||||||
char := &AdventureCharacter{CombatLevel: 30}
|
char := &DnDCharacter{Level: 30}
|
||||||
tier := arenaGetTier(1)
|
tier := arenaGetTier(1)
|
||||||
monster := arenaGetMonster(1, 1)
|
monster := arenaGetMonster(1, 1)
|
||||||
|
|
||||||
@@ -576,7 +576,7 @@ func TestArenaGearDropRates_Decreasing(t *testing.T) {
|
|||||||
// ── Render Tests (New/Updated) ─────────────────────────────────────────────
|
// ── Render Tests (New/Updated) ─────────────────────────────────────────────
|
||||||
|
|
||||||
func TestRenderArenaStreakEntry_ShowsMultipliers(t *testing.T) {
|
func TestRenderArenaStreakEntry_ShowsMultipliers(t *testing.T) {
|
||||||
char := &AdventureCharacter{CombatLevel: 50}
|
char := &DnDCharacter{Level: 50}
|
||||||
tier := arenaGetTier(1)
|
tier := arenaGetTier(1)
|
||||||
monster := arenaGetMonster(1, 1)
|
monster := arenaGetMonster(1, 1)
|
||||||
|
|
||||||
@@ -604,7 +604,7 @@ func TestRenderArenaStreakEntry_ShowsMultipliers(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenderArenaStreakEntry_HighLevel_AllEligible(t *testing.T) {
|
func TestRenderArenaStreakEntry_HighLevel_AllEligible(t *testing.T) {
|
||||||
// T5 requires level 70, so use level 70+ to unlock everything
|
// T5 requires level 70, so use level 70+ to unlock everything
|
||||||
char := &AdventureCharacter{CombatLevel: 70}
|
char := &DnDCharacter{Level: 70}
|
||||||
tier := arenaGetTier(1)
|
tier := arenaGetTier(1)
|
||||||
monster := arenaGetMonster(1, 1)
|
monster := arenaGetMonster(1, 1)
|
||||||
|
|
||||||
@@ -641,9 +641,8 @@ func TestRenderArenaRoundStart_ZeroEarnings(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenderArenaStatus_Active(t *testing.T) {
|
func TestRenderArenaStatus_Active(t *testing.T) {
|
||||||
run := &ArenaRun{Tier: 2, Round: 3, Status: "active", Earnings: 8000, TierEarnings: 1500, RoundsSurvived: 6}
|
run := &ArenaRun{Tier: 2, Round: 3, Status: "active", Earnings: 8000, TierEarnings: 1500, RoundsSurvived: 6}
|
||||||
char := &AdventureCharacter{CombatLevel: 20}
|
|
||||||
|
|
||||||
text := renderArenaStatus(run, char)
|
text := renderArenaStatus(run)
|
||||||
if !strings.Contains(text, "Streak") {
|
if !strings.Contains(text, "Streak") {
|
||||||
t.Error("status should say Arena Streak")
|
t.Error("status should say Arena Streak")
|
||||||
}
|
}
|
||||||
@@ -660,9 +659,8 @@ func TestRenderArenaStatus_Active(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenderArenaStatus_Awaiting(t *testing.T) {
|
func TestRenderArenaStatus_Awaiting(t *testing.T) {
|
||||||
run := &ArenaRun{Tier: 3, Status: "awaiting", Earnings: 20000, TierEarnings: 0, RoundsSurvived: 12}
|
run := &ArenaRun{Tier: 3, Status: "awaiting", Earnings: 20000, TierEarnings: 0, RoundsSurvived: 12}
|
||||||
char := &AdventureCharacter{CombatLevel: 30}
|
|
||||||
|
|
||||||
text := renderArenaStatus(run, char)
|
text := renderArenaStatus(run)
|
||||||
if !strings.Contains(text, "advancing shortly") {
|
if !strings.Contains(text, "advancing shortly") {
|
||||||
t.Error("awaiting status should mention advancing")
|
t.Error("awaiting status should mention advancing")
|
||||||
}
|
}
|
||||||
@@ -793,9 +791,8 @@ func TestRenderArenaLevelGate(t *testing.T) {
|
|||||||
|
|
||||||
func TestRenderArenaStatus(t *testing.T) {
|
func TestRenderArenaStatus(t *testing.T) {
|
||||||
run := &ArenaRun{Tier: 3, Round: 2, Status: "active", Earnings: 5000, RoundsSurvived: 5}
|
run := &ArenaRun{Tier: 3, Round: 2, Status: "active", Earnings: 5000, RoundsSurvived: 5}
|
||||||
char := &AdventureCharacter{CombatLevel: 30}
|
|
||||||
|
|
||||||
text := renderArenaStatus(run, char)
|
text := renderArenaStatus(run)
|
||||||
if !strings.Contains(text, "Tier: 3") {
|
if !strings.Contains(text, "Tier: 3") {
|
||||||
t.Error("status should show tier")
|
t.Error("status should show tier")
|
||||||
}
|
}
|
||||||
@@ -1054,7 +1051,7 @@ func TestArenaStreakEuroMultiplier_Exact(t *testing.T) {
|
|||||||
// ── Streak Entry Shows Brim & Battle Sponsorship ──────────────────────────
|
// ── Streak Entry Shows Brim & Battle Sponsorship ──────────────────────────
|
||||||
|
|
||||||
func TestArenaStreakEntry_Sponsorship(t *testing.T) {
|
func TestArenaStreakEntry_Sponsorship(t *testing.T) {
|
||||||
char := &AdventureCharacter{CombatLevel: 1}
|
char := &DnDCharacter{Level: 1}
|
||||||
tier := arenaGetTier(1)
|
tier := arenaGetTier(1)
|
||||||
monster := arenaGetMonster(1, 1)
|
monster := arenaGetMonster(1, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ func TestIndexDDL_ContainsNewIndexes(t *testing.T) {
|
|||||||
Earnings: 500,
|
Earnings: 500,
|
||||||
TierEarnings: 100,
|
TierEarnings: 100,
|
||||||
}
|
}
|
||||||
status := renderArenaStatus(run, &AdventureCharacter{})
|
status := renderArenaStatus(run)
|
||||||
if !strings.Contains(status, "Tier: 2") {
|
if !strings.Contains(status, "Tier: 2") {
|
||||||
t.Error("renderArenaStatus should show tier")
|
t.Error("renderArenaStatus should show tier")
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ func TestIndexDDL_ContainsNewIndexes(t *testing.T) {
|
|||||||
|
|
||||||
// Awaiting state
|
// Awaiting state
|
||||||
run.Status = "awaiting"
|
run.Status = "awaiting"
|
||||||
status = renderArenaStatus(run, &AdventureCharacter{})
|
status = renderArenaStatus(run)
|
||||||
if !strings.Contains(status, "bail") {
|
if !strings.Contains(status, "bail") {
|
||||||
t.Error("renderArenaStatus should show bail command for awaiting runs")
|
t.Error("renderArenaStatus should show bail command for awaiting runs")
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ func TestRenderArenaStatus_NoInternalLeak(t *testing.T) {
|
|||||||
Earnings: 0,
|
Earnings: 0,
|
||||||
TierEarnings: 50,
|
TierEarnings: 50,
|
||||||
}
|
}
|
||||||
msg := renderArenaStatus(run, &AdventureCharacter{})
|
msg := renderArenaStatus(run)
|
||||||
|
|
||||||
for _, bad := range []string{"panic", "goroutine", "runtime.", "err="} {
|
for _, bad := range []string{"panic", "goroutine", "runtime.", "err="} {
|
||||||
if strings.Contains(msg, bad) {
|
if strings.Contains(msg, bad) {
|
||||||
|
|||||||
Reference in New Issue
Block a user