diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/woods.atl b/ATL/Pooh/woods.atl index ce1da37..5a2ce85 100644 --- a/ATL/Pooh/woods.atl +++ b/ATL/Pooh/woods.atl @@ -104,9 +104,9 @@ their branches. Broken branches lie about on the ground and cob webs span the spaces between the trees. Watch your steps, you never know what you may meet in here. And don't get lost!" - neighbour "Deep forest" - neighbour "Tunnel" neighbour "Central woods" + neighbour "Tunnel" + exit-hook "deep-forest" define-place "Tunnel" description "A dark, musty tunnel opens up before you. Worms crawl about the @@ -259,6 +259,7 @@ description "TODO" item "Berries" neighbour "Sandy pit" + exit-hook "misty-forest" define-place "The World" description "Well, so you have dared it at last. With the 100 Acre Wood at diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/woods.atl b/ATL/Pooh/woods.atl index ce1da37..5a2ce85 100644 --- a/ATL/Pooh/woods.atl +++ b/ATL/Pooh/woods.atl @@ -104,9 +104,9 @@ their branches. Broken branches lie about on the ground and cob webs span the spaces between the trees. Watch your steps, you never know what you may meet in here. And don't get lost!" - neighbour "Deep forest" - neighbour "Tunnel" neighbour "Central woods" + neighbour "Tunnel" + exit-hook "deep-forest" define-place "Tunnel" description "A dark, musty tunnel opens up before you. Worms crawl about the @@ -259,6 +259,7 @@ description "TODO" item "Berries" neighbour "Sandy pit" + exit-hook "misty-forest" define-place "The World" description "Well, so you have dared it at last. With the 100 Acre Wood at diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index 51c6b94..c0f34b8 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -19,6 +19,7 @@ (monster NIL) (npc NIL) (spawns NIL) + (command NIL) (entry-hook "") (exit-hook "") (requires "")) ;Can be an ability or an item diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/woods.atl b/ATL/Pooh/woods.atl index ce1da37..5a2ce85 100644 --- a/ATL/Pooh/woods.atl +++ b/ATL/Pooh/woods.atl @@ -104,9 +104,9 @@ their branches. Broken branches lie about on the ground and cob webs span the spaces between the trees. Watch your steps, you never know what you may meet in here. And don't get lost!" - neighbour "Deep forest" - neighbour "Tunnel" neighbour "Central woods" + neighbour "Tunnel" + exit-hook "deep-forest" define-place "Tunnel" description "A dark, musty tunnel opens up before you. Worms crawl about the @@ -259,6 +259,7 @@ description "TODO" item "Berries" neighbour "Sandy pit" + exit-hook "misty-forest" define-place "The World" description "Well, so you have dared it at last. With the 100 Acre Wood at diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index 51c6b94..c0f34b8 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -19,6 +19,7 @@ (monster NIL) (npc NIL) (spawns NIL) + (command NIL) (entry-hook "") (exit-hook "") (requires "")) ;Can be an ability or an item diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index 439e27f..d7de231 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -60,6 +60,8 @@ (setf loaded-files (cons file-name loaded-files))) ;; check if this is a Lisp extension file (when (equalp (pathname-type file-name) "lisp") + (setf (world-extension-files *world*) + (cons file-name (world-extension-files *world*))) (load file-name) (return-from load-file)) ;; otherwise, parse the ATL file diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/woods.atl b/ATL/Pooh/woods.atl index ce1da37..5a2ce85 100644 --- a/ATL/Pooh/woods.atl +++ b/ATL/Pooh/woods.atl @@ -104,9 +104,9 @@ their branches. Broken branches lie about on the ground and cob webs span the spaces between the trees. Watch your steps, you never know what you may meet in here. And don't get lost!" - neighbour "Deep forest" - neighbour "Tunnel" neighbour "Central woods" + neighbour "Tunnel" + exit-hook "deep-forest" define-place "Tunnel" description "A dark, musty tunnel opens up before you. Worms crawl about the @@ -259,6 +259,7 @@ description "TODO" item "Berries" neighbour "Sandy pit" + exit-hook "misty-forest" define-place "The World" description "Well, so you have dared it at last. With the 100 Acre Wood at diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index 51c6b94..c0f34b8 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -19,6 +19,7 @@ (monster NIL) (npc NIL) (spawns NIL) + (command NIL) (entry-hook "") (exit-hook "") (requires "")) ;Can be an ability or an item diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index 439e27f..d7de231 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -60,6 +60,8 @@ (setf loaded-files (cons file-name loaded-files))) ;; check if this is a Lisp extension file (when (equalp (pathname-type file-name) "lisp") + (setf (world-extension-files *world*) + (cons file-name (world-extension-files *world*))) (load file-name) (return-from load-file)) ;; otherwise, parse the ATL file diff --git a/lisp/ui.lisp b/lisp/ui.lisp index 9f7442e..ff3c3c5 100644 --- a/lisp/ui.lisp +++ b/lisp/ui.lisp @@ -40,18 +40,28 @@ (format t "~&Items: ~A" (string-from-list (place-item p))) (format t "~&NPCs: ~A" (string-from-list (place-npc p))) (format t "~&Monsters: ~A" (string-from-list - (list-place-objects 'monster p)))) + (list-place-objects 'monster p))) + (when (place-command p) + (format t "~&Commands: ~A" (string-from-list (place-command p))))) (defun game-command (cmd player) "Execute a typed-in game command" (let* ((command (read-from-string cmd)) (space (position #\Space cmd)) (arg (if space (second (cut-string cmd (1+ space))) NIL)) + ;; Check default commands (cmd-fn (when (member command *commands* :test #'eq) command))) + ;; Search for place commands + (when (member cmd + (place-command (get-game-object 'place (player-place player))) + :test #'equalp) + (setf cmd-fn command)) + ;; Search for item commands (highest priority) (dolist (i (objectify-name-list 'item (player-item player))) (when (member (to-string command) (item-command i) :test #'equalp) (setf cmd-fn command) (return))) + ;; If found, execute the command (if cmd-fn (if space (funcall cmd-fn player arg) (funcall cmd-fn player)) @@ -89,7 +99,7 @@ attack - Fight a monster save - Save the game to file -Some items may provide additional commands.") +Some places and items may provide additional commands.") (format t "~A" help-text)) (defun clear (player) @@ -167,7 +177,7 @@ (format t "~&You cannot enter this place unless you have: ~A" req) (return-from goto)))) ;; Change places - (let ((hook (place-exit-hook (get-game-object 'place location)))) ;exit hook + (let ((hook (place-exit-hook (get-game-object 'place (player-place player))))) ;exit hook (unless (zerop (length hook)) (funcall (read-from-string hook) player))) (clear-screen) (debugging "~&~A is going to ~A." (player-name player) location) @@ -176,7 +186,7 @@ (let ((hook (place-entry-hook (get-game-object 'place location)))) ;entry hook (unless (zerop (length hook)) (funcall (read-from-string hook) player))) (add-player-experience player 1) - (describe-place location)) + (describe-place (player-place player))) (defun look (player &optional object-name) "Print a description of this object" diff --git a/ATL/Pooh/pooh-extensions.lisp b/ATL/Pooh/pooh-extensions.lisp index 217a1bf..507d41a 100644 --- a/ATL/Pooh/pooh-extensions.lisp +++ b/ATL/Pooh/pooh-extensions.lisp @@ -25,3 +25,37 @@ (format t "~&KANGA: Oh my dear, you look hurt! Here, let me take care of you.") (format t "~&~%Kanga bandages your wounds. You feel better.") (setf (player-health player) (player-max-health player)))) + +(let ((lost-in NIL)) + (defun lost-in-the-forest (player place prob) + "Walking through a forest, it's easy to end up going in circles..." + (when (> prob (random 100)) + ;; Make sure all neighbouring places have the is-lost hook + (dolist (p (place-neighbour (get-game-object 'place place))) + (let ((p (get-game-object 'place p))) + (when (zerop (length (place-entry-hook p))) + (set-object-attribute p 'entry-hook "is-lost")))) + ;; Set the lost-in variable to the current place + (setf lost-in place))) + + (defun is-lost (player) + "Return the player to where he started from" + (when lost-in + (format t "~&Suddenly, you are no longer sure you are walking in the right") + (format t "~&direction. Perhaps you should keep more to your left. Or to") + (format t "~&your right? The trees all look the same here...") + (format t "~&You are walking in circles!") + (read-line) + (change-player-location player lost-in) + (spawn-monsters lost-in) + (clear-screen) + (setf lost-in NIL)))) + +(defun misty-forest (player) + "A wrapper function for lost-in-the-forest for the misty forest location" + (lost-in-the-forest player "Misty forest" 67)) + +(defun deep-forest (player) + "A wrapper function for lost-in-the-forest for the deep forest location" + (lost-in-the-forest player "Deep forest" 40)) + diff --git a/ATL/Pooh/woods.atl b/ATL/Pooh/woods.atl index ce1da37..5a2ce85 100644 --- a/ATL/Pooh/woods.atl +++ b/ATL/Pooh/woods.atl @@ -104,9 +104,9 @@ their branches. Broken branches lie about on the ground and cob webs span the spaces between the trees. Watch your steps, you never know what you may meet in here. And don't get lost!" - neighbour "Deep forest" - neighbour "Tunnel" neighbour "Central woods" + neighbour "Tunnel" + exit-hook "deep-forest" define-place "Tunnel" description "A dark, musty tunnel opens up before you. Worms crawl about the @@ -259,6 +259,7 @@ description "TODO" item "Berries" neighbour "Sandy pit" + exit-hook "misty-forest" define-place "The World" description "Well, so you have dared it at last. With the 100 Acre Wood at diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index 51c6b94..c0f34b8 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -19,6 +19,7 @@ (monster NIL) (npc NIL) (spawns NIL) + (command NIL) (entry-hook "") (exit-hook "") (requires "")) ;Can be an ability or an item diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index 439e27f..d7de231 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -60,6 +60,8 @@ (setf loaded-files (cons file-name loaded-files))) ;; check if this is a Lisp extension file (when (equalp (pathname-type file-name) "lisp") + (setf (world-extension-files *world*) + (cons file-name (world-extension-files *world*))) (load file-name) (return-from load-file)) ;; otherwise, parse the ATL file diff --git a/lisp/ui.lisp b/lisp/ui.lisp index 9f7442e..ff3c3c5 100644 --- a/lisp/ui.lisp +++ b/lisp/ui.lisp @@ -40,18 +40,28 @@ (format t "~&Items: ~A" (string-from-list (place-item p))) (format t "~&NPCs: ~A" (string-from-list (place-npc p))) (format t "~&Monsters: ~A" (string-from-list - (list-place-objects 'monster p)))) + (list-place-objects 'monster p))) + (when (place-command p) + (format t "~&Commands: ~A" (string-from-list (place-command p))))) (defun game-command (cmd player) "Execute a typed-in game command" (let* ((command (read-from-string cmd)) (space (position #\Space cmd)) (arg (if space (second (cut-string cmd (1+ space))) NIL)) + ;; Check default commands (cmd-fn (when (member command *commands* :test #'eq) command))) + ;; Search for place commands + (when (member cmd + (place-command (get-game-object 'place (player-place player))) + :test #'equalp) + (setf cmd-fn command)) + ;; Search for item commands (highest priority) (dolist (i (objectify-name-list 'item (player-item player))) (when (member (to-string command) (item-command i) :test #'equalp) (setf cmd-fn command) (return))) + ;; If found, execute the command (if cmd-fn (if space (funcall cmd-fn player arg) (funcall cmd-fn player)) @@ -89,7 +99,7 @@ attack - Fight a monster save - Save the game to file -Some items may provide additional commands.") +Some places and items may provide additional commands.") (format t "~A" help-text)) (defun clear (player) @@ -167,7 +177,7 @@ (format t "~&You cannot enter this place unless you have: ~A" req) (return-from goto)))) ;; Change places - (let ((hook (place-exit-hook (get-game-object 'place location)))) ;exit hook + (let ((hook (place-exit-hook (get-game-object 'place (player-place player))))) ;exit hook (unless (zerop (length hook)) (funcall (read-from-string hook) player))) (clear-screen) (debugging "~&~A is going to ~A." (player-name player) location) @@ -176,7 +186,7 @@ (let ((hook (place-entry-hook (get-game-object 'place location)))) ;entry hook (unless (zerop (length hook)) (funcall (read-from-string hook) player))) (add-player-experience player 1) - (describe-place location)) + (describe-place (player-place player))) (defun look (player &optional object-name) "Print a description of this object" diff --git a/lisp/world.lisp b/lisp/world.lisp index 3aefaf6..0f90693 100644 --- a/lisp/world.lisp +++ b/lisp/world.lisp @@ -25,7 +25,8 @@ (npcs NIL) (items NIL) (weapons NIL) - (quests NIL)) + (quests NIL) + (extension-files NIL)) (setf *world* (make-world)) ;XXX Move this to another module? @@ -65,7 +66,9 @@ (format t "~&WARNING: The loaded game was saved by a ") (format t "different version of Atlantis!")) (if (world-p loaded-world) - (setf *world* loaded-world) + (progn (setf *world* loaded-world) + (dolist (lisp-file (world-extension-files *world*)) + (load lisp-file))) (error "World file ~A is corrupted!" game-file))))) (defun save-world (game-file)