diff options
| author | historia <[not public]> | 2026-06-11 20:41:06 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-11 20:41:06 -0400 |
| commit | d6ab0e93a64525ce34f89e26d5272efbac513c32 (patch) | |
| tree | d0ec59a72a32a15d0917d9c6c3bfa2f2a424c1f1 /internal/game/cmd_map.go | |
| parent | 6b2b4bf470b655f01c5a21c5f558a6102402c214 (diff) | |
| download | thehouseoficarus-d6ab0e93a64525ce34f89e26d5272efbac513c32.tar.gz | |
feat: big map and options changes
Diffstat (limited to 'internal/game/cmd_map.go')
| -rw-r--r-- | internal/game/cmd_map.go | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/internal/game/cmd_map.go b/internal/game/cmd_map.go new file mode 100644 index 0000000..7c506f9 --- /dev/null +++ b/internal/game/cmd_map.go @@ -0,0 +1,140 @@ +package game + +import ( + "strings" + + "thirdcollapse/internal/net" + "thirdcollapse/internal/player" + "thirdcollapse/internal/world" +) + +func (g *Game) doMap(sess *net.Session) { + p := sess.Player.(*player.Player) + mapWidth := p.OptionInt("mapwidth") + mapHeight := p.OptionInt("mapheight") + if mapWidth < 5 { + mapWidth = 5 + } + if mapHeight < 5 { + mapHeight = 5 + } + + lines := buildFullMap(g, p.RoomID, mapWidth, mapHeight) + + mode := p.OptionString("mappadding") + if mode == "none" || mode == "x" { + lines = stripBlankRows(lines) + } + if mode == "none" || mode == "y" { + lines = leftTrimCommon(lines) + } + + if len(lines) == 0 { + sess.WriteLine("\nNo map data to display.") + return + } + sess.WriteLine("") + for _, line := range lines { + sess.WriteLine(line) + } +} + +func stripBlankRows(lines []string) []string { + var out []string + for _, line := range lines { + if strings.TrimSpace(line) != "" { + out = append(out, line) + } + } + return out +} + +func leftTrimCommon(lines []string) []string { + min := -1 + for _, line := range lines { + if strings.TrimSpace(line) == "" { + continue + } + n := 0 + for _, r := range line { + if r == ' ' { + n++ + } else { + break + } + } + if min < 0 || n < min { + min = n + } + } + if min <= 0 { + return lines + } + result := make([]string, len(lines)) + for i, line := range lines { + if len(line) <= min { + result[i] = "" + } else { + result[i] = line[min:] + } + } + return result +} + +func buildFullMap(g *Game, roomID, mapWidth, mapHeight int) []string { + mg := buildGraph(g, roomID) + + grid := make([][]rune, mapHeight) + for i := range grid { + grid[i] = make([]rune, mapWidth) + for j := range grid[i] { + grid[i][j] = ' ' + } + } + + cx := mapWidth / 2 + cy := mapHeight / 2 + + for pos, rid := range mg.posToRoom { + gr := cy + pos[1]*2 + gc := cx + pos[0]*2 + if gr < 0 || gr >= mapHeight || gc < 0 || gc >= mapWidth { + continue + } + if rid == roomID { + grid[gr][gc] = '@' + } else { + grid[gr][gc] = roomMapSymbol(g, rid) + } + } + + for pos, rid := range mg.posToRoom { + x, y := pos[0], pos[1] + + if rightID, ok := mg.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] = '─' + } + } + } + + if bottomID, ok := mg.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] = '│' + } + } + } + } + + lines := make([]string, mapHeight) + for i := range grid { + lines[i] = string(grid[i]) + } + return lines +} |
