mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Expedition autopilot Phase 4 + rogue sneak attack + TwinBee voice sweep
Tedium-removal pass driven by live play feedback. Three big threads: Expedition autopilot Phase 4 — background auto-run + harvest-until-dry: - New expeditionAutoRunTicker walks active expeditions every 15min (5min tick, per-expedition CAS on new last_autorun_at column). Skips combat sessions, briefing/recap quiet windows, expeditions <30min old. - Walks up to 3 rooms/tick with compact narration; suppresses DMs when 0 rooms walked or just hitting the per-tick cap (no "stretch complete" filler). Player only hears from the bot when a real decision is needed. - Compact mode: one-line combat narration for trash/elite, auto-resolves elite doorways via the forward-sim engine (boss still pauses). Threaded via new advanceOnceWithOpts → resolveRoom → resolveCombatRoom. - Auto-harvest now grinds each Common/Uncommon node until dry (cap at 8 attempts/visit), mirroring manual !scavenge retries. Rare+ still pauses. - Ambient ticker: anti-repeat by Kind via new last_ambient_kind column (avoids two pack_rat DMs in a row when the pool only has 6 lines). - !expedition go <n> now routes to the fork-choice handler when active + numeric; fork footer rewritten to suggest !expedition go instead of !zone go. Boss/Elite doorway: formatNextRoomMessage routes the action hint by next room type and autopilot loop breaks via new nextRoomType field so "Room X/Y — Boss" doesn't double-print with contradictory hints (!zone advance vs !fight). - runAutopilotWalk extracted from expeditionCmdRun so foreground and background share the loop body. Rogue Sneak Attack actually exists now: - Audit found the rogue's "Sneak Attack" passive was AutoCritFirst + 5% damage rider. No Nd6, ever. Phase 2 Monte Carlo masked this with a small flat buff; the class's defining mechanic never matched its tooltip or 5e identity. - Added SneakAttackDie int to CombatModifiers, per-hit Nd6 in combat_primitives.go (same lane as DivineStrikePerHit). Scales with level: 1d6 at L1-2 ... 4d6 at L7-8 ... capped at 10d6 at L19-20. - AutoCritFirst + 5% rider retained as bonuses on top of working sneak attack — preserves the opener-burst feel. - L7 rogue expected per-hit ~8 → ~22 damage. Valdris fight math goes from "16 rounds to kill, die in 8" to winnable. TwinBee voice sweep (Phase B3): - ~530 line changes across 24 files replacing third-person "TwinBee notes/files/tracks/respects/..." constructions with first-person inside flavor string literals. Code identifiers (TwinBeeLine, twinBeeLine, etc.), chat-prefix labels (🎭 **TwinBee:**), item names (TwinBee's Bell), achievements, and game-title references in fun.go (Konami TwinBee ship) left intact. - Catches a real bug: Valdris fight rendered "TwinBee marks the Legendary Resistance" mid-combat in third person, contradicting the Phase B2 convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,12 +15,12 @@ package flavor
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var EliteRoomEntryWarrens = []string{
|
||||
"The chamber widens. A hobgoblin in lacquered scale stands at the center, arms folded, watching the door. The lesser goblins go quiet. TwinBee notes the silence is the part you should be paying attention to.",
|
||||
"A war-banner hangs from the ceiling — three clans stitched together with rough thread. Beneath it, a Warchief turns to face you with the slow patience of someone who has done this part a hundred times. TwinBee straightens up out of habit.",
|
||||
"The corridor opens into a drilling ground. Goblins in formation. A Hobgoblin barking orders that stop the moment your boot hits the threshold. TwinBee has seen this exact composition in Shining Force and finds the parallel unhelpful.",
|
||||
"You smell the polish before you see the armor. The Warchief's blade is oiled, his straps are tight, his stance is correct. TwinBee acknowledges, with reluctance, that this one was trained.",
|
||||
"A circle of torches. A throne of stacked shields. The hobgoblin seated on it does not stand. He gestures, single-finger, in a way TwinBee universally translates as 'come here.' You go there.",
|
||||
"The room has been cleared for combat. Rugs rolled, braziers spaced evenly, sand on the floor for grip. TwinBee respects the preparation and is professionally annoyed by it.",
|
||||
"The chamber widens. A hobgoblin in lacquered scale stands at the center, arms folded, watching the door. The lesser goblins go quiet. I note the silence is the part you should be paying attention to.",
|
||||
"A war-banner hangs from the ceiling — three clans stitched together with rough thread. Beneath it, a Warchief turns to face you with the slow patience of someone who has done this part a hundred times. I straighten up out of habit.",
|
||||
"The corridor opens into a drilling ground. Goblins in formation. A Hobgoblin barking orders that stop the moment your boot hits the threshold. I have seen this exact composition in Shining Force and find the parallel unhelpful.",
|
||||
"You smell the polish before you see the armor. The Warchief's blade is oiled, his straps are tight, his stance is correct. I acknowledge, with reluctance, that this one was trained.",
|
||||
"A circle of torches. A throne of stacked shields. The hobgoblin seated on it does not stand. He gestures, single-finger, in a way I universally translates as 'come here.' You go there.",
|
||||
"The room has been cleared for combat. Rugs rolled, braziers spaced evenly, sand on the floor for grip. I respect the preparation and am professionally annoyed by it.",
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -30,23 +30,23 @@ var EliteRoomEntryWarrens = []string{
|
||||
|
||||
// Surprise Attack: +2d6 if player has not acted this combat.
|
||||
var GrolSurpriseAttackLines = []string{
|
||||
"Grol moves before you do. He always moves before you do. TwinBee notes — too late — that the first hit in this fight is his.",
|
||||
"The cleaver comes around in an arc that started before you were in the room. TwinBee winces in advance.",
|
||||
"He's not waiting for the fight to start. The fight starts when he says it does. TwinBee marks the lesson and files it under 'next time.'",
|
||||
"Grol moves before you do. He always moves before you do. I note — too late — that the first hit in this fight is his.",
|
||||
"The cleaver comes around in an arc that started before you were in the room. I wince in advance.",
|
||||
"He's not waiting for the fight to start. The fight starts when he says it does. I mark the lesson and file it under 'next time.'",
|
||||
}
|
||||
|
||||
// Heart of Hruggek: crits deal max damage (no roll).
|
||||
var GrolHeartOfHruggekLines = []string{
|
||||
"Grol crits and the dice don't roll. TwinBee has seen this Bugbear blessing once before. The number is the maximum number, every time, no negotiation.",
|
||||
"His critical lands flat-max. No spread, no luck — just Hruggek's blessing collecting on a long-overdue debt. TwinBee notes the damage with grim respect.",
|
||||
"The crit hits like a Final Fantasy 'Berserk' status — capped, deterministic, unkind. TwinBee skips the roll and writes the maximum.",
|
||||
"Grol crits and the dice don't roll. I have seen this Bugbear blessing once before. The number is the maximum number, every time, no negotiation.",
|
||||
"His critical lands flat-max. No spread, no luck — just Hruggek's blessing collecting on a long-overdue debt. I note the damage with grim respect.",
|
||||
"The crit hits like a Final Fantasy 'Berserk' status — capped, deterministic, unkind. I skip the roll and write the maximum.",
|
||||
}
|
||||
|
||||
// Terrifying Roar: 1/combat; allies +2 to hit for 2 turns; player WIS DC 13 or Frightened.
|
||||
var GrolTerrifyingRoarLines = []string{
|
||||
"Grol throws his head back and roars. The room shakes. The goblins around him stand straighter. TwinBee says: 'WIS save. Now.'",
|
||||
"The roar isn't a sound — it's a pressure change. Your knees know about it before your ears do. TwinBee respects the technique and asks you to roll Wisdom.",
|
||||
"He bellows once. The torchlight bends. The goblins answer with cheers that sound rehearsed. TwinBee notes the buff is up; you have two turns to outlast it.",
|
||||
"Grol throws his head back and roars. The room shakes. The goblins around him stand straighter. I say: 'WIS save. Now.'",
|
||||
"The roar isn't a sound — it's a pressure change. Your knees know about it before your ears do. I respect the technique and ask you to roll Wisdom.",
|
||||
"He bellows once. The torchlight bends. The goblins answer with cheers that sound rehearsed. I note the buff is up; you have two turns to outlast it.",
|
||||
}
|
||||
|
||||
// GrolSignatureCallouts — combined pool the boss-entry composer samples
|
||||
@@ -67,10 +67,10 @@ var GrolSignatureCallouts = func() []string {
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
var LoreLinesWarrens = []string{
|
||||
"The Warrens are old. Not goblin-old — older. The tunnels predate the goblins and the goblins know it. They've widened doorways meant for something taller and braced ceilings meant for something heavier. TwinBee has theories about what was here first. None of them are reassuring.",
|
||||
"Grol united the three clans by killing each of their war-chiefs in single combat, in order, in one afternoon. The fourth clan declined to send a chief and pledged loyalty by letter. TwinBee finds the letter, professionally, very funny.",
|
||||
"The graffiti on the walls dates the occupation. Goblins date by leaders and the names go back six generations. TwinBee can read goblin script when pressed and notes that the third-oldest name is one a paladin order would still recognize.",
|
||||
"The Merchant's Road above doesn't know about the Warrens. The Merchant's Road above used to know about the Warrens. TwinBee was here when it stopped knowing, and notes that the people in charge of Knowing About Things were the first to disappear.",
|
||||
"Hobgoblins hold formation; goblins hold grudges; bugbears hold pretty much anything they pick up. TwinBee offers this not as a joke but as a tactical primer that will save you a lot of HP if you remember it.",
|
||||
"The belt Grol wears is not a trophy. It is a contract. Each tooth on it is a debt some troll forgave when the wearing of the belt began, and the debts run in both directions. TwinBee strongly suggests not breaking the belt unless you mean to.",
|
||||
"The Warrens are old. Not goblin-old — older. The tunnels predate the goblins and the goblins know it. They've widened doorways meant for something taller and braced ceilings meant for something heavier. I have theories about what was here first. None of them are reassuring.",
|
||||
"Grol united the three clans by killing each of their war-chiefs in single combat, in order, in one afternoon. The fourth clan declined to send a chief and pledged loyalty by letter. I find the letter, professionally, very funny.",
|
||||
"The graffiti on the walls dates the occupation. Goblins date by leaders and the names go back six generations. I can read goblin script when pressed and note that the third-oldest name is one a paladin order would still recognize.",
|
||||
"The Merchant's Road above doesn't know about the Warrens. The Merchant's Road above used to know about the Warrens. I was here when it stopped knowing, and note that the people in charge of Knowing About Things were the first to disappear.",
|
||||
"Hobgoblins hold formation; goblins hold grudges; bugbears hold pretty much anything they pick up. I offer this not as a joke but as a tactical primer that will save you a lot of HP if you remember it.",
|
||||
"The belt Grol wears is not a trophy. It is a contract. Each tooth on it is a debt some troll forgave when the wearing of the belt began, and the debts run in both directions. I strongly suggests not breaking the belt unless you mean to.",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user