mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 08:52:42 +00:00
Adv 2.0 D&D polish: GM→DM rename, streamed zone combat, end-to-end scenario test
GM→DM rename across docs and code (GMNarrationType→DMNarrationType, GMState→DMState, narration constants, comments) so the system reads as "Dungeon Master" everywhere. Player-visible "GM mood" wording stays where it appears in flavor. Streamed zone/expedition combat: zone advance now stages patrol → patrol play-by-play → patrol resolution → room intro → room play-by-play → final outcome through sendZoneCombatMessages with 2–3s pacing (arena keeps its 5–8s window). Combat narrative lines pick up a compact d20-vs-AC roll annotation for hit/crit/miss/block events. Combat outcome polish: dndHPSnapshot lets narration show sheet HP rather than legacy combat-engine HP, and markAdventureDead clears the zombie state where hp_current was 0 but the legacy alive flag stayed true after a D&D-layer KO. Adv 2.0 announcement (ADVENTURE_2.0_ANNOUNCEMENT.md), README rewrite covering the new layer, and adv2_scenario_test.go — a full zone-run + expedition + harvest playthrough against a copy of the prod DB asserting persisted state end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,7 @@ type DungeonRun struct {
|
||||
BossDefeated bool
|
||||
Abandoned bool
|
||||
LootCollected []string
|
||||
GMMood int
|
||||
DMMood int
|
||||
StartedAt time.Time
|
||||
LastActionAt time.Time
|
||||
CompletedAt *time.Time
|
||||
@@ -178,6 +178,10 @@ func startZoneRun(userID id.UserID, zoneID ZoneID, dndLevel int, rng *rand.Rand)
|
||||
seq := generateRoomSequence(zone, rng)
|
||||
seqJSON, _ := json.Marshal(seq)
|
||||
|
||||
startMood := 50
|
||||
if isHol, _ := isHolidayToday(); isHol {
|
||||
startMood = 55
|
||||
}
|
||||
run := &DungeonRun{
|
||||
RunID: newRunID(),
|
||||
UserID: string(userID),
|
||||
@@ -186,7 +190,7 @@ func startZoneRun(userID id.UserID, zoneID ZoneID, dndLevel int, rng *rand.Rand)
|
||||
TotalRooms: len(seq),
|
||||
RoomSeq: seq,
|
||||
RoomsCleared: []int{},
|
||||
GMMood: 50,
|
||||
DMMood: startMood,
|
||||
StartedAt: time.Now().UTC(),
|
||||
LastActionAt: time.Now().UTC(),
|
||||
}
|
||||
@@ -194,8 +198,8 @@ func startZoneRun(userID id.UserID, zoneID ZoneID, dndLevel int, rng *rand.Rand)
|
||||
INSERT INTO dnd_zone_run
|
||||
(run_id, user_id, zone_id, current_room, total_rooms,
|
||||
room_seq_json, rooms_cleared, gm_mood)
|
||||
VALUES (?, ?, ?, 0, ?, ?, '[]', 50)`,
|
||||
run.RunID, run.UserID, string(zoneID), run.TotalRooms, string(seqJSON),
|
||||
VALUES (?, ?, ?, 0, ?, ?, '[]', ?)`,
|
||||
run.RunID, run.UserID, string(zoneID), run.TotalRooms, string(seqJSON), startMood,
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("insert zone run: %w", err)
|
||||
}
|
||||
@@ -271,7 +275,7 @@ func scanZoneRun(row scanner) (*DungeonRun, error) {
|
||||
if err := row.Scan(
|
||||
&r.RunID, &r.UserID, &zoneID, &r.CurrentRoom, &r.TotalRooms,
|
||||
&seqJSON, &clearedJSON, &bossDefeatedI, &abandonedI,
|
||||
&lootJSON, &r.GMMood, &r.StartedAt, &r.LastActionAt, &completedAtRaw,
|
||||
&lootJSON, &r.DMMood, &r.StartedAt, &r.LastActionAt, &completedAtRaw,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user