X-Git-Url: https://jxself.org/git/?p=mudsync.git;a=blobdiff_plain;f=mudsync%2Froom.scm;h=8f1e0a330d9ab2323ba495b9ac2b0185f5111eb6;hp=0ad886ceece07226a1dd508154c91c619535e4a1;hb=1c10b6fdd8662522b6a2103f7ad59c588acfa2dc;hpb=754bd427883ab189433fad90293e05d9aced2f70 diff --git a/mudsync/room.scm b/mudsync/room.scm index 0ad886c..8f1e0a3 100644 --- a/mudsync/room.scm +++ b/mudsync/room.scm @@ -19,6 +19,7 @@ (define-module (mudsync room) #:use-module (mudsync command) #:use-module (mudsync gameobj) + #:use-module (mudsync utils) #:use-module (8sync actors) #:use-module (8sync agenda) #:use-module (oop goops) @@ -46,28 +47,19 @@ (traverse-check #:init-value (const #t) #:init-keyword #:traverse-check)) -(define* (exit-can-traverse? exit actor - #:optional (target-actor (actor-id actor))) - ((slot-ref exit 'traverse-check) exit actor target-actor)) +;; @@: Should we make whos-exiting optional? Would there ever be any +;; reason? +(define* (exit-can-traverse? exit room whos-exiting) + ((slot-ref exit 'traverse-check) exit room whos-exiting)) -(define* (exit-is-visible? exit actor - #:optional (target-actor (actor-id actor))) - ((slot-ref exit 'traverse-check) exit actor target-actor)) +(define* (exit-is-visible? exit room whos-exiting) + ((slot-ref exit 'visible-check) exit room whos-exiting)) ;;; Rooms ;;; ===== -(define %room-contain-commands - (list - (loose-direct-command "look" 'cmd-look-at) - (empty-command "look" 'cmd-look-room) - (empty-command "go" 'cmd-go-where) - (loose-direct-command "go" 'cmd-go) - (greedy-command "say" 'cmd-say) - (greedy-command "emote" 'cmd-emote))) - ;; TODO: Subclass from container? (define-class () ;; A list of @@ -75,11 +67,24 @@ #:init-keyword #:exits #:getter room-exits) - (container-commands - #:init-value (wrap %room-contain-commands)) + (container-dom-commands + #:allocation #:each-subclass + #:init-thunk + (build-commands + (("l" "look") ((empty-command cmd-look-room))) + ("go" ((empty-command cmd-go-where) + (loose-direct-command cmd-go))) + (("say" "\"" "'") ((greedy-command cmd-say))) + (("emote" "/me") ((greedy-command cmd-emote))))) + + (container-sub-commands + #:allocation #:each-subclass + #:init-thunk + (build-commands + (("l" "look") ((loose-direct-command cmd-look-at-from-room))))) (actions #:allocation #:each-subclass - #:init-value + #:init-thunk (build-actions (cmd-go room-cmd-go) (cmd-go-where room-cmd-go-where) @@ -89,7 +94,7 @@ ;; in this case the command is the same version as the normal ;; look-room version (cmd-look-room room-look-room) - (cmd-look-at room-look-at) + (cmd-look-at-from-room room-look-dont-see-it) (cmd-say room-cmd-say) (cmd-emote room-cmd-emote)))) @@ -104,25 +109,45 @@ ;; in case it's a special (dyn-ref room (slot-ref exit 'to)) #f)) + (define player (message-from message)) (define player-name - (msg-val (<-wait (message-from message) 'get-name))) + (mbody-val (<-wait player 'get-name))) (cond (exit - ;; Set the player's new location - (<-wait (message-from message) 'set-loc! - #:loc to-address) - ;; Tell everyone else the person walked away - (room-tell-room - room - (format #f "~a wanders ~a.\n" - player-name direct-obj)) - (<- to-address 'announce-entrance - #:who-entered (message-from message)) - ;; Have the new room update the player to the new location - (<- to-address 'look-room - #:to-id (message-from message))) + (call-with-values (lambda () + (exit-can-traverse? exit room player)) + (lambda* (can-traverse? #:optional player-flavortext + room-flavortext) + (if can-traverse? + ;; looks like we can go, so let's go! + (begin + ;; Set the player's new location + (<-wait player 'set-loc! + #:loc to-address) + (when player-flavortext + (<-wait player 'tell + #:text player-flavortext)) + ;; Tell everyone else the person walked away + (room-tell-room + room (or room-flavortext + (format #f "~a wanders ~a.\n" + player-name direct-obj))) + (<- to-address 'announce-entrance + #:who-entered player) + ;; Have the new room update the player to the new location + (<- to-address 'look-room + #:to-id player)) + ;; Otherwise, if we can't go... + (begin + (<- player 'tell + #:text (or player-flavortext + `("You try to go " ,direct-obj " but something " + "seems to block you."))) + (when room-flavortext + (room-tell-room room room-flavortext + #:exclude player))))))) (else - (<- (message-from message) 'tell + (<- player 'tell #:text "You don't see any way to go there.\n")))) (define (room-cmd-go-where room message) @@ -131,30 +156,12 @@ ;;; 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))) + `((strong "=> " ,(slot-ref room 'name) " <=") + (p ,(slot-ref room 'desc)))) ;; Get a list of other things the player would see in the room (define occupant-names-all @@ -178,11 +185,13 @@ (if (eq? occupant-names-filtered '()) #f (format #f "You see here: ~a.\n" - (list-words-as-string occupant-names-filtered)))) + (string-join occupant-names-filtered + ", ")))) (define final-text (if occupant-names-string - (string-append room-text occupant-names-string) + `(,@room-text + (p (em ,occupant-names-string))) room-text)) (<- player-id 'tell @@ -190,9 +199,9 @@ (define* (room-look-room room message - ;; Either send it to the #:to-id of the message, - ;; or to the sender of the message - #:key (to-id (message-from message))) + ;; Either send it to the #:to-id of the message, + ;; or to the sender of the message + #:key (to-id (message-from message))) "Command: Player asks to look around the room" (room-player-looks-around room to-id)) @@ -202,35 +211,17 @@ (lambda (return) (for-each (lambda (occupant) - (msg-receive (_ #:key goes-by) - (<-wait occupant 'goes-by) - (if (member called-this goes-by) - (return occupant)))) + (define goes-by (mbody-val (<-wait occupant 'goes-by))) + (if (ci-member called-this goes-by) + (return occupant))) (hash-map->list (lambda (key val) key) (slot-ref room 'occupants))) #f))) -(define %formless-desc - "You don't see anything special.") - -(define* (room-look-at room message #:key direct-obj) - "Look at a specific object in the room." - (define matching-object - (room-find-thing-called room direct-obj)) - - (cond - (matching-object - (let ((obj-desc - (msg-val (<-wait matching-object 'get-desc - #:whos-looking (message-from message))))) - (if obj-desc - (<- (message-from message) 'tell - #:text (string-append obj-desc "\n")) - (<- (message-from message) 'tell - #:text (string-append %formless-desc "\n"))))) - (else - (<- (message-from message) 'tell - #:text "You don't see that here, so you can't look at it.\n")))) +(define* (room-look-dont-see-it room message #:key direct-obj) + "In general, if we get to this point, we didn't find something to look at." + (<- (message-from message) 'tell + #:text "You don't see that here, so you can't look at it.\n")) (define* (room-tell-room room text #:key exclude wait) @@ -255,22 +246,22 @@ (define* (room-cmd-say room message #:key phrase) "Command: Say something to room participants." (define player-name - (msg-val (<-wait (message-from message) 'get-name))) + (mbody-val (<-wait (message-from message) 'get-name))) (define message-to-send - (format #f "~a says: ~a\n" player-name phrase)) + `((b "<" ,player-name ">") " " ,phrase)) (room-tell-room room message-to-send)) (define* (room-cmd-emote room message #:key phrase) "Command: Say something to room participants." (define player-name - (msg-val (<-wait (message-from message) 'get-name))) + (mbody-val (<-wait (message-from message) 'get-name))) (define message-to-send - (format #f "* ~a ~a\n" player-name phrase)) + `((b "* " ,player-name) " " ,phrase)) (room-tell-room room message-to-send)) (define* (room-announce-entrance room message #:key who-entered) (define player-name - (msg-val (<-wait who-entered 'get-name))) + (mbody-val (<-wait who-entered 'get-name))) (define message-to-send (format #f "~a enters the room.\n" player-name)) (room-tell-room room message-to-send