From 582ae7c4ffaddad629c53750b80c807745489b37 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Thu, 5 May 2016 14:35:45 -0500 Subject: [PATCH] See objects in the same room as you --- mudsync/game-master.scm | 2 +- mudsync/gameobj.scm | 34 +++++++++++++++++++++++++-- mudsync/room.scm | 51 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/mudsync/game-master.scm b/mudsync/game-master.scm index aab0b7a..34476b0 100644 --- a/mudsync/game-master.scm +++ b/mudsync/game-master.scm @@ -190,7 +190,7 @@ with an anonymous persona" ;; create and register the player (player (create-actor* gm (@@ (mudsync player) ) "player" - #:username guest-name + #:name guest-name #:gm (actor-id gm) #:client client-id))) (display "Are we broke yet?\n") diff --git a/mudsync/gameobj.scm b/mudsync/gameobj.scm index 1d12007..8278769 100644 --- a/mudsync/gameobj.scm +++ b/mudsync/gameobj.scm @@ -52,7 +52,8 @@ (set-loc! (wrap-apply gameobj-set-loc!)) (get-name (wrap-apply gameobj-get-name)) (get-desc (wrap-apply gameobj-get-desc)) - (goes-by (wrap-apply gameobj-goes-by)))) + (goes-by (wrap-apply gameobj-goes-by)) + (visible-name (wrap-apply gameobj-visible-name)))) ;;; *all* game components that talk to players should somehow ;;; derive from this class. @@ -91,7 +92,14 @@ (container-commands #:init-value '()) (message-handler #:init-value - (simple-dispatcher gameobj-actions))) + (simple-dispatcher gameobj-actions)) + + ;; Most objects are generally visible by default + (generally-visible #:init-value #t) + ;; @@: Would be preferable to be using generic methods for this... + ;; Hopefully we can port this to Guile 2.2 soon... + (visible-to-player? + #:init-value (wrap-apply gameobj-visible-to-player?))) ;;; gameobj message handlers @@ -186,3 +194,25 @@ (define (gameobj-simple-name-f gameobj) "Simplest version: return ourselves for our name." (gameobj-name gameobj)) + +(define (gameobj-visible-to-player? gameobj whos-looking) + "Check to see whether we're visible to the player or not. +By default, this is whether or not the generally-visible flag is set." + (slot-ref gameobj 'generally-visible)) + +(define-mhandler (gameobj-visible-name actor message whos-looking) + ;; Are we visible? + (define we-are-visible + ((slot-ref actor 'visible-to-player?) actor whos-looking)) + + (define name-to-return + (if we-are-visible + ;; Return our name + (match (slot-ref actor 'name) + ((? procedure? name-proc) + (name-proc actor whos-looking)) + ((? string? name) + name) + (#f #f)) + #f)) + (<-reply actor message #:text name-to-return)) diff --git a/mudsync/room.scm b/mudsync/room.scm index aee0636..efc2a38 100644 --- a/mudsync/room.scm +++ b/mudsync/room.scm @@ -147,14 +147,63 @@ claim to point to." ;;; 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 room-text)) + #:text final-text)) + (define-mhandler (room-look-room room message) "Command: Player asks to look around the room" -- 2.31.1