Add masterwork rework, arena combat log, Death's Reprieve fix, and wordle improvements

Adventure — Masterwork Rework:
- Expand from 3 generic items to 15 tiered masterwork items across
  mining (weapon), fishing (armor), and foraging (boots) with per-tier
  drop rates (5%/4%/3%/2%/1.5%) and location gating
- Skill-specific cross-skill bonuses replace flat masterwork check
- Auto-equip if better, silent discard for duplicates, inventory for rest
- Add !adventure equip command for manual masterwork equipping
- Tiered room announcements: T1-2 DM only, T3 quiet, T4-5 full
- First-drop detection with special message
- Character sheet shows /⚔️ markers for masterwork/arena gear
- Sell protection for special gear in shop

Adventure — Arena Combat Log:
- Turn-based Dragon Quest style narrative for arena fights
- Outcome-first design: roll determines win/loss, log assembled backward
- No-repeat flavor text via actionPicker with per-pool tracking
- 60 participation XP on arena loss

Adventure — Death's Reprieve Fix:
- All equipment set to 1 condition instead of death-level degradation

Wordle:
- Refactored word sourcing and expanded fallback word list
- Simplified Wordnik integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-03-29 16:24:59 -07:00
parent 31a1d00236
commit 0a1359de46
19 changed files with 2427 additions and 289 deletions

View File

@@ -3,6 +3,7 @@ package plugin
import (
"fmt"
"strings"
"time"
)
// ── Arena Tier Menu ─────────────────────────────────────────────────────────
@@ -30,7 +31,10 @@ func renderArenaTierMenu(char *AdventureCharacter, stats *ArenaPersonalStats) st
stats.TotalRuns, stats.TotalDeaths, stats.TotalEarnings))
}
b.WriteString("\n`!arena tier <1-5>` — Enter a tier\n")
b.WriteString("\n⛑️ _Today's helmets are provided by Brim & Battle — celebrated makers of baseball hats — and proud sponsors of the Arena. ")
b.WriteString("Their new VeriFort line of field-evaluated combat headgear represents an exciting expansion beyond their area of expertise. ")
b.WriteString("Winners may receive a complimentary sample. Brim & Battle thanks you for your participation in their ongoing verification process._\n\n")
b.WriteString("`!arena tier <1-5>` — Enter a tier\n")
b.WriteString("`!arena stats` — Your arena stats\n")
b.WriteString("`!arena leaderboard` — Top arena players\n")
return b.String()
@@ -262,6 +266,39 @@ func renderArenaLevelGate(tier *ArenaTier, playerLevel int) string {
tier.Number, tier.Name, tier.MinLevel, playerLevel)
}
// ── Helmet Drop ────────────────────────────────────────────────────────────
func renderArenaHelmetDrop(gear *ArenaGearSet) string {
var b strings.Builder
b.WriteString(fmt.Sprintf("⛑️ **Equipment Drop: %s**\n\n", gear.HelmetName))
b.WriteString(fmt.Sprintf("_%s_\n\n", gear.Description))
b.WriteString(fmt.Sprintf("Tier %d Arena gear — 1.5x effectiveness. ", gear.Tier))
switch gear.SetKey {
case "bloodied":
b.WriteString("Set bonus: **Survivor's Instinct** — +3% to all activity success rates.")
case "ironclad":
b.WriteString("Set bonus: **Battle-Hardened** — +5% XP gain from all activities.")
case "tempered":
b.WriteString("Set bonus: **Seasoned** — Equipment condition degrades 25% slower across all slots.")
case "champions":
b.WriteString("Set bonus: **Commanding Presence** — +10% to equipment score in all probability calculations.")
case "sovereign":
b.WriteString("Set bonus: **Death's Reprieve** — Once per 7 days, survive a lethal outcome instead of dying.")
}
b.WriteString("\n\nEquipped automatically.")
return b.String()
}
// ── Death's Reprieve Announcement ──────────────────────────────────────────
func renderArenaDeathReprieve(playerName, location string, nextWindow time.Time) string {
return fmt.Sprintf("⚔️ **%s**'s Sovereign gear activated **Death's Reprieve**. "+
"They should be dead. They are not. %s will have to try harder. Next window: %s.",
playerName, location, nextWindow.Format("2006-01-02 15:04 UTC"))
}
// ── Already In Run Message ──────────────────────────────────────────────────
func renderArenaAlreadyInRun(run *ArenaRun) string {