From 7d76673fa0707d204c7d084c8f90c8133c22a31a Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 29 Jun 2026 18:13:33 -0400 Subject: feat: migrated map (and bfs) to full 3D instead of individual 2D maps on different planes. --- internal/game/cmd_room_insert.go | 56 ++++++++++------------------------------ 1 file changed, 13 insertions(+), 43 deletions(-) (limited to 'internal/game/cmd_room_insert.go') diff --git a/internal/game/cmd_room_insert.go b/internal/game/cmd_room_insert.go index 4fbcd10..6164e50 100644 --- a/internal/game/cmd_room_insert.go +++ b/internal/game/cmd_room_insert.go @@ -65,12 +65,16 @@ func (g *Game) roomInsert(sess *net.Session, args []string) { oppositeDir := world.OppositeExit[dir] - if delta, isHorizontal := world.DirectionDeltas[dir]; isHorizontal { + if delta3D, ok := world.DirectionDeltas3D[dir]; ok { coord, roomAt := g.buildGridFrom(p.RoomID) - sSet := g.bfsComponent(targetID, p.RoomID) + sSet := g.bfsReachable(targetID, func(_ int, _ world.ExitDir, target int) bool { + return target == p.RoomID + }) - withoutEdge := g.bfsWithoutEdge(p.RoomID, dir, targetID) + withoutEdge := g.bfsReachable(p.RoomID, func(rid int, d world.ExitDir, target int) bool { + return rid == p.RoomID && d == dir && target == targetID + }) for rid := range sSet { if withoutEdge[rid] { room, _ := g.World.LoadRoom(rid) @@ -90,7 +94,7 @@ func (g *Game) roomInsert(sess *net.Session, args []string) { continue } oldPos := coord[rid] - newPos := [2]int{oldPos[0] + delta[0], oldPos[1] + delta[1]} + newPos := [3]int{oldPos[0] + delta3D[0], oldPos[1] + delta3D[1], oldPos[2] + delta3D[2]} if occupier, ok := roomAt[newPos]; ok && !sSet[occupier] { occRoom, _ := g.World.LoadRoom(occupier) occName := fmt.Sprintf("#%d", occupier) @@ -221,7 +225,10 @@ func (g *Game) roomInsert(sess *net.Session, args []string) { g.checkAggro(sess) } -func (g *Game) bfsComponent(startID, excludeID int) map[int]bool { +// bfsReachable returns the set of rooms reachable from startID over the room +// exit graph, restricted to known rooms. skipEdge, when non-nil, prunes an +// individual directed exit (the edge from rid via dir to target) from the walk. +func (g *Game) bfsReachable(startID int, skipEdge func(rid int, dir world.ExitDir, target int) bool) map[int]bool { roomIndex := g.World.RoomIndex() visited := map[int]bool{startID: true} queue := []int{startID} @@ -234,51 +241,14 @@ func (g *Game) bfsComponent(startID, excludeID int) map[int]bool { continue } for _, ed := range world.ExitOrder { - if ed == world.Up || ed == world.Down { - continue - } exit, ok := room.Exits[ed] if !ok || exit.Room <= 0 || !roomIndex[exit.Room] { continue } target := exit.Room - if target == excludeID { - continue - } - if visited[target] { + if skipEdge != nil && skipEdge(rid, ed, target) { continue } - visited[target] = true - queue = append(queue, target) - } - } - return visited -} - -func (g *Game) bfsWithoutEdge(fromID int, skipDir world.ExitDir, skipTo int) map[int]bool { - roomIndex := g.World.RoomIndex() - visited := map[int]bool{fromID: true} - queue := []int{fromID} - - for len(queue) > 0 { - rid := queue[0] - queue = queue[1:] - room, err := g.World.LoadRoom(rid) - if err != nil { - continue - } - for _, ed := range world.ExitOrder { - if ed == world.Up || ed == world.Down { - continue - } - exit, ok := room.Exits[ed] - if !ok || exit.Room <= 0 || !roomIndex[exit.Room] { - continue - } - if rid == fromID && ed == skipDir && exit.Room == skipTo { - continue - } - target := exit.Room if visited[target] { continue } -- cgit v1.2.3