diff options
| author | historia <[not public]> | 2026-06-29 04:21:37 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-29 04:21:37 -0400 |
| commit | 0fe67cfd5def4ac3e919fd611fe5acc55ca2d253 (patch) | |
| tree | fbcdcdeb355bd6c9d3afab006f052a8b465f7feb /internal/game/render_map.go | |
| parent | 72dbe734015916f98020d6a617981956f0509e26 (diff) | |
| download | thehouseoficarus-0fe67cfd5def4ac3e919fd611fe5acc55ca2d253.tar.gz | |
better dialog color, edge cases on blocked map links fixed
Diffstat (limited to 'internal/game/render_map.go')
| -rw-r--r-- | internal/game/render_map.go | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/internal/game/render_map.go b/internal/game/render_map.go index 58e0613..8790a1e 100644 --- a/internal/game/render_map.go +++ b/internal/game/render_map.go @@ -42,6 +42,7 @@ type mapCell struct { type mapGraph struct { posToRoom map[[2]int]int roomToPos map[int][2]int + dist map[int]int } var bfsDirs = []struct { @@ -58,6 +59,7 @@ func buildGraph(g *Game, startRoomID int, visited map[int]bool) *mapGraph { mg := &mapGraph{ posToRoom: make(map[[2]int]int), roomToPos: make(map[int][2]int), + dist: make(map[int]int), } type node struct { @@ -67,6 +69,7 @@ func buildGraph(g *Game, startRoomID int, visited map[int]bool) *mapGraph { queue := []node{{startRoomID, 0, 0}} mg.posToRoom[[2]int{0, 0}] = startRoomID mg.roomToPos[startRoomID] = [2]int{0, 0} + mg.dist[startRoomID] = 0 for len(queue) > 0 { n := queue[0] @@ -92,6 +95,7 @@ func buildGraph(g *Game, startRoomID int, visited map[int]bool) *mapGraph { nx, ny := n.x+d.dx, n.y+d.dy mg.posToRoom[[2]int{nx, ny}] = targetID mg.roomToPos[targetID] = [2]int{nx, ny} + mg.dist[targetID] = mg.dist[n.roomID] + 1 queue = append(queue, node{targetID, nx, ny}) } } @@ -350,9 +354,16 @@ func (c *mapRenderCtx) nodeSpec(roomID int) color.ColorSpec { // the per-direction traversability of the two exits joining them. ok is false // when there is no link at all, so the caller draws nothing: // - both directions open -> bidirectional bar (- / |) -// - exactly one open -> arrow pointing along the open direction -// - >=1 exists but none open -> blocked 'X' -// - neither exit exists -> ok == false (no cell) +// - outward direction open -> arrow pointing outward +// - outward direction blocked -> blocked 'X' +// - only inward direction open -> arrow pointing inward +// - none traversable -> blocked 'X' +// - neither exit exists -> ok == false (no cell) +// +// "Outward" is the exit from the room nearer the player (smaller BFS distance) +// toward the farther one — i.e. the link as reached along the shortest path. +// Since each BFS hop is a unit grid step, grid-adjacent rooms always differ in +// distance parity, so there is never a tie to break. // // Bars and arrows use the normal link coloring (dim if an endpoint is unvisited, // otherwise the gradient average); only 'X' uses the blocked color. @@ -360,23 +371,32 @@ func (c *mapRenderCtx) connectorCell(roomA, roomB int, dirAB, dirBA world.ExitDi fwd := exitStateTo(c.g, c.sess, roomA, dirAB, roomB) // A -> B bwd := exitStateTo(c.g, c.sess, roomB, dirBA, roomA) // B -> A - if fwd == exitAbsent && bwd == exitAbsent { + switch { + case fwd == exitAbsent && bwd == exitAbsent: return mapCell{}, false + case fwd == exitOpen && bwd == exitOpen: + return c.coloredCell(roomA, roomB, barGlyph(c.mg, dirAB)) + } + + // Orient the link outward, from near room to far room. + outDir, inDir, out, in := dirAB, dirBA, fwd, bwd + if c.bg.dist[roomB] < c.bg.dist[roomA] { + outDir, inDir, out, in = dirBA, dirAB, bwd, fwd } - var glyph rune switch { - case fwd == exitOpen && bwd == exitOpen: - glyph = barGlyph(c.mg, dirAB) - case fwd == exitOpen: - glyph = arrowGlyph(c.mg, dirAB) - case bwd == exitOpen: - glyph = arrowGlyph(c.mg, dirBA) + case out == exitOpen: + return c.coloredCell(roomA, roomB, arrowGlyph(c.mg, outDir)) + case out == exitAbsent && in == exitOpen: + return c.coloredCell(roomA, roomB, arrowGlyph(c.mg, inDir)) default: - // At least one exit exists but none are currently traversable. return mapCell{char: 'X', spec: c.blockedSpec}, true } +} +// coloredCell applies the shared link coloring logic for bar/arrow glyphs +// (dim if either endpoint is unvisited, otherwise the gradient average). +func (c *mapRenderCtx) coloredCell(roomA, roomB int, glyph rune) (mapCell, bool) { if c.visited != nil && (!c.visited[roomA] || !c.visited[roomB]) { return mapCell{char: glyph, spec: c.dimSpec}, true } |
