diff options
Diffstat (limited to 'internal/game/look_room.go')
| -rw-r--r-- | internal/game/look_room.go | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/internal/game/look_room.go b/internal/game/look_room.go index 8bd85be..7fe527f 100644 --- a/internal/game/look_room.go +++ b/internal/game/look_room.go @@ -72,64 +72,81 @@ func (g *Game) resolveObjDesc(sess *net.Session, def *object.ObjectDef) (string, return "", false } -func (g *Game) showRoomExits(sess *net.Session, p *player.Player, room *world.Room) { - if len(room.Exits) > 0 { - sess.WriteLine("") - if p.OptionBool("exits") { - sess.WriteLine("Exits:") - type exitLine struct { - dir string - targetName string - } - var lines []exitLine - maxDirLen := 0 - for _, dir := range world.ExitOrder { - exitDef, ok := room.Exits[dir] - if !ok { - continue - } - if exitDef.Hidden && !g.exitDiscovered(p, room.ID, dir) { +// formatExitLines builds the verbose " dir - target [tags]" exit listing, +// applying hidden-exit filtering and blocked/HIDDEN tags via exitDisplayState. +// Shared by showRoomExits (the `look` exit section) and the standalone `exits` +// command so they always agree on what is listed and how it is tagged. +func (g *Game) formatExitLines(sess *net.Session, room *world.Room) []string { + type exitLine struct { + dir string + targetName string + } + var lines []exitLine + maxDirLen := 0 + for _, dir := range world.ExitOrder { + exitDef, ok := room.Exits[dir] + if !ok { + continue + } + ed := g.exitDisplayState(sess, room.ID, dir, exitDef) + if !ed.Visible { continue } coloredDir := g.colorize(sess, "exit_direction", string(dir)) - targetRoom, err := g.World.LoadRoom(exitDef.Room) - targetName := g.colorize(sess, "room_number", fmt.Sprintf("#%d", exitDef.Room)) - if err == nil { - targetName = g.colorize(sess, "exit_name", targetRoom.Name) - } - if exitDef.AlwaysBlocked { - targetName += " (impassable)" - } - if exitDef.Condition != nil && !g.checkCondition(sess, exitDef.Condition) { - targetName += " (blocked)" - } - if exitDef.Hidden { - targetName += " (HIDDEN)" - } - lines = append(lines, exitLine{coloredDir, targetName}) - if visibleLen(coloredDir) > maxDirLen { - maxDirLen = visibleLen(coloredDir) - } - } + targetRoom, err := g.World.LoadRoom(exitDef.Room) + targetName := g.colorize(sess, "room_number", fmt.Sprintf("#%d", exitDef.Room)) + if err == nil { + targetName = g.colorize(sess, "exit_name", targetRoom.Name) + } + if ed.Blocked { + targetName += " (blocked)" + } + if ed.TagHidden { + targetName += " (HIDDEN)" + } + lines = append(lines, exitLine{coloredDir, targetName}) + if visibleLen(coloredDir) > maxDirLen { + maxDirLen = visibleLen(coloredDir) + } + } + out := make([]string, len(lines)) + for i, l := range lines { + pad := maxDirLen + (len(l.dir) - visibleLen(l.dir)) + out[i] = fmt.Sprintf(" %-*s - %s", pad, l.dir, l.targetName) + } + return out +} + +func (g *Game) showRoomExits(sess *net.Session, p *player.Player, room *world.Room) { + if len(room.Exits) == 0 { + return + } + sess.WriteLine("") + if p.OptionBool("exits") { + lines := g.formatExitLines(sess, room) + if len(lines) > 0 { + sess.WriteLine("Exits:") for _, l := range lines { - pad := maxDirLen + (len(l.dir) - visibleLen(l.dir)) - sess.WriteLine(fmt.Sprintf(" %-*s - %s", pad, l.dir, l.targetName)) + sess.WriteLine(l) } - } else { - sess.Write("Exits: ") - first := true - for _, dir := range world.ExitOrder { - exitDef, ok := room.Exits[dir] - if !ok || (exitDef.Hidden && !g.exitDiscovered(p, room.ID, dir)) { - continue - } - if !first { - sess.Write(", ") - } - sess.Write(g.colorize(sess, "exit_direction", string(dir))) - first = false - } - sess.WriteLine("") } + return + } + sess.Write("Exits: ") + first := true + for _, dir := range world.ExitOrder { + exitDef, ok := room.Exits[dir] + if !ok { + continue + } + if !g.exitDisplayState(sess, room.ID, dir, exitDef).Visible { + continue + } + if !first { + sess.Write(", ") + } + sess.Write(g.colorize(sess, "exit_direction", string(dir))) + first = false } + sess.WriteLine("") } |
