frumpy fellow is a she now, obviously ;P
[mudsync.git] / worlds / bricabrac.scm
index 1035dd76173ff9187325478a6dba95538fa0643b..d4c26294971da2ab4ff627f55c937f998a172881 100644 (file)
@@ -1,5 +1,5 @@
 ;;; Mudsync --- Live hackable MUD
 ;;; Mudsync --- Live hackable MUD
-;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016, 2017 Christopher Allan Webber <cwebber@dustycloud.org>
 ;;;
 ;;; This file is part of Mudsync.
 ;;;
 ;;;
 ;;; This file is part of Mudsync.
 ;;;
@@ -258,16 +258,15 @@ character.\n")))
     <chatty-npc> 'lobby
     #:name "a frumpy fellow"
     #:desc
     <chatty-npc> 'lobby
     #:name "a frumpy fellow"
     #:desc
-    '((p "  Whoever this is, they looks totally exhausted.  They're
+    '((p "  Whoever this is, she looks totally exhausted.  She's
 collapsed into the only comfortable looking chair in the room and you
 collapsed into the only comfortable looking chair in the room and you
-don't get the sense that they're likely to move any time soon.
+don't get the sense that she's likely to move any time soon.
   You notice they're wearing a sticker badly adhesed to their clothing
   You notice they're wearing a sticker badly adhesed to their clothing
-which says \"Hotel Proprietor\", but they look so disorganized that you
+which says \"Hotel Proprietor\", but she looks so disorganized that you
 think that can't possibly be true... can it?
 think that can't possibly be true... can it?
-  Despite their exhaustion, you sense they'd be happy to chat with you,
+  Despite her exhaustion, you sense she'd be happy to chat with you,
 though the conversation may be a bit one sided."))
     #:goes-by '("frumpy fellow" "fellow"
 though the conversation may be a bit one sided."))
     #:goes-by '("frumpy fellow" "fellow"
-                "Chris Webber"  ; heh, did you rtfc?  or was it so obvious?
                 "hotel proprietor" "proprietor")
     #:catchphrases hotel-owner-grumps)
    ;; Object: Sign
                 "hotel proprietor" "proprietor")
     #:catchphrases hotel-owner-grumps)
    ;; Object: Sign
@@ -597,6 +596,243 @@ platter!  It has \"RL02.5\" written on it.  It looks kind of loose."
 ;;; Playroom
 ;;; --------
 
 ;;; Playroom
 ;;; --------
 
