mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Adv 2.0 D&D Phase 11 D1e: zone combat + trap + boss resolution
Wires real combat into !zone advance. Each room now resolves through
its own path: Entry is pure flavor, Exploration spawns a SpawnWeight-
biased non-elite from the zone roster, Elite filters to elite-flagged
entries, Trap nicks 8–20% MaxHP scaled by tier (KO-protected), Boss
runs the bestiary entry from zone.Boss with the zone Loot table on
victory. Combat reuses the existing dungeonCombatPhases pipeline with
the player's full D&D layer (class/race/subclass passives, equipment,
HP scaling, armed abilities, pending casts) and persists HP, subclass
state, and CR-weighted XP after each kill.
Mood event triggers fold in: nat-20s/nat-1s scanned from CombatResult
events apply +3/-2 deltas, player_death applies -5 + abandons the run,
zone_complete (already wired in D1d) lands when the boss falls. Loot
drops materialize into adventure_inventory with coin patterns
("coins_2d10x5") expanded into rolled gold-pouch treasure rows and
named items rendered as tier-scaled placeholder treasure (real
equipment-registry wiring is a later content phase).
Updates the D1d mood-on-completion test to drive the persistence layer
directly, since real combat against the L1 Goblin Warrens roster is
non-deterministic.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -168,24 +168,28 @@ func TestZoneCmd_AdvanceFinalRoomBumpsMood(t *testing.T) {
|
||||
zoneCmdTestCharacter(t, uid, 1)
|
||||
defer cleanupZoneRuns(uid)
|
||||
|
||||
p := &AdventurePlugin{}
|
||||
if err := p.handleDnDZoneCmd(MessageContext{Sender: uid}, "enter goblin_warrens"); err != nil {
|
||||
// D1e wired real combat into !zone advance, so the cmd-level path
|
||||
// is no longer deterministic for an L1 fighter against the Goblin
|
||||
// Warrens roster. Drive the persistence layer directly to assert
|
||||
// the mood-on-completion contract.
|
||||
run, err := startZoneRun(uid, ZoneGoblinWarrens, 1, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
run, _ := getActiveZoneRun(uid)
|
||||
// Advance through every room. zone_complete fires on the boss-room
|
||||
// advance and bumps mood by +10 (50 → 60).
|
||||
for i := 0; i < run.TotalRooms; i++ {
|
||||
if err := p.handleDnDZoneCmd(MessageContext{Sender: uid}, "advance"); err != nil {
|
||||
t.Fatalf("advance %d: %v", i, err)
|
||||
if _, err := markRoomCleared(run.RunID); err != nil {
|
||||
t.Fatalf("markRoomCleared %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
if _, err := applyMoodEvent(run.RunID, MoodEventZoneComplete); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
final, err := getZoneRun(run.RunID)
|
||||
if err != nil || final == nil {
|
||||
t.Fatal("could not fetch completed run")
|
||||
}
|
||||
if !final.BossDefeated {
|
||||
t.Error("boss should be defeated after final advance")
|
||||
t.Error("boss should be defeated after final markRoomCleared")
|
||||
}
|
||||
if final.GMMood != 60 {
|
||||
t.Errorf("post-completion mood = %d, want 60 (50 + zone_complete +10)", final.GMMood)
|
||||
|
||||
Reference in New Issue
Block a user