go: port dungeon generation, items base, pack, and monster creation

rooms.c, passages.c, new_level.c ported in full: room/maze layout,
corridor spanning tree with extra connections, passage numbering flood
fill, trap/stairs/object placement, treasure rooms. Careful RNG-call
ordering throughout keeps generation seed-faithful to C.

Supporting subsystems this depends on, also ported:
- screen.go: curses replaced by in-memory Window cell buffers behind a
  Terminal interface (tcell arrives with the UI phase; tests run headless)
- io.go: msg/addmsg/endmsg message-line protocol, status line, step_ok
- pack.c in full (add_pack sorting/stacking walk, get_item, inventory)
- things.c in full (inv_name, new_thing, discovery lists, pagination)
- monsters.c in full; chase.c navigation half (roomin/cansee/see_monst/
  find_dest/runto/set_oldch); rings.c, armor.c in full
- weapons.c/sticks.c creation half (init_weapon, fix_stick, num)
- misc.c look() display update, eat, level-up, direction input
- daemons.c callbacks except stomach (needs death()) and the runners
  chase driver (combat phase)
- init.c init_player with the starting kit

Tests: level invariants across seeds, determinism, 30-depth sweep.
This commit is contained in:
2026-07-06 19:05:46 +02:00
parent 7fa2048402
commit a69ef7dc04
21 changed files with 3872 additions and 17 deletions

19
game/move.go Normal file
View File

@@ -0,0 +1,19 @@
package game
// move.c — hero movement. doorOpen arrives first (room entry needs it);
// the movement commands and traps come with the UI phase.
// doorOpen is called to wake up things in a room that might move when the
// hero enters (move.c door_open).
func (g *RogueGame) doorOpen(rp *Room) {
if rp.Flags.Has(IsGone) {
return
}
for y := rp.Pos.Y; y < rp.Pos.Y+rp.Max.Y; y++ {
for x := rp.Pos.X; x < rp.Pos.X+rp.Max.X; x++ {
if isUpper(g.Level.VisibleChar(y, x)) {
g.wakeMonster(y, x)
}
}
}
}