aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_room_insert.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/cmd_room_insert.go')
-rw-r--r--internal/game/cmd_room_insert.go56
1 files changed, 13 insertions, 43 deletions
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
}