diff options
| author | historia <[not public]> | 2026-06-27 17:26:23 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-27 17:26:23 -0400 |
| commit | 83f8f5447ec3baf85314ce7343f0e339d28bcc15 (patch) | |
| tree | bf01d0da4eb7b72e0fd410a74fc0ed6d2bc42232 /internal | |
| parent | 988b006a5bb9edb6465653566e7bdf8175347b8c (diff) | |
| download | thehouseoficarus-83f8f5447ec3baf85314ce7343f0e339d28bcc15.tar.gz | |
refactor: removed some redundant new map code
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/color/color.go | 3 | ||||
| -rw-r--r-- | internal/game/cmd_symbol.go | 4 | ||||
| -rw-r--r-- | internal/game/map_test.go | 3 | ||||
| -rw-r--r-- | internal/game/render_map.go | 77 | ||||
| -rw-r--r-- | internal/world/room.go | 44 |
5 files changed, 57 insertions, 74 deletions
diff --git a/internal/color/color.go b/internal/color/color.go index 13fca69..e971382 100644 --- a/internal/color/color.go +++ b/internal/color/color.go @@ -298,9 +298,6 @@ func Parse(input string) ColorSpec { // parseColorIndex parses a 1-2 digit hexadecimal color index (00-FF, case // insensitive) into its 0-255 value. Out-of-range or non-hex input fails. func parseColorIndex(s string) (int, bool) { - if s == "" { - return 0, false - } n, err := strconv.ParseUint(s, 16, 0) if err != nil || n > 255 { return 0, false diff --git a/internal/game/cmd_symbol.go b/internal/game/cmd_symbol.go index 0c3014b..b18f3f7 100644 --- a/internal/game/cmd_symbol.go +++ b/internal/game/cmd_symbol.go @@ -28,7 +28,7 @@ func (g *Game) executeSymbol(sess *net.Session, args []string, rawInput string) return } - // ponytail: extract symbol char from rawInput to preserve case, since + // extract symbol char from rawInput to preserve case, since // handleGameCommand lowercases args before dispatch (same pattern as say). char := args[0] if idx := strings.Index(strings.ToLower(rawInput), "symbol"); idx >= 0 { @@ -54,7 +54,7 @@ func (g *Game) executeSymbol(sess *net.Session, args []string, rawInput string) if !cleared { r, size := utf8.DecodeRuneInString(char) if size == 0 || size != len(char) || r == utf8.RuneError { - // ponytail: color-only mode — args are a color spec, keep existing char + // color-only mode — args are a color spec, keep existing char colorSpec := strings.Join(args, " ") spec := color.Parse(colorSpec) if spec.Empty() { diff --git a/internal/game/map_test.go b/internal/game/map_test.go index 05e70d0..4869d38 100644 --- a/internal/game/map_test.go +++ b/internal/game/map_test.go @@ -25,7 +25,6 @@ func writeTempRoom(t *testing.T, dir string, id int, body string) { } } - // TestMapConnectorGlyphs verifies the directional link rendering: bidirectional // links draw a bar, one-way (or one-side-blocked) links draw a directional // arrow, and links with no traversable direction draw a blocked 'X'. @@ -105,8 +104,6 @@ func TestMapConnectorGlyphs(t *testing.T) { } } - - func TestBuildTinyMap(t *testing.T) { g := &Game{ Deps: Deps{World: world.New("../../data")}, diff --git a/internal/game/render_map.go b/internal/game/render_map.go index 049db06..ff9ffa5 100644 --- a/internal/game/render_map.go +++ b/internal/game/render_map.go @@ -174,8 +174,8 @@ func buildTinyMap(g *Game, sess *net.Session, roomID int, mg mapGlyphs) []string if !leftOK || !rightOK { continue } - if exitsConnect(g, leftRoom, rightRoom, world.East, world.West) { - grid[(y+1)*2][(x+1)*2+1] = ctx.connectorCell(leftRoom, rightRoom, world.East, world.West) + if cell, ok := ctx.connectorCell(leftRoom, rightRoom, world.East, world.West); ok { + grid[(y+1)*2][(x+1)*2+1] = cell } } } @@ -189,8 +189,8 @@ func buildTinyMap(g *Game, sess *net.Session, roomID int, mg mapGlyphs) []string if !topOK || !bottomOK { continue } - if exitsConnect(g, topRoom, bottomRoom, world.South, world.North) { - grid[(y+1)*2+1][(x+1)*2] = ctx.connectorCell(topRoom, bottomRoom, world.South, world.North) + if cell, ok := ctx.connectorCell(topRoom, bottomRoom, world.South, world.North); ok { + grid[(y+1)*2+1][(x+1)*2] = cell } } } @@ -260,22 +260,22 @@ func buildFullMap(g *Game, sess *net.Session, roomID, mapWidth, mapHeight int, m for pos, rid := range bg.posToRoom { x, y := pos[0], pos[1] - if rightID, ok := bg.posToRoom[[2]int{x + 1, y}]; ok { - if exitsConnect(g, rid, rightID, world.East, world.West) { - gr := cy + y*2 - gc := cx + x*2 + 1 - if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth { - grid[gr][gc] = ctx.connectorCell(rid, rightID, world.East, world.West) + if rightID, exists := bg.posToRoom[[2]int{x + 1, y}]; exists { + gr := cy + y*2 + gc := cx + x*2 + 1 + if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth { + if cell, ok := ctx.connectorCell(rid, rightID, world.East, world.West); ok { + grid[gr][gc] = cell } } } - if bottomID, ok := bg.posToRoom[[2]int{x, y + 1}]; ok { - if exitsConnect(g, rid, bottomID, world.South, world.North) { - gr := cy + y*2 + 1 - gc := cx + x*2 - if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth { - grid[gr][gc] = ctx.connectorCell(rid, bottomID, world.South, world.North) + if bottomID, exists := bg.posToRoom[[2]int{x, y + 1}]; exists { + gr := cy + y*2 + 1 + gc := cx + x*2 + if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth { + if cell, ok := ctx.connectorCell(rid, bottomID, world.South, world.North); ok { + grid[gr][gc] = cell } } } @@ -302,7 +302,7 @@ func resolveMapAt(g *Game, sess *net.Session) color.ColorSpec { if sess != nil { return g.resolveColor(sess, "map_at") } - return color.NoColor() + return color.Parse("0F") } func resolveDim(g *Game, sess *net.Session) color.ColorSpec { @@ -347,17 +347,23 @@ func (c *mapRenderCtx) nodeSpec(roomID int) color.ColorSpec { } // connectorCell builds the link cell between two grid-adjacent rooms based on -// the per-direction traversability of the two exits joining them: -// - both directions open -> bidirectional bar (- / |) -// - exactly one open -> arrow pointing along the open direction -// - neither open (>=1 blocked) -> blocked 'X' +// 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) // // Bars and arrows use the normal link coloring (dim if an endpoint is unvisited, // otherwise the gradient average); only 'X' uses the blocked color. -func (c *mapRenderCtx) connectorCell(roomA, roomB int, dirAB, dirBA world.ExitDir) mapCell { +func (c *mapRenderCtx) connectorCell(roomA, roomB int, dirAB, dirBA world.ExitDir) (mapCell, bool) { 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 { + return mapCell{}, false + } + var glyph rune switch { case fwd == exitOpen && bwd == exitOpen: @@ -367,15 +373,14 @@ func (c *mapRenderCtx) connectorCell(roomA, roomB int, dirAB, dirBA world.ExitDi case bwd == exitOpen: glyph = arrowGlyph(c.mg, dirBA) default: - // The caller only draws a connector when at least one exit exists, so - // reaching here means every existing direction is blocked. - return mapCell{char: 'X', spec: c.blockedSpec} + // At least one exit exists but none are currently traversable. + return mapCell{char: 'X', spec: c.blockedSpec}, true } if c.visited != nil && (!c.visited[roomA] || !c.visited[roomB]) { - return mapCell{char: glyph, spec: c.dimSpec} + return mapCell{char: glyph, spec: c.dimSpec}, true } - return mapCell{char: glyph, spec: color.Average(c.nodeSpec(roomA), c.nodeSpec(roomB))} + return mapCell{char: glyph, spec: color.Average(c.nodeSpec(roomA), c.nodeSpec(roomB))}, true } type exitState int @@ -451,7 +456,7 @@ func roomMapSymbol(g *Game, sess *net.Session, roomID int, unvisited bool) (rune if data.Color != "" { spec = color.Parse(data.Color) } - // ponytail: non-ASCII custom symbols fall back to 'o' + // non-ASCII custom symbols fall back to 'o' // when unicode mode is off, but preserve the color. if !sess.Player.OptionBool("unicode") && r > 127 { return 'o', spec @@ -470,22 +475,6 @@ func roomMapSymbol(g *Game, sess *net.Session, roomID int, unvisited bool) (rune return '■', roomSpec } -func exitsConnect(g *Game, room1, room2 int, dir12, dir21 world.ExitDir) bool { - r1, ok := loadRoom(g, room1) - if !ok { - return false - } - if id, ok := exitTarget(r1, dir12); ok && id == room2 { - return true - } - r2, ok := loadRoom(g, room2) - if !ok { - return false - } - id, ok := exitTarget(r2, dir21) - return ok && id == room1 -} - func exitTarget(room *world.Room, dir world.ExitDir) (int, bool) { if room == nil { return 0, false diff --git a/internal/world/room.go b/internal/world/room.go index d542bf4..8f13b82 100644 --- a/internal/world/room.go +++ b/internal/world/room.go @@ -66,15 +66,15 @@ func (e *ExitDef) UnmarshalYAML(value *yaml.Node) error { } type Room struct { - ID int `yaml:"id"` - Name string `yaml:"name"` - Color string `yaml:"color"` - Description behavior.DescList `yaml:"description"` - Exits map[ExitDir]ExitDef `yaml:"exits"` - Objects []RoomObject `yaml:"objects"` - ItemSpawns []SpawnDef `yaml:"item_spawns"` - Mobs []RoomMob `yaml:"mobs"` - OnEnter []EnterStep `yaml:"on_enter"` + ID int `yaml:"id"` + Name string `yaml:"name"` + Color string `yaml:"color"` + Description behavior.DescList `yaml:"description"` + Exits map[ExitDir]ExitDef `yaml:"exits"` + Objects []RoomObject `yaml:"objects"` + ItemSpawns []SpawnDef `yaml:"item_spawns"` + Mobs []RoomMob `yaml:"mobs"` + OnEnter []EnterStep `yaml:"on_enter"` Hazard string `yaml:"hazard"` BlockTransport bool `yaml:"block_transport"` Triggers []TriggerDef `yaml:"triggers"` @@ -100,19 +100,19 @@ func (rm *RoomMob) UnmarshalYAML(value *yaml.Node) error { } type EnterStep struct { - Message string `yaml:"message"` - Condition *behavior.Condition `yaml:"condition"` - Delay int `yaml:"delay"` - SetFlags map[string]any `yaml:"set_flags"` - SetPlayerFlags map[string]any `yaml:"set_player_flags"` - Broadcast string `yaml:"broadcast"` - BroadcastGlobal string `yaml:"broadcast_global"` - SpawnMob *SpawnMobConfig `yaml:"spawn_mob"` - DespawnMob string `yaml:"despawn_mob"` - GiveItem string `yaml:"give_item"` - TakeItem string `yaml:"take_item"` - Teleport int `yaml:"teleport"` - Heal int `yaml:"heal"` + Message string `yaml:"message"` + Condition *behavior.Condition `yaml:"condition"` + Delay int `yaml:"delay"` + SetFlags map[string]any `yaml:"set_flags"` + SetPlayerFlags map[string]any `yaml:"set_player_flags"` + Broadcast string `yaml:"broadcast"` + BroadcastGlobal string `yaml:"broadcast_global"` + SpawnMob *SpawnMobConfig `yaml:"spawn_mob"` + DespawnMob string `yaml:"despawn_mob"` + GiveItem string `yaml:"give_item"` + TakeItem string `yaml:"take_item"` + Teleport int `yaml:"teleport"` + Heal int `yaml:"heal"` } // IsTimed reports whether the step carries enter-sequence semantics (any |
