aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_map.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-29 04:21:37 -0400
committerhistoria <[not public]>2026-06-29 04:21:37 -0400
commit0fe67cfd5def4ac3e919fd611fe5acc55ca2d253 (patch)
treefbcdcdeb355bd6c9d3afab006f052a8b465f7feb /internal/game/render_map.go
parent72dbe734015916f98020d6a617981956f0509e26 (diff)
downloadthehouseoficarus-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.go44
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
}