+(define-actor <rgb-machine> (<gameobj>)
+  ((cmd-run rgb-machine-cmd-run)
+   (cmd-reset rgb-machine-cmd-reset))
+  (commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 (("run" "start") ((direct-command cmd-run)))
+                 ("reset" ((direct-command cmd-reset)))))
+  (resetting #:init-value #f
+             #:accessor .resetting)
+  ;; used to reset, and to kick off the first item in the list
+  (rgb-items #:init-keyword #:rgb-items
+             #:accessor .rgb-items))
+
+(define (rgb-machine-cmd-run rgb-machine message . _)
+  (define player (message-from message))
+  (<-wait player 'tell
+          #:text '("You start the rube goldberg machine."))
+  (<-wait (gameobj-loc rgb-machine) 'tell-room
+          #:text `(,(mbody-val (<-wait player 'get-name))
+                   " runs the rube goldberg machine.")
+          #:exclude player)
+  (8sleep 1)
+  (match (.rgb-items rgb-machine)
+    ((first-item rest ...)
+     (<- (dyn-ref rgb-machine first-item) 'trigger))))
+
+(define (rgb-machine-cmd-reset rgb-machine message . _)
+  (define player (message-from message))
+  (cond
+   ((not (.resetting rgb-machine))
+    (set! (.resetting rgb-machine) #t)
+    (<-wait player 'tell
+            #:text '("You reset the rube goldberg machine."))
+    (<-wait (gameobj-loc rgb-machine) 'tell-room
+            #:text `(,(mbody-val (<-wait player 'get-name))
+                     " resets the rube goldberg machine.")
+            #:exclude player)
+    (<-wait (gameobj-loc rgb-machine) 'tell-room
+            #:text '("From a panel in the wall, a white gloved mechanical "
+                     "arm reaches out to reset all the "
+                     "rube goldberg components."))
+    (8sleep (/ 1 2))
+    (for-each
+     (lambda (rgb-item)
+       (<- (dyn-ref rgb-machine rgb-item) 'reset)
+       (8sleep (/ 1 2)))
+     (.rgb-items rgb-machine))
+    (<- (gameobj-loc rgb-machine) 'tell-room
+        #:text "The machine's mechanical arm retreats into the wall!")
+    (set! (.resetting rgb-machine) #f))
+   (else
+    (<-wait player 'tell
+            #:text '("But it's in the middle of resetting right now!")))))
+
+(define-actor <rgb-item> (<gameobj>)
+  ((trigger rgb-item-trigger)
+   (reset rgb-item-reset))
+  (invisible? #:init-value #t)
+  (steps #:init-keyword #:steps
+         #:accessor .steps)
+  (triggers-as #:init-value #f
+               #:init-keyword #:triggers-as
+               #:getter .triggers-as)
+  (reset-msg #:init-keyword #:reset-msg
+             #:getter .reset-msg)
+  ;; States: ready -> running -> ran
+  (state #:init-value 'ready
+         #:accessor .state))
+
+
+(define (rgb-item-trigger rgb-item message . _)
+  (define room (gameobj-loc rgb-item))
+  (case (.state rgb-item)
+    ((ready)
+     ;; Set state to running
+     (set! (.state rgb-item) 'running)
+
+     ;; Loop through all steps
+     (for-each
+      (lambda (step)
+        (match step
+          ;; A string?  That's the description of what's happening, tell players
+          ((? string? str)
+           (<- room 'tell-room #:text str))
+          ;; A number?  Sleep for that many secs
+          ((? number? num)
+           (8sleep num))
+          ;; A symbol?  That's another gameobj to look up dynamically
+          ((? symbol? sym)
+           (<- (dyn-ref rgb-item sym) 'trigger
+               #:triggered-by (.triggers-as rgb-item)))
+          (_ (throw 'unknown-step-type
+                    "Don't know how to process rube goldberg machine step type?"
+                    #:step step))))
+      (.steps rgb-item))
+
+     ;; We're done! Set state to ran
+     (set! (.state rgb-item) 'ran))
+
+    (else
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been triggered!")))))
+
+(define (rgb-item-reset rgb-item message . _)
+  (define room (gameobj-loc rgb-item))
+  (case (.state rgb-item)
+    ((ran)
+     (set! (.state rgb-item) 'ready)
+     (<- room 'tell-room
+         #:text (.reset-msg rgb-item)))
+    ((running)
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " is currently running!")))
+    ((ready)
+     (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been reset.")))))
+
+(define-actor <rgb-kettle> (<rgb-item>)
+  ((trigger rgb-kettle-trigger)
+   (reset rgb-kettle-reset))
+  (heated #:accessor .heated
+          #:init-value #f)
+  (filled #:accessor .filled
+          #:init-value #f))
+
+(define* (rgb-kettle-trigger rgb-item message #:key triggered-by)
+  (define room (gameobj-loc rgb-item))
+  (if (not (eq? (.state rgb-item) 'ran))
+      (begin
+        (match triggered-by
+          ('water-demon
+           (set! (.state rgb-item) 'running)
+           (set! (.filled rgb-item) #t))
+          ('quik-heater
+           (set! (.state rgb-item) 'running)
+           (set! (.heated rgb-item) #t)))
+        (when (and (.filled rgb-item)
+                   (.heated rgb-item))
+          (<- room 'tell-room
+              #:text '((i "*kshhhhhh!*")
+                       " The water has boiled!"))
+          (8sleep .25)
+          (set! (.state rgb-item) 'ran)
+          ;; insert a cup of hot tea in the room
+          (create-gameobj <hot-tea> (gameobj-gm rgb-item) room)
+          (<- room 'tell-room
+              #:text '("The machine pours out a cup of hot tea! "
+                       "Looks like the machine finished!"))))
+      (<- room 'tell-room
+         #:text `("... but " ,(slot-ref rgb-item 'name)
+                  " has already been triggered!"))))
+
+(define (rgb-kettle-reset rgb-item message . rest-args)
+  (define room (gameobj-loc rgb-item))
+  (when (eq? (.state rgb-item) 'ran)
+    (set! (.heated rgb-item) #f)
+    (set! (.filled rgb-item) #f))
+  (apply rgb-item-reset rgb-item message rest-args))
+
+(define-actor <tinfoil-hat> (<gameobj>)
+  ((cmd-wear tinfoil-hat-wear))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 ("wear" ((direct-command cmd-wear))))))
+
+(define (tinfoil-hat-wear tinfoil-hat message . _)
+  (<- (message-from message) 'tell
+      #:text '("You put on the tinfoil hat, and, to be perfectly honest with you "
+               "it's a lot harder to take you seriously.")))
+
+
+(define-actor <hot-tea> (<gameobj>)
+  ((cmd-drink hot-tea-cmd-drink)
+   (cmd-sip hot-tea-cmd-sip))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk (build-commands
+                 ("drink" ((direct-command cmd-drink)))
+                 ("sip" ((direct-command cmd-sip)))))
+  
+  (sips-left #:init-value 4
+             #:accessor .sips-left)
+  (name #:init-value "a cup of hot tea")
+  (take-me? #:init-value #t)
+  (goes-by #:init-value '("cup of hot tea" "cup of tea" "tea" "cup"))
+  (desc #:init-value "It's a steaming cup of hot tea.  It looks pretty good!"))
+
+(define (hot-tea-cmd-drink hot-tea message . _)
+  (define player (message-from message))
+  (define player-loc (mbody-val (<-wait player 'get-loc)))
+  (define player-name (mbody-val (<-wait player 'get-name)))
+  (<- player 'tell
+      #:text "You drink a steaming cup of hot tea all at once... hot hot hot!")
+  (<- player-loc 'tell-room
+      #:text `(,player-name
+               " drinks a steaming cup of hot tea all at once.")
+      #:exclude player)
+  (gameobj-self-destruct hot-tea))
+
+(define (hot-tea-cmd-sip hot-tea message . _)
+  (define player (message-from message))
+  (define player-loc (mbody-val (<-wait player 'get-loc)))
+  (define player-name (mbody-val (<-wait player 'get-name)))
+  (set! (.sips-left hot-tea) (- (.sips-left hot-tea) 1))
+  (<- player 'tell
+      #:text "You take a sip of your steaming hot tea.  How refined!")
+  (<- player-loc 'tell-room
+      #:text `(,player-name
+               " takes a sip of their steaming hot tea.  How refined!")
+      #:exclude player)
+  (when (= (.sips-left hot-tea) 0)
+    (<- player 'tell
+        #:text "You've finished your tea!")
+    (<- player-loc 'tell-room
+        #:text `(,player-name
+                 " finishes their tea!")
+        #:exclude player)
+    (gameobj-self-destruct hot-tea)))
+
+(define-actor <fanny-pack> (<container>)
+  ((cmd-take-from-while-wearing cmd-take-from)
+   (cmd-put-in-while-wearing cmd-put-in))
+  (contained-commands
+   #:allocation #:each-subclass
+   #:init-thunk
+   (build-commands
+    (("l" "look") ((direct-command cmd-look-at)))
+    ("take" ((prep-indir-command cmd-take-from-while-wearing
+                                 '("from" "out of"))))
+    ("put" ((prep-indir-command cmd-put-in-while-wearing
+                                '("in" "inside" "into" "on")))))))
+
 (define playroom
   (lol
    ('playroom
 (define playroom
   (lol
    ('playroom
@@ -648,7 +884,138 @@ if this room is intended for children or child-like adults.")
     #:name "a rubber duck"
     #:goes-by '("rubber duck" "duck")
     #:take-me? #t
     #:name "a rubber duck"
     #:goes-by '("rubber duck" "duck")
     #:take-me? #t
-    #:desc "It's a yellow rubber duck with a bright orange beak.")))
+    #:desc "It's a yellow rubber duck with a bright orange beak.")
+
+   ('playroom:toy-chest:tinfoil-hat
+    <tinfoil-hat> 'playroom:toy-chest
+    #:name "a tinfoil hat"
+    #:goes-by '("tinfoil hat" "hat")
+    #:take-me? #t
+    #:desc "You'd have to be a crazy person to wear this thing!")
+
+   ('playroom:toy-chest:fanny-pack
+    <fanny-pack> 'playroom:toy-chest
+    #:name "a fanny pack"
+    #:goes-by '("fanny pack" "pack")
+    #:take-me? #t
+    #:desc
+    (lambda (toy-chest whos-looking)
+      (let ((contents (gameobj-occupants toy-chest)))
+        `((p "It's a leather fanny pack, so it's both tacky and kinda cool.")
+          (p "Inside you see:"
+             ,(if (eq? contents '())
+                  " nothing!  It's empty!"
+                  `(ul ,(map (lambda (occupant)
+                               `(li ,(mbody-val
+                                      (<-wait occupant 'get-name))))
+                             (gameobj-occupants toy-chest)))))))))
+
+   ;; Things inside the toy chest
+   ('playroom:toy-chest:fanny-pack:plastic-elephant
+    <gameobj> 'playroom:toy-chest:fanny-pack
+    #:name "a plastic elephant"
+    #:goes-by '("plastic elephant" "elephant")
+    #:take-me? #t
+    #:desc "It's a tiny little plastic elephant.  Small, but heartwarming.")
+
+   ('playroom:rgb-machine
+    <rgb-machine> 'playroom
+    #:name "a Rube Goldberg machine"
+    #:goes-by '("rube goldberg machine" "machine")
+    #:rgb-items '(playroom:rgb-dominoes
+                  playroom:rgb-switch-match
+                  playroom:rgb-candle
+                  playroom:rgb-catapult
+                  playroom:rgb-water-demon
+                  playroom:rgb-quik-heater
+                  playroom:rgb-kettle)
+    #:desc "It's one of those hilarious Rube Goldberg machines.
+What could happen if you started it?")
+
+   ;; Dominoes topple
+   ('playroom:rgb-dominoes
+    <rgb-item> 'playroom
+    #:name "some dominoes"
+    #:goes-by '("dominoes" "some dominoes")
+    #:steps `("The dominoes topple down the line..."
+              1
+              "The last domino lands on a switch!"
+              1.5
+              playroom:rgb-switch-match)
+    #:reset-msg "The dominoes are placed back into position.")
+
+   ;; Which hit the switch and strike a match
+   ('playroom:rgb-switch-match
+    <rgb-item> 'playroom
+    #:name "a switch"
+    #:goes-by '("switch" "match")
+    #:steps `("The switch lights a match!"
+              ,(/ 2 3)
+              "The match lights a candle!"
+              1.5
+              playroom:rgb-candle)
+    #:reset-msg "A fresh match is installed and the switch is reset.")
+   ;; which lights a candle and burns a rope
+   ('playroom:rgb-candle
+    <rgb-item> 'playroom
+    #:name "a candle"
+    #:goes-by '("candle")
+    #:steps `("The candle burns..."
+              (/ 2 3)  ; oops!
+              "The candle is burning away a rope!"
+              2
+              "The rope snaps!"
+              .5
+              playroom:rgb-catapult)
+    #:reset-msg "A fresh candle is installed.")
+   ;; which catapults a rock
+   ('playroom:rgb-catapult
+    <rgb-item> 'playroom
+    #:name "a catapult"
+    #:goes-by '("catapult")
+    #:steps `("The snapped rope unleashes a catapult, which throws a rock!"
+              2
+              "The rock flies through a water demon, startling it!"
+              .5
+              playroom:rgb-water-demon
+              2
+              "The rock whacks into the quik-heater's on button!"
+              .5
+              playroom:rgb-quik-heater)
+    #:reset-msg
+    '("A fresh rope is attached to the catapult, which is pulled taught. "
+      "A fresh rock is placed on the catapult."))
+   ;; which both:
+   ;;   '- panics the water demon
+   ;;      '- which waters the kettle
+   ('playroom:rgb-water-demon
+    <rgb-item> 'playroom
+    #:name "the water demon"
+    #:triggers-as 'water-demon
+    #:goes-by '("water demon" "demon")
+    #:steps `("The water demon panics, and starts leaking water into the kettle below!"
+              3
+              "The kettle is filled!"
+              playroom:rgb-kettle)
+    #:reset-msg '("The water demon is scratched behind the ears and calms down."))
+   ;;   '- bops the quik-heater button
+   ;;      '- which heats the kettle
+   ('playroom:rgb-quik-heater
+    <rgb-item> 'playroom
+    #:name "the quik heater"
+    #:triggers-as 'quik-heater
+    #:goes-by '("quik heater" "heater")
+    #:steps `("The quik-heater heats up the kettle above it!"
+              3
+              "The kettle is heated up!"
+              playroom:rgb-kettle)
+    #:reset-msg '("The quik heater is turned off."))
+   ;; Finally, the kettle
+   ('playroom:rgb-kettle
+    <rgb-kettle> 'playroom
+    #:name "the kettle"
+    #:goes-by '("kettle")
+    #:reset-msg '("The kettle is emptied."))))
 
 
 \f
 
 
 \f
@@ -1367,8 +1734,22 @@ is a map detailing the layout of the underground structure."))
             #:to 'hive-entrance)
           (make <exit>
             #:name "east"
             #:to 'hive-entrance)
           (make <exit>
             #:name "east"
-            #:to 'federation-station)))
-
+            #:to 'federation-station)
+          (make <exit>
+            #:name "south"
+            #:traverse-check
+            (lambda (exit room whos-exiting)
+              (values #f '("Ooh, if only you could go south and check this out! "
+                           "Unfortunately this whole area is sealed off... the proprietor "
+                           "probably never got around to fixing it. "
+                           "Too bad, it would have had monsters to fight and everything!"))))
+          (make <exit>
+            #:name "southwest"
+            #:traverse-check
+            (lambda (exit room whos-exiting)
+              (values #f '("Hm, it's one of those revolving doors that only revolves in "
+                           "one direction, and it isn't this one.  You guess that while "
+                           "this doesn't appear to be an entrance, it probably is an exit."))))))
    ;; map
    ('underground-lab:map
     <readable> 'underground-lab
    ;; map
    ('underground-lab:map
     <readable> 'underground-lab
@@ -1381,7 +1762,7 @@ is a map detailing the layout of the underground structure."))
    ('underground-lab:8sync-sign
     <readable> 'underground-lab
     #:name "a sign labeled \"8sync design goals\""
    ('underground-lab:8sync-sign
     <readable> 'underground-lab
     #:name "a sign labeled \"8sync design goals\""
-    #:goes-by '("sign" "8sync design goals sign" "8sync sign")
+    #:goes-by '("sign" "8sync design goals sign" "8sync goals" "8sync design" "8sync sign")
     #:read-text 8sync-design-goals
     #:desc `((p "The sign says:")
              ,8sync-design-goals))))
     #:read-text 8sync-design-goals
     #:desc `((p "The sign says:")
              ,8sync-design-goals))))
@@ -1561,11 +1942,18 @@ as well as an exit leading to the south."))
    ('gift-shop
     <room> #f
     #:name "Museum Gift Shop"
    ('gift-shop
     <room> #f
     #:name "Museum Gift Shop"
-    #:desc "foo"
+    #:desc '("There are all sorts of scrolls and knicknacks laying around here, "
+             "but they all seem glued in place and instead of a person manning the shop "
+             "there's merely a cardboard cutout of a person with a \"shopkeeper\" nametag. "
+             "You can pretty well bet that someone wanted to finish this room but ran out of "
+             "time.")
     #:exits (list
              (make <exit>
                #:name "northeast"
     #:exits (list
              (make <exit>
                #:name "northeast"
-               #:to 'underground-lab)
+               #:to 'underground-lab
+               #:traverse-check
+               (lambda (exit room whos-exiting)
+                 (values #t '("The revolving door spins as you walk through it.  Whee!"))))
              (make <exit>
                #:name "north"
                #:to 'async-museum)))))
              (make <exit>
                #:name "north"
                #:to 'async-museum)))))
@@ -1767,8 +2155,50 @@ network.")
             #:name "west"
             #:to 'underground-lab)))
    ;; nodes
             #:name "west"
             #:to 'underground-lab)))
    ;; nodes
+   ('federation-station:nodes
+    <floor-panel> 'federation-station
+    #:name "some nodes"
+    #:desc "Each node seems to be producing its own information, but publishing 
+updates to subscribing nodes on the graph.  You see various posts of notes, videos,
+comments, and so on flowing from node to node."
+    #:invisible? #t
+    #:goes-by '("nodes" "node" "some nodes"))
    ;; network
    ;; activitypub poster
    ;; network
    ;; activitypub poster
+   ('federation-station:activitypub-poster
+    <readable-desc> 'federation-station
+    #:name "an ActivityPub poster"
+    #:goes-by '("activitypub poster" "activitypub" "poster")
+    #:desc
+    '((p (a "https://www.w3.org/TR/activitypub/"
+            "ActivityPub")
+         " is a federation standard being developed under the "
+         (a "https://www.w3.org/wiki/Socialwg/"
+            "w3C Social Working Group")
+         ", and doubles as a general client-to-server API. "
+         "It follows a few simple core ideas:")
+      (ul (li "Uses "
+              (a "https://www.w3.org/TR/activitystreams-core/"
+                 "ActivityStreams")
+              " for its serialization format: easy to read, e json(-ld) syntax "
+              "with an extensible vocabulary covering the majority of "
+              "social networking interations.")
+          (li "Email-like addressing: list of recipients as "
+              (b "to") ", " (b "cc") ", " (b "bcc") " fields.")
+          (li "Every user has URLs for their outbox and inbox:"
+              (ul (li (b "inbox: ")
+                      "Servers POST messages to addressed recipients' inboxes "
+                      "to federate out content. "
+                      "Also doubles as endpoint for a client to read most "
+                      "recently received messages via GET.")
+                  (li (b "outbox: ")
+                      "Clients can POST to user's outbox to send a message to others. "
+                      "(Similar to sending an email via your MTA.) "
+                      "Doubles as endpoint others can read from to the "
+                      "extent authorized; for example publicly available posts."))
+              "All the federation bits happen by servers posting to users' inboxes."))))
+   ;; An ActivityStreams message
+
    ;; conspiracy chart
    ('federation-station:conspiracy-chart
     <readable-desc> 'federation-station
    ;; conspiracy chart
    ('federation-station:conspiracy-chart
     <readable-desc> 'federation-station
@@ -1811,8 +2241,7 @@ network.")
             (a "http://www.saraswat.org/desiderata.html"
                "in building decentralized MUDs")
             " similar to what is being "
             (a "http://www.saraswat.org/desiderata.html"
                "in building decentralized MUDs")
             " similar to what is being "
-            "worked on for " (b "federation") ". "
-            "(See the network spaces desiderata document.)")))))
+            "worked on for " (b "federation") ". ")))))
 
    ;; goblin
 
 
    ;; goblin