--- /dev/null
+(if-lib::load-libs :advent)\r
+\r
+(in-package :advent)\r
+\r
+(defparameter *caves-closed* 0)\r
+(defparameter *canyon-from* 0)\r
+(defparameter *treasures-found* 0)\r
+(defparameter *deaths* 0)\r
+(defparameter *dark-warning* 0)\r
+(defparameter *feefie-count* 0)\r
+\r
+;;; Rules for treasures, which will be scattered all over the game\r
+\r
+(ref inside-building)\r
+\r
+(ifclass treasure ()\r
+ (deposit-points integer 10)\r
+ (after\r
+ (take (when (eql *location* inside-building)\r
+ (decf *score* (deposit-points self)))\r
+ (when (hasnt *noun* :treasure-found)\r
+ (give *noun* :treasure-found))\r
+ "Taken!")\r
+ (drop (decf *score* 5)\r
+ (when (eql *location* inside-building)\r
+ (incf *score* (deposit-points self))\r
+ "Safely deposited"))))\r
+\r
+;;; The outside world\r
+\r
+(ifclass above-ground (room)\r
+ (has :light :nodwarf))\r
+\r
+(object at-end-of-road (above-ground) "At End Of Road"\r
+ (description "You are standing at the end of a road\r
+ before a small brick building. Around you is\r
+ a forest. A small stream flows out of the\r
+ building and down a gully.")\r
+ (w-to 'at-hill-in-road) (u-to 'at-hill-in-road)\r
+ (e-to 'inside-building) (in-to 'inside-building)\r
+ (d-to 'in-a-valley) (s-to 'in-a-valley) (n-to 'in-forest-1)\r
+ (name "gully" "road" "street" "path"))\r
+\r
+;;Unlike Inform, LIFP objects must have names. I would be using @***\r
+;;syntax for the object whose name is not important\r
+\r
+(ref at-hill-in-road inside-building)\r
+\r
+(object @wellhouse (scenery) "well house"\r
+ (name "well" "house" "brick" "building" "small" "wellhouse")\r
+ (description "It's a small brick building. It seems to be\r
+ a well house.")\r
+ (before (enter (when (not (eql *location* inside-building))\r
+ (go-to-room inside-building))))\r
+ (found-in At-End-Of-Road At-Hill-In-Road Inside-Building))\r
+\r
+(free-symbol :stream)\r
+ ;;There is already a class STREAM in Common Lisp. We\r
+ ;;need to make it inacessible from our package so the\r
+ ;;new STREAM could be defined.\r
+\r
+(ref bottle ming-vase shards at-slit-in-streambed in-pit \r
+ in-cavern-with-waterfall at-reservoir in-a-valley)\r
+\r
+(object stream (scenery) "stream"\r
+ (name "stream" "water" "brook" "river" "lake" "small" "tumbling"\r
+ "splashing" "babbling" "rushing" "reservoir")\r
+ (found-in At-End-Of-Road In-A-Valley At-Slit-In-Streambed\r
+ In-Pit In-Cavern-With-Waterfall At-Reservoir\r
+ Inside-Building)\r
+ (before\r
+ (drink "You have taken a drink from the stream. The\r
+ water tastes strongly of minerals, but is not\r
+ unpleasant. It is extremely cold.")\r
+ (take (if (in bottle *player*)\r
+ (instead 'fill bottle)\r
+ "You have nothing in which to carry the water."))\r
+ (put-in (if (eql *second* bottle) (instead 'fill bottle)\r
+ "You have nothing in which to carry the water."))\r
+ (receive (when (eql *noun* ming-vase)\r
+ (rmv ming-vase) (move shards *location*)\r
+ (decf *score* 5) \r
+ (return-from before "The sudden change in\r
+ temperature has delicately shattered the vase."))\r
+ (when (eql *noun* bottle)\r
+ (return-from before (instead 'fill bottle)))\r
+ (rmv *noun*)\r
+ (when (ofclass *noun* 'treasure) (decf *score* 10))\r
+ (sprint "~a washes away with the stream" (the-name *noun*))\r
+ t)))\r
+\r
+(ref in-forest-1 in-forest-2)\r
+\r
+(object @road (scenery) "road"\r
+ (name "road" "street" "path" "dirt")\r
+ (description "The road is dirt, not yellow brick.")\r
+ (found-in At-End-Of-Road At-Hill-In-Road In-Forest-2))\r
+\r
+(object @forest (scenery) "forest"\r
+ (name "forest" "tree" "trees" "oak" "maple" "grove" "pine"\r
+ "spruce" "birch" "ash" "saplings" "bushes" "leaves"\r
+ "berry" "berries" "hardwood")\r
+ (description "The trees of the forest are large hardwood\r
+ oak and maple, with an occasional grove of pine\r
+ or spruce. There is quite a bit of undergrowth,\r
+ largely birch and ash saplings plus nondescript\r
+ bushes of various sorts. This time of year\r
+ visibility is quite restricted by all the leaves,\r
+ but travel is quite easy if you detour around the\r
+ spruce and berry bushes.")\r
+ (found-in At-End-Of-Road At-Hill-In-Road In-A-Valley\r
+ In-Forest-1 In-Forest-2)\r
+ (has :multitude))\r
+\r
+(object at-hill-in-road (above-ground) "At Hill In Road"\r
+ (description "You have walked up a hill, still in the\r
+ forest. The road slopes back down the other side\r
+ of the hill. There is a building in the distance.")\r
+ (e-to 'at-end-of-road) (n-to 'at-end-of-road)\r
+ (d-to 'at-end-of-road) (s-to 'in-forest-1)\r
+ (name "gully" "road" "street" "path"))\r
+\r
+\r
+(object @hill (scenery) "hill" at-hill-in-road\r
+ (description "It's just a typical hill.")\r
+ (name "hill" "bump" "incline"))\r
+\r
+(object @otherside (scenery) "other side of hill"\r
+ (article "the")\r
+ (description "Why not explore it yourself?")\r
+ (name "other" "side" "of"))\r
+\r
+(ref spring sewer-pipes in-debris-room at-y2)\r
+\r
+(object inside-building (above-ground) "Inside Building"\r
+ (description "You are inside a building, a well house for a \r
+ large spring.")\r
+ (cant-go "The stream flows out through a pair of 1 foot \r
+ diameter sewer pipes. The only exit is to the west.")\r
+ (before\r
+ (enter (when (among *noun* spring sewer-pipes) \r
+ "The stream flows out through a pair of 1 foot\r
+ diameter sewer pipes. It would be advisable to\r
+ use the exit."))\r
+ (xyzzy (when (has in-debris-room :visited) \r
+ (go-to-room in-debris-room) t))\r
+ (plugh (when (has at-y2 :visited)\r
+ (go-to-room at-y2) t)))\r
+ (w-to 'at-end-of-road) (out-to 'at-end-of-road)\r
+ (in-to "The pipes are too small"))\r
+\r
+(object spring (scenery) "spring" inside-building\r
+ (name "spring" "large")\r
+ (description "The stream flows out through a pair of 1 foot \r
+ diameter sewer pipes."))\r
+\r
+(object sewer-pipes (scenery) \r
+ "pair of 1 foot diameter sewer pipes" inside-building\r
+ (name "pipes" "pipe" "one" "foot" "diameter" "sewer" "sewer-pipes")\r
+ (description "Too small. The only exit is to the west."))\r
+\r
+(object set-of-keys (item) "set of keys" inside-building\r
+ (description "It's just a normal-looking set of keys.")\r
+ (glance "There are some keys on the ground here.")\r
+ (before (count "A dozen or so keys."))\r
+ (name "keys" "key" "keyring" "set" "of" "bunch"))\r
+\r
+(object tasty-food (food) "tasty food" inside-building\r
+ (description "Sure looks yummy!") (article "some")\r
+ (glance "There is tasty food here.")\r
+ (name "food" "ration" "rations" "tripe"\r
+ "yummy" "tasty" "delicious" "scrumptious")\r
+ (after (eat "Delicious!")))\r
+\r
+(ref fresh-batteries old-batteries vending-machine dead-end-14)\r
+\r
+(object brass-lantern (item switchable) "brass lantern" inside-building\r
+ (name "lamp" "headlamp" "headlight" "lantern" "light" \r
+ "shiny" "brass")\r
+ (glance (lambda ()\r
+ (if (has self :on)\r
+ "Your lamp is here, gleaming brightly."\r
+ "There is a shiny brass lamp nearby.")))\r
+ (power-remaining integer 330)\r
+ (replace-batteries function\r
+ (lambda ()\r
+ (when (in fresh-batteries *player* *location*)\r
+ (rmv fresh-batteries) (give fresh-batteries :general)\r
+ (move old-batteries *location*)\r
+ (setf (power-remaining self) 2500)\r
+ "I'm taking the liberty of replacing the batteries.")))\r
+ (before \r
+ (examine (sprint "It is a shiny brass lamp")\r
+ (if (has self :on) \r
+ (if (< (power-remaining self) 30) ", glowing dimly."\r
+ ", glowing brightly.")\r
+ ". It is not currently lit."))\r
+ (burn (instead 'switch-on self))\r
+ (rub "Rubbing the electric lamp is not particularly \r
+ rewarding. Anyway, nothing exciting happens.")\r
+ (switch-on (when (<= (power-remaining self) 0)\r
+ "Unfortunately, the batteries seem to be dead."))\r
+ (receive\r
+ (cond\r
+ ((eql *noun* old-batteries)\r
+ "Those batteries are dead; they won't do any good at all.")\r
+ ((eql *noun* fresh-batteries) (rp self 'replace-batteries) t)\r
+ (t "The only thing you might successfully put in the\r
+ lamp is a fresh pair of batteries."))))\r
+ (after\r
+ (switch-on (give self :light) (start-daemon self) nil)\r
+ (switch-off (give self :~light) nil))\r
+ (daemon\r
+ (lambda () (block daemon\r
+ (when (hasnt self :on) (stop-daemon self) \r
+ (return-from daemon t))\r
+ (let ((tt (decf (power-remaining self))))\r
+ (when (zerop tt) (give self :~on :~light))\r
+ (when (or (in self *player*) (in self *location*))\r
+ (case tt\r
+ (0 (sprint "Your lamp has run out of power.")\r
+ (unless (or (in fresh-batteries *player*)\r
+ (has *location* :light))\r
+ (setf *gamestate* 3)\r
+ (return-from daemon " You can't explore the cave\r
+ without a lamp. So let's just call it a day."))\r
+ (newline) (return-from daemon t))\r
+ (30 (sprint "Your lamp is getting dim.")\r
+ (cond \r
+ ((has fresh-batteries :general)\r
+ " You're also out of spare batteries.\r
+ You'd best start wrapping this up.")\r
+ ((and (in fresh-batteries vending-machine)\r
+ (has dead-end-14 :visited))\r
+ " You'd best start wrapping this up,\r
+ unless you can find some fresh batteries. I\r
+ seem to recall there's a vending machine in\r
+ the maze. Bring some coins with you.")\r
+ ((notin fresh-batteries vending-machine\r
+ *player* *location*)\r
+ " You'd best go back for those batteries.")\r
+ (t (newline) t))))))))))\r
+\r
+(ref water-in-the-bottle oil oil-in-the-bottle)\r
+\r
+(object bottle (item container) "small bottle" inside-building\r
+ (name "bottle" "jar" "flask")\r
+ (glance "There is an empty bottle here.")\r
+ (before\r
+ (let-go\r
+ (when (in *noun* bottle) \r
+ "You're holding that already (in the bottle)."))\r
+ (receive\r
+ (if (among *noun* stream oil) (instead 'fill self)\r
+ "The bottle is only supposed to hold liquids."))\r
+ (fill\r
+ (cond\r
+ ((child bottle) "The bottle is full already.")\r
+ ((and (in stream *location*) (in spring *location*))\r
+ (move water-in-the-bottle bottle)\r
+ "The bottle is now full of water.")\r
+ ((in oil *location*)\r
+ (move oil-in-the-bottle bottle)\r
+ "The bottle is now full of oil.")\r
+ (t "There is nothing here with which to fill the bottle.")))\r
+ (empty\r
+ (if (child bottle)\r
+ (progn (rmv (child bottle)) \r
+ "Your bottle is now empty and the ground is now wet.")\r
+ "The bottle is already empty!")))\r
+ (has :open))\r
+\r
+(object water-in-the-bottle () "bottled water"\r
+ (name "bottled" "water" "h2o") (article "some")\r
+ (before\r
+ (drink (rmv self) (instead 'drink stream)))\r
+ (description "It looks like ordinary water to me."))\r
+\r
+(object oil-in-the-bottle () "bottled oil"\r
+ (name "oil" "bottled" "lubricant" "grease") (article "some")\r
+ (before (drink (instead 'drink oil)))\r
+ (description "It looks like ordinary oil to me."))\r
+\r
+(object in-forest-1 (above-ground) "In Forest"\r
+ (description "You are in open forest, with a deep valley to one side.")\r
+ (e-to 'in-a-valley) (d-to 'in-a-valley)\r
+ (n-to 'in-forest-1) (w-to 'in-forest-1) (s-to 'in-forest-1)\r
+ (initial (lambda () (when (zerop (random 2)) \r
+ (go-to-room 'in-forest-2)))))\r
+\r
+(object in-forest-2 (above-ground) "In Forest"\r
+ (description "You are in open forest near both a valley and a road.")\r
+ (n-to 'at-end-of-road) (e-to 'in-a-valley) (w-to 'in-a-valley)\r
+ (d-to 'in-a-valley) (s-to 'in-forest-1))\r
+\r
+(object in-a-valley (above-ground) "In A Valley"\r
+ (description "You are in a valley in the forest beside a\r
+ stream tumbling along a rocky bed.")\r
+ (name "valley")\r
+ (n-to 'at-end-of-road) (e-to in-forest-1) (w-to 'in-forest-1)\r
+ (u-to 'in-forest-1) (s-to 'at-slit-in-streambed)\r
+ (d-to 'at-slit-in-streambed))\r
+\r
+(object at-slit-in-streambed (above-ground) "At Slit In Streambed"\r
+ (description "At your feet all the water of the stream \r
+ splashes into a 2-inch slit in the rock. Downstream \r
+ the streambed is bare rock.")\r
+ (n-to 'in-a-valley) (e-to 'in-forest-1) (w-to 'in-forest-1)\r
+ (s-to 'outside-grate) (d-to "You don't fit through a two-inch slit!")\r
+ (in-to "You don't fit through a two-inch slit!"))\r
+\r
+(object @2inslit (scenery) "2-inch slit"\r
+ (name "slit" "two" "inch" "2-inch")\r
+ (description "It's just a 2-inch slit in the rock, through which the \r
+ stream is flowing.")\r
+ (before (enter "You don't fit through a two-inch slit!")))\r
+\r
+(object @streambed (scenery) "streambed"\r
+ (name "bed" "streambed" "rock" "small" "rocky" "bare" "dry")\r
+ (found-in in-a-valley at-slit-in-streambed)) \r
+\r
+(object outside-grate (above-ground) "Outside Grate"\r
+ (description "You are in a 20-foot depression floored with \r
+ bare dirt. Set into the dirt is a strong steel grate \r
+ mounted in concrete. A dry streambed leads into the \r
+ depression.")\r
+ (e-to 'in-forest-1) (w-to 'in-forest-1) (s-to 'in-forest-1)\r
+ (n-to 'at-slit-in-streambed)\r
+ (d-to (lambda ()\r
+ (if (hasnt grate :locked :open)\r
+ (progn\r
+ (sprint "(first opening the grate)~%")\r
+ (give grate :open))\r
+ 'grate))))\r
+\r
+(object @20ftdepression (scenery) "20-foot depression"\r
+ (description "You're standing in it")\r
+ (name "depression" "dirt" "twenty" "foot" "bare" "20-foot"))\r
+\r
+(ref below-the-grate)\r
+\r
+(object grate (door) "steel grate"\r
+ (name "grate" "lock" "gate" "grille" "metal" \r
+ "strong" "steel" "grating")\r
+ (description "It just looks like an ordinary grate\r
+ mounted in concrete.")\r
+ (key 'set-of-keys)\r
+ (door-dir\r
+ (lambda () (if (eql *location* below-the-grate) 'u-to 'd-to)))\r
+ (door-to\r
+ (lambda () (if (eql *location* below-the-grate)\r
+ outside-grate below-the-grate)))\r
+ (glance\r
+ (lambda ()\r
+ (cond ((has self :open) "The grate stands open.")\r
+ ((hasnt self :locked) "The grate is unlocked but shut.")\r
+ (t t))))\r
+ (found-in below-the-grate outside-grate)\r
+ (has :openable :lockable :locked))\r
+\r
+;;FACILIS DESCENSUS AVERNO\r
+\r
+(object below-the-grate (room) "Below the Grate"\r
+ (description "You are in a small chamber beneath a 3x3\r
+ steel grate to the surface. A low crawl over\r
+ cobbles leads inward to the west.")\r
+ (w-to 'in-cobble-crawl) (u-to 'grate))\r
+ \r
+ \r
+ \r
+ \r
+ \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+(supply init ()\r
+ (setf *location* at-end-of-road))
\ No newline at end of file