๐Ÿ“ฆ sleepyfran / duets

๐Ÿ“„ RoomInfo.fs ยท 106 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106[<AutoOpen>]
module Duets.Cli.Components.RoomInfo

open Duets.Agents
open Duets.Cli.Text
open Duets.Cli.Text.World
open Duets.Entities
open Duets.Simulation

/// Lists all entrances to other places from the current room.
let private listEntrances (interactions: InteractionWithMetadata list) =
    let entrances =
        interactions
        |> List.choose (fun interaction ->
            match interaction.Interaction with
            | Interaction.FreeRoam(FreeRoamInteraction.Enter(place)) ->
                Some(place)
            | _ -> None)
        |> List.concat

    match entrances with
    | [] -> None
    | entrances ->
        let entrancesDescription =
            Generic.listOf entrances World.placeNameWithType

        Some(
            $"""There {Generic.pluralOf "is an entrance" "are entrances" entrancesDescription.Length} towards {entrancesDescription}."""
        )
    |> Option.iter showMessage

/// Lists all exits leading to streets from the current room.
let private listExits (interactions: InteractionWithMetadata list) =
    let state = State.get ()

    let exits =
        interactions
        |> List.choose (fun interaction ->
            match interaction.Interaction with
            | Interaction.FreeRoam(FreeRoamInteraction.GoOut(streetId)) ->
                Some(streetId)
            | _ -> None)

    match exits with
    | [] -> None
    | exits ->
        let exitsDescription =
            Generic.listOf exits (fun streetId ->
                let street = Queries.World.streetInCurrentCity streetId state

                $"{street.Name |> Styles.place}")

        Some(
            $"""There is an exit towards {exitsDescription} leading out of this place."""
        )
    |> Option.iter showMessage

/// Gets the list of connected streets from the interactions.
let private getConnectedStreets (interactions: InteractionWithMetadata list) =
    let connectedStreets =
        interactions
        |> List.choose (fun interaction ->
            match interaction.Interaction with
            | Interaction.FreeRoam(FreeRoamInteraction.GoToStreet(streets)) ->
                Some(streets)
            | _ -> None)
        |> List.concat

    match connectedStreets with
    | [] -> None
    | exits ->
        Generic.listOf exits (fun street -> $"{street.Name |> Styles.place}")
        |> Some

/// Lists all room connections (directions to other rooms) from the current room.
let private listRoomConnections (interactions: InteractionWithMetadata list) =
    let state = State.get ()
    let cityId, placeId, _ = state |> Queries.World.currentCoordinates
    let place = Queries.World.placeInCityById cityId placeId

    let connections =
        interactions
        |> List.choose (fun interaction ->
            match interaction.Interaction with
            | Interaction.FreeRoam(FreeRoamInteraction.Move(direction, roomId)) ->
                let roomType = Queries.World.roomById cityId placeId roomId

                Some(direction, roomType)
            | _ -> None)

    let connectedStreetListOpt = getConnectedStreets interactions

    match connections with
    | [] -> World.noConnectionsToRoom place connectedStreetListOpt
    | connections ->
        World.connectingNodes place connections connectedStreetListOpt
    |> showMessage

/// Displays information about the current room including connections, entrances,
/// exits, people, and items. This is used both when entering a room and when
/// using the look command.
let showRoomInfo (interactions: InteractionWithMetadata list) =
    listRoomConnections interactions
    listEntrances interactions
    listExits interactions