(define room-actions
(build-actions
;; desc == description
+ (init (wrap-apply room-init))
(wire-exits! (wrap-apply room-wire-exits!))
(cmd-go (wrap-apply room-cmd-go))
(cmd-go-where (wrap-apply room-cmd-go-where))
- (cmd-look-room (wrap-apply room-cmd-look-room))))
+ (look-room (wrap-apply room-look-room))
+ ;; in this case the command is the same version as the normal
+ ;; look-room version
+ (cmd-look-room (wrap-apply room-look-room))))
(define room-actions*
(append room-actions gameobj-actions))
;; @@: Can remove this indirection once things settle
#:init-value (wrap-apply room-action-dispatch)))
+(define (room-init room message)
+ (room-wire-exits! room))
-(define (room-wire-exits! room message)
+(define (room-wire-exits! room)
"Actually hook up the rooms' exit addresses to the rooms they
claim to point to."
(for-each
(lambda (exit)
(define new-exit
(message-ref
- (<-wait room (gameobj-gm room) 'lookup-room
+ (<-wait room (gameobj-gm room) 'lookup-special
#:symbol (slot-ref exit 'to-symbol))
'room-id))
(room-exits room)))
(cond
(exit
+ ;; Set the player's new location
(<-wait room (message-from message) 'set-loc!
#:loc (slot-ref exit 'to-address))
- (<- room (message-from message) 'look-room))
+ ;; Have the new room update the player to the new location
+ (<- room (slot-ref exit 'to-address) 'look-room
+ #:to-id (message-from message)))
(else
(<- room (message-from message) 'tell
#:text "You don't see any way to go there.\n"))))
(<- room (message-from message) 'tell
#:text "Go where?\n"))
-(define-mhandler (room-cmd-look-room room message)
- (<- room (message-from message) 'look-room))
+;;; look commands
+
+(define (list-words-as-string words)
+ "A little utility for listing a bunch of words in an English-style list"
+ ;; TODO: This could be made faster by traversing the O(n)
+ ;; list once, not twice
+ (let ((word-length (length words)))
+ (cond
+ ((eqv? word-length 0) "")
+ ((eqv? word-length 1) (car words))
+ (else
+ ;; TODO: and this is NOT efficient
+ (string-append
+ (string-join
+ (drop-right words 1)
+ ", ")
+ " and "
+ (last words))))))
+
+(define (room-player-looks-around room player-id)
+ "Handle looking around the room"
+ ;; Get the room text
+ (define room-text
+ (format #f "**~a**\n~a\n"
+ (slot-ref room 'name)
+ (slot-ref room 'desc)))
+
+ ;; Get a list of other things the player would see in the room
+ (define occupant-names-all
+ (map
+ (lambda (occupant)
+ (message-ref
+ (<-wait room occupant 'visible-name
+ #:whos-looking player-id)
+ 'text))
+ (remove
+ (lambda (x) (equal? x player-id))
+ (hash-map->list (lambda (x _) x)
+ (slot-ref room 'occupants)))))
+
+ ;; Strip out the #f responses (these aren't listed because they lack a name
+ ;; or they aren't "obviously visible" to the player)
+ (define occupant-names-filtered
+ (filter identity occupant-names-all))
+
+ (define occupant-names-string
+ (if (eq? occupant-names-filtered '())
+ #f
+ (format #f "You see here: ~a.\n"
+ (list-words-as-string occupant-names-filtered))))
+
+ (define final-text
+ (if occupant-names-string
+ (string-append room-text occupant-names-string)
+ room-text))
+
+ (<- room player-id 'tell
+ #:text final-text))
+
+
+(define-mhandler (room-look-room room message)
+ "Command: Player asks to look around the room"
+ (room-player-looks-around
+ room
+ ;; Either send it to the #:to-id of the message, or to the
+ ;; sender of the message
+ (message-ref message 'to-id
+ (message-from message))))