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