distinguish container-sub-commands and container-dom-commands
[mudsync.git] / mudsync / player.scm
index 844aaf96f031fbf4112a05b602a3bd5e0f4e5813..78d9a01574efbed2f113f8e9f18fbd1d1e53cf63 100644 (file)
   #:use-module (mudsync gameobj)
   #:use-module (mudsync game-master)
   #:use-module (mudsync parser)
-  #:use-module (8sync systems actors)
+  #:use-module (8sync actors)
   #:use-module (8sync agenda)
+  #:use-module (8sync rmeta-slot)
   #:use-module (ice-9 control)
   #:use-module (ice-9 format)
   #:use-module (ice-9 match)
   #:use-module (oop goops)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-9)
-  #:export (<player>
-            player-self-commands))
+  #:export (<player>))
 
 ;;; Players
 ;;; =======
 
-(define player-actions
-  (build-actions
-   (init (wrap-apply player-init))
-   (handle-input (wrap-apply player-handle-input))
-   (tell (wrap-apply player-tell))
-   (disconnect-self-destruct (wrap-apply player-disconnect-self-destruct))
-   (cmd-inventory (wrap-apply player-cmd-inventory))))
-
-(define player-actions*
-  (append player-actions
-          gameobj-actions))
-
-(define player-dispatcher
-  (simple-dispatcher player-actions*))
-
-(define player-self-commands
-  (list
-   (empty-command "inventory" 'cmd-inventory)
-   ;; aliases...
-   ;; @@: Should use an "alias" system for common aliases?
-   (empty-command "inv" 'cmd-inventory)
-   (empty-command "i" 'cmd-inventory)))
-
 (define-class <player> (<gameobj>)
   (username #:init-keyword #:username
             #:getter player-username)
 
-  (self-commands #:init-value player-self-commands)
+  (self-commands #:allocation #:each-subclass
+                 #:init-thunk
+                 (build-commands
+                  (("inventory" "inv" "i") ((empty-command cmd-inventory)))
+                  ("help" ((empty-command cmd-help)))))
 
-  (message-handler
-   #:init-value
-   (wrap-apply player-dispatcher)))
+  (actions #:allocation #:each-subclass
+           #:init-thunk
+           (build-actions
+            (init player-init)
+            (handle-input player-handle-input)
+            (tell player-tell)
+            (disconnect-self-destruct player-disconnect-self-destruct)
+            (cmd-inventory player-cmd-inventory)
+            (cmd-help player-cmd-help))))
 
 
 ;;; player message handlers
 
 (define (player-init player message)
   ;; Look around the room we're in
-  (<- player (gameobj-loc player) 'look-room))
+  (<- (gameobj-loc player) 'look-room))
 
 
 (define* (player-handle-input player message #:key input)
 
   (match winner
     ((cmd-action winner-id message-args)
-     (apply <- player winner-id cmd-action message-args))
+     (apply <- winner-id cmd-action message-args))
     (#f
-     (<- player (gameobj-gm player) 'write-home
-         #:text "Huh?\n"))))
+     (<- (gameobj-gm player) 'write-home
+         #:text "Sorry, I didn't understand that? (type \"help\" for common commands)\n"))))
 
 (define* (player-tell player message #:key text)
-  (<- player (gameobj-gm player) 'write-home
+  (<- (gameobj-gm player) 'write-home
       #:text text))
 
 (define (player-disconnect-self-destruct player message)
   "Action routine for being told to disconnect and self destruct."
   (define loc (gameobj-loc player))
   (when loc
-    (<- player loc 'tell-room
+    (<- loc 'tell-room
         #:exclude (actor-id player)
         #:text (format #f "~a disappears in a puff of entropy!\n"
                        (slot-ref player 'name))))
   (define inv-names
     (map
      (lambda (inv-item)
-       (msg-receive (_ #:key val)
-           (<-wait player inv-item 'get-name)
-         val))
+       (mbody-val (<-wait inv-item 'get-name)))
      (gameobj-occupants player)))
   (define text-to-show
     (if (eq? inv-names '())
         "You aren't carrying anything.\n"
-        (apply string-append
-               "You are carrying:\n"
-               (map (lambda (item-name)
-                      (string-append "  * " item-name "\n"))
-                    inv-names))))
-  (<- player (actor-id player) 'tell #:text text-to-show))
+        `((p "You are carrying:")
+          (ul ,(map (lambda (item-name)
+                      `(li ,item-name))
+                    inv-names)))))
+  (<- (actor-id player) 'tell #:text text-to-show))
+
+(define (player-cmd-help player message)
+  (<- (actor-id player) 'tell
+      #:text '((strong "** Mudsync Help **")(br)
+               (p "You're playing Mudsync, a multiplayer text-adventure. "
+                  "Type different commands to interact with your surroundings "
+                  "and other players.")
+               (p "Some common commands:"
+                  (ul (li (strong "say <message>") " -- "
+                          "Chat with other players in the same room. "
+                          "(Also aliased to the " (b "\"") " character.)")
+                      (li (strong "look") " -- "
+                          "Look around the room you're in.")
+                      (li (strong "look [at] <object>") " -- "
+                          "Examine a particular object.")
+                      (li (strong "go <exit>") " -- "
+                          "Move to another room in <exit> direction.")))
+               (p "Different objects can be interacted with in different ways. "
+                  "For example, if there's a bell in the same room as you, "
+                  "you might try typing " (em "ring bell")
+                  " and see what happens."))))
 
 
 ;;; Command handling
                  #:player-id (actor-id player)))))
 
   ;; Ask the room for its commands
-  (define room-commands
+  (define room-dom-commands
     ;; TODO: Map room id and sort
-    (msg-receive (_ #:key commands)
-        (<-wait player player-loc
-             'get-container-commands
-             #:verb verb)
+    (mbody-receive (_ #:key commands)
+        (<-wait player-loc 'get-container-dom-commands
+                #:verb verb)
+      commands))
+
+  (define room-sub-commands
+    ;; TODO: Map room id and sort
+    (mbody-receive (_ #:key commands)
+        (<-wait player-loc 'get-container-sub-commands
+                #:verb verb)
       commands))
 
   ;; All the co-occupants of the room (not including ourself)
   (define co-occupants
     (remove
      (lambda (x) (equal? x (actor-id player)))
-     (msg-receive (_ #:key occupants)
-         (<-wait player player-loc 'get-occupants)
-       occupants)))
+     (mbody-val (<-wait player-loc 'get-occupants))))
 
   ;; @@: There's a race condition here if someone leaves the room
   ;;   during this, heh...
   (define co-occupant-commands
     (fold
      (lambda (co-occupant prev)
-       (msg-receive (_ #:key commands goes-by)
-           (<-wait player co-occupant 'get-commands
-                              #:verb verb)
+       (mbody-receive (_ #:key commands goes-by)
+           (<-wait co-occupant 'get-commands
+                   #:verb verb)
          (append
           (map (lambda (command)
                  (list command goes-by co-occupant))
 
   ;; Append our own command handlers
   (define our-commands
-    (filter
-     (lambda (cmd)
-       (equal? (command-verbs cmd) verb))
-     (val-or-run
-      (slot-ref player 'self-commands))))
+    (class-rmeta-ref (class-of player) 'self-commands verb
+                     #:dflt '()))
 
   ;; Append our inventory's relevant command handlers
   (define inv-items
   (define inv-item-commands
     (fold
      (lambda (inv-item prev)
-       (msg-receive (_ #:key commands goes-by)
-           (<-wait player inv-item
-                   'get-contained-commands
+       (mbody-receive (_ #:key commands goes-by)
+           (<-wait inv-item 'get-contained-commands
                    #:verb verb)
          (append
           (map (lambda (command)
 
   ;; Now return a big ol sorted list of ((actor-id . command))
   (append
-   (sort-commands-append-actor room-commands
+   (sort-commands-append-actor room-dom-commands
                                player-loc '()) ; room doesn't go by anything
    (sort-commands-multi-actors co-occupant-commands)
    (sort-commands-append-actor our-commands
                                (actor-id player) '()) ; nor does player
-   (sort-commands-multi-actors inv-item-commands)))
+   (sort-commands-multi-actors inv-item-commands)
+   (sort-commands-append-actor room-sub-commands
+                               player-loc '())))
 
 (define (sort-commands-append-actor commands actor-id goes-by)
   (sort-commands-multi-actors