diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/lisp/creator.lisp b/lisp/creator.lisp new file mode 100644 index 0000000..e0bb854 --- /dev/null +++ b/lisp/creator.lisp @@ -0,0 +1,56 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; This is an ATL code-generating module to ease the world creation +;;; process for non-coders (and those too lazy to write more than +;;; necessary...). +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 20/06/2015 +;;; + +(defun import-spreadsheet (spreadsheet atl-file) + "Import and convert a spreadsheet (requires LibreOffice)" + (let* ((ods-pathname (parse-namestring spreadsheet)) + (csv-pathname (make-pathname + :directory (pathname-directory ods-pathname) + :name (pathname-name ods-pathname) + :type "csv"))) + ;; Convert the spreadsheet to csv (only works with clisp!) + (ext:shell (format nil "libreoffice --headless --convert-to csv ~A~A~A" + (namestring ods-pathname) " --outdir " + (namestring (make-pathname :directory + (pathname-directory ods-pathname))))) + (csv-to-atl csv-pathname atl-file))) + +(defun csv-to-atl (csv-pathname atl-file &aux (atl-code "")) + "Convert a csv file to ATL" + (setf atl-code ";; This code has been automatically generated by the +;; Atlantis world creator.") + (do* ((csv-file (load-text-file csv-pathname)) (line-nr 2 (1+ line-nr)) + (object-type (read-from-string + (first (split-string (first csv-file) #\,)))) + (object-characteristics (split-string (second csv-file) #\,)) + (line (nth line-nr csv-file) (nth line-nr csv-file)) + (line-values (split-string line #\,) (split-string line #\,))) + ((null line) NIL) + ;; Start a new define-command + (setf atl-code (format NIL "~A~&~%~A" atl-code + (concatenate 'string "define-" + (string-downcase (to-string object-type)) + " " (first line-values)))) + ;; Enter the value for each characteristic + (dotimes (i (1- (length object-characteristics))) + (setf atl-code (format NIL "~A~&~A" atl-code + (concatenate 'string (to-string #\tab) + (nth (1+ i) object-characteristics) " " + (nth (1+ i) line-values)))))) + ;; Write the generated code to file + (with-open-file (atl atl-file :direction :output) + (format atl "~A" atl-code))) + +(defun world-creator () + "The UI for the functions in this module" + (format t "~&Sorry, not yet available!")) diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/lisp/creator.lisp b/lisp/creator.lisp new file mode 100644 index 0000000..e0bb854 --- /dev/null +++ b/lisp/creator.lisp @@ -0,0 +1,56 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; This is an ATL code-generating module to ease the world creation +;;; process for non-coders (and those too lazy to write more than +;;; necessary...). +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 20/06/2015 +;;; + +(defun import-spreadsheet (spreadsheet atl-file) + "Import and convert a spreadsheet (requires LibreOffice)" + (let* ((ods-pathname (parse-namestring spreadsheet)) + (csv-pathname (make-pathname + :directory (pathname-directory ods-pathname) + :name (pathname-name ods-pathname) + :type "csv"))) + ;; Convert the spreadsheet to csv (only works with clisp!) + (ext:shell (format nil "libreoffice --headless --convert-to csv ~A~A~A" + (namestring ods-pathname) " --outdir " + (namestring (make-pathname :directory + (pathname-directory ods-pathname))))) + (csv-to-atl csv-pathname atl-file))) + +(defun csv-to-atl (csv-pathname atl-file &aux (atl-code "")) + "Convert a csv file to ATL" + (setf atl-code ";; This code has been automatically generated by the +;; Atlantis world creator.") + (do* ((csv-file (load-text-file csv-pathname)) (line-nr 2 (1+ line-nr)) + (object-type (read-from-string + (first (split-string (first csv-file) #\,)))) + (object-characteristics (split-string (second csv-file) #\,)) + (line (nth line-nr csv-file) (nth line-nr csv-file)) + (line-values (split-string line #\,) (split-string line #\,))) + ((null line) NIL) + ;; Start a new define-command + (setf atl-code (format NIL "~A~&~%~A" atl-code + (concatenate 'string "define-" + (string-downcase (to-string object-type)) + " " (first line-values)))) + ;; Enter the value for each characteristic + (dotimes (i (1- (length object-characteristics))) + (setf atl-code (format NIL "~A~&~A" atl-code + (concatenate 'string (to-string #\tab) + (nth (1+ i) object-characteristics) " " + (nth (1+ i) line-values)))))) + ;; Write the generated code to file + (with-open-file (atl atl-file :direction :output) + (format atl "~A" atl-code))) + +(defun world-creator () + "The UI for the functions in this module" + (format t "~&Sorry, not yet available!")) diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index c2f6917..47e400c 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -38,6 +38,7 @@ (defstruct item (name "") (description "") + (cost 0) (weapon "no") (function NIL)) diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/lisp/creator.lisp b/lisp/creator.lisp new file mode 100644 index 0000000..e0bb854 --- /dev/null +++ b/lisp/creator.lisp @@ -0,0 +1,56 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; This is an ATL code-generating module to ease the world creation +;;; process for non-coders (and those too lazy to write more than +;;; necessary...). +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 20/06/2015 +;;; + +(defun import-spreadsheet (spreadsheet atl-file) + "Import and convert a spreadsheet (requires LibreOffice)" + (let* ((ods-pathname (parse-namestring spreadsheet)) + (csv-pathname (make-pathname + :directory (pathname-directory ods-pathname) + :name (pathname-name ods-pathname) + :type "csv"))) + ;; Convert the spreadsheet to csv (only works with clisp!) + (ext:shell (format nil "libreoffice --headless --convert-to csv ~A~A~A" + (namestring ods-pathname) " --outdir " + (namestring (make-pathname :directory + (pathname-directory ods-pathname))))) + (csv-to-atl csv-pathname atl-file))) + +(defun csv-to-atl (csv-pathname atl-file &aux (atl-code "")) + "Convert a csv file to ATL" + (setf atl-code ";; This code has been automatically generated by the +;; Atlantis world creator.") + (do* ((csv-file (load-text-file csv-pathname)) (line-nr 2 (1+ line-nr)) + (object-type (read-from-string + (first (split-string (first csv-file) #\,)))) + (object-characteristics (split-string (second csv-file) #\,)) + (line (nth line-nr csv-file) (nth line-nr csv-file)) + (line-values (split-string line #\,) (split-string line #\,))) + ((null line) NIL) + ;; Start a new define-command + (setf atl-code (format NIL "~A~&~%~A" atl-code + (concatenate 'string "define-" + (string-downcase (to-string object-type)) + " " (first line-values)))) + ;; Enter the value for each characteristic + (dotimes (i (1- (length object-characteristics))) + (setf atl-code (format NIL "~A~&~A" atl-code + (concatenate 'string (to-string #\tab) + (nth (1+ i) object-characteristics) " " + (nth (1+ i) line-values)))))) + ;; Write the generated code to file + (with-open-file (atl atl-file :direction :output) + (format atl "~A" atl-code))) + +(defun world-creator () + "The UI for the functions in this module" + (format t "~&Sorry, not yet available!")) diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index c2f6917..47e400c 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -38,6 +38,7 @@ (defstruct item (name "") (description "") + (cost 0) (weapon "no") (function NIL)) diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index dbb06af..f5d5656 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -9,6 +9,10 @@ ;;; date: 09/05/2015 ;;; +;; A list of ATL language constructs +;; (Note: not complete - each (defcommand) appends to this list) +(defvar *atl-commands* + '(load-file start-place name-world)) (defun build-define-command (object-type) "Build a new define command function for the specified object type" @@ -18,6 +22,8 @@ (funcall (build-symbol "make-" object-type) :name name))) (defmacro defcommand (command-name object-type) + ;; XXX Macros should not have side-effects? + (setf *atl-commands* (cons command-name *atl-commands*)) `(defun ,command-name (name) (funcall ,(build-define-command object-type) name))) @@ -76,13 +82,15 @@ ((not (or (eql (aref line 0) #\;) (eql (aref line 0) #\SPACE) (eql (aref line 0) #\TAB))) - ;; TODO Catch syntax errors - (setf current-object (funcall (symbol-function - (read-from-string line)) - ;; this is a kludge to work around a clisp bug (not - ;; recognizing the :start keyword in read-from-string) - (read-from-string (second - (cut-string line (position #\space line))))))) + (let ((def-cmd (read-from-string line))) + (if (member def-cmd *atl-commands*) + (setf current-object + (funcall def-cmd + ;; clisp doesn't recognize the :start + ;; keyword in read-from-string + (read-from-string (second (cut-string line + (position #\space line)))))) + (error "~&ERROR: unrecognized syntax: '~A'" line)))) ;; interpret an option command ((or (eql (aref line 0) #\Space) (eql (aref line 0) #\Tab)) @@ -90,6 +98,6 @@ (set-object-attribute current-object (read-from-string line) (read-from-string (second (cut-string line (position #\space line)))))) - (T (error "~&ERROR: unrecognized syntax on line ~A: '~A'" - ;; can't happen - (1+ line-nr) line)))))) + (T ;; can't happen + (error "~&ERROR: unrecognized syntax: '~A'" line)))))) + diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/lisp/creator.lisp b/lisp/creator.lisp new file mode 100644 index 0000000..e0bb854 --- /dev/null +++ b/lisp/creator.lisp @@ -0,0 +1,56 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; This is an ATL code-generating module to ease the world creation +;;; process for non-coders (and those too lazy to write more than +;;; necessary...). +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 20/06/2015 +;;; + +(defun import-spreadsheet (spreadsheet atl-file) + "Import and convert a spreadsheet (requires LibreOffice)" + (let* ((ods-pathname (parse-namestring spreadsheet)) + (csv-pathname (make-pathname + :directory (pathname-directory ods-pathname) + :name (pathname-name ods-pathname) + :type "csv"))) + ;; Convert the spreadsheet to csv (only works with clisp!) + (ext:shell (format nil "libreoffice --headless --convert-to csv ~A~A~A" + (namestring ods-pathname) " --outdir " + (namestring (make-pathname :directory + (pathname-directory ods-pathname))))) + (csv-to-atl csv-pathname atl-file))) + +(defun csv-to-atl (csv-pathname atl-file &aux (atl-code "")) + "Convert a csv file to ATL" + (setf atl-code ";; This code has been automatically generated by the +;; Atlantis world creator.") + (do* ((csv-file (load-text-file csv-pathname)) (line-nr 2 (1+ line-nr)) + (object-type (read-from-string + (first (split-string (first csv-file) #\,)))) + (object-characteristics (split-string (second csv-file) #\,)) + (line (nth line-nr csv-file) (nth line-nr csv-file)) + (line-values (split-string line #\,) (split-string line #\,))) + ((null line) NIL) + ;; Start a new define-command + (setf atl-code (format NIL "~A~&~%~A" atl-code + (concatenate 'string "define-" + (string-downcase (to-string object-type)) + " " (first line-values)))) + ;; Enter the value for each characteristic + (dotimes (i (1- (length object-characteristics))) + (setf atl-code (format NIL "~A~&~A" atl-code + (concatenate 'string (to-string #\tab) + (nth (1+ i) object-characteristics) " " + (nth (1+ i) line-values)))))) + ;; Write the generated code to file + (with-open-file (atl atl-file :direction :output) + (format atl "~A" atl-code))) + +(defun world-creator () + "The UI for the functions in this module" + (format t "~&Sorry, not yet available!")) diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index c2f6917..47e400c 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -38,6 +38,7 @@ (defstruct item (name "") (description "") + (cost 0) (weapon "no") (function NIL)) diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index dbb06af..f5d5656 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -9,6 +9,10 @@ ;;; date: 09/05/2015 ;;; +;; A list of ATL language constructs +;; (Note: not complete - each (defcommand) appends to this list) +(defvar *atl-commands* + '(load-file start-place name-world)) (defun build-define-command (object-type) "Build a new define command function for the specified object type" @@ -18,6 +22,8 @@ (funcall (build-symbol "make-" object-type) :name name))) (defmacro defcommand (command-name object-type) + ;; XXX Macros should not have side-effects? + (setf *atl-commands* (cons command-name *atl-commands*)) `(defun ,command-name (name) (funcall ,(build-define-command object-type) name))) @@ -76,13 +82,15 @@ ((not (or (eql (aref line 0) #\;) (eql (aref line 0) #\SPACE) (eql (aref line 0) #\TAB))) - ;; TODO Catch syntax errors - (setf current-object (funcall (symbol-function - (read-from-string line)) - ;; this is a kludge to work around a clisp bug (not - ;; recognizing the :start keyword in read-from-string) - (read-from-string (second - (cut-string line (position #\space line))))))) + (let ((def-cmd (read-from-string line))) + (if (member def-cmd *atl-commands*) + (setf current-object + (funcall def-cmd + ;; clisp doesn't recognize the :start + ;; keyword in read-from-string + (read-from-string (second (cut-string line + (position #\space line)))))) + (error "~&ERROR: unrecognized syntax: '~A'" line)))) ;; interpret an option command ((or (eql (aref line 0) #\Space) (eql (aref line 0) #\Tab)) @@ -90,6 +98,6 @@ (set-object-attribute current-object (read-from-string line) (read-from-string (second (cut-string line (position #\space line)))))) - (T (error "~&ERROR: unrecognized syntax on line ~A: '~A'" - ;; can't happen - (1+ line-nr) line)))))) + (T ;; can't happen + (error "~&ERROR: unrecognized syntax: '~A'" line)))))) + diff --git a/lisp/ui.lisp b/lisp/ui.lisp index 509d606..f8cb7cf 100644 --- a/lisp/ui.lisp +++ b/lisp/ui.lisp @@ -115,7 +115,7 @@ (defvar *commands* '(help place player goto pickup drop talk - weapon fight shoot + equip fight shoot about save clear)) ;;; The following commands don't take any arguments except for a player @@ -134,22 +134,23 @@ talk - Talk to an NPC pickup - Pick up an item lying around drop - Drop the item +equip - Equip this item as your weapon shoot - Take a shot at a monster fight - Fight a monster save - Save the game to file") (format t "~A" help-text)) +(defun clear (player) + "Clear the screen (wrapper function)" + (clear-screen) + (place player)) + ;; XXX Will the following two functions give problems? (Their name is ;; identical with the struct name) Probably not, but best to be aware. (defun place (player) "Describe the player's current location (wrapper function)" (describe-place (player-place player))) -(defun clear (player) - "Clear the screen (wrapper function)" - (clear-screen) - (place player)) - (defun player (p) "Print a description of this player" (let ((tab (string #\tab))) @@ -214,37 +215,25 @@ (unless object-name (format t "~&Please specify the object you wish to inspect!") (return-from about)) - ;; TODO There's got to be a more elegant way of doing this... + ;; TODO What about objects that the player is carrying? + ;; And there's probably a more elegant way of doing this... (let ((place (get-game-object 'place (player-place player))) (description NIL)) - (macrolet ((set-descr (place-object place-description object-type) - `(when (member object-name (,place-object place) - :test #'equalp) - (setf description (,place-description - (get-game-object - ',object-type - object-name)))))) - (set-descr place-item item-description item) - (set-descr place-monster monster-description monster) - (set-descr place-npc npc-description npc)) + (macrolet ((set-descr (type) + (let ((place-descr (build-symbol type "-description")) + (place-object (build-symbol "place-" type))) + `(when (member object-name (,place-object place) + :test #'equalp) + (setf description (,place-descr + (get-game-object ',type + object-name))))))) + (set-descr item) + (set-descr monster) + (set-descr npc)) (if description (format t "~&(~A) ~A" object-name description) (format t "~&Could not find ~A!" object-name)))) - - ;; (cond ((member object-name (place-item place)) - ;; (setf description (item-description - ;; (get-game-object 'item object-name)))) - ;; ((member object-name (place-monster place)) - ;; (setf description (monster-description - ;; (get-game-object 'monster object-name)))) - ;; ((member object-name (place-monster place)) - ;; (setf description (monster-description - ;; (get-game-object 'monster object-name)))) - ;; (t (format t "~&Could not find ~A!" object-name) - ;; (return-from about))) - ;; (format t "~&~A" description))) - (defun talk (player &optional npc-name) "Talk to the desired NPC" ;; TODO Add interactive facility @@ -289,7 +278,7 @@ (format t "~&You have dropped: ~A" item)) (format t "~&You do not possess this item!"))) -(defun weapon (player &optional new-weapon) +(defun equip (player &optional new-weapon) "The player sets another item to be his weapon" (when (or (not new-weapon) (equalp new-weapon "none")) (setf (player-weapon player) "") diff --git a/ATL/ATL-item-conversion.ods b/ATL/ATL-item-conversion.ods new file mode 100644 index 0000000..a5442c2 --- /dev/null +++ b/ATL/ATL-item-conversion.ods Binary files differ diff --git a/ATL/creator-test.atl b/ATL/creator-test.atl new file mode 100644 index 0000000..fa40b88 --- /dev/null +++ b/ATL/creator-test.atl @@ -0,0 +1,185 @@ +;; This code has been automatically generated by the +;; Atlantis world creator. + +define-item Rope (20m) + cost 5 + +define-item Backpack + cost 5 + +define-item Knife + cost 10 + +define-item Short sword + cost 40 + +define-item Long sword + cost 80 + +define-item Dagger + cost 20 + +define-item Spear + cost 25 + +define-item Short bow + cost 30 + +define-item Longbow + cost 60 + +define-item Slingshot + cost 15 + +define-item Throwing knife + cost 15 + +define-item Quiver of arrows + cost 20 + +define-item Leather armour + cost 60 + +define-item Chain mail + cost 120 + +define-item Plate armour + cost 200 + +define-item Buckler + cost 35 + +define-item Full shield + cost 45 + +define-item Candles (3x) + cost 5 + +define-item Matches + cost 1 + +define-item Food rations (5x) + cost 10 + +define-item Grappling hook + cost 15 + +define-item Fishing net + cost 25 + +define-item Fishing rod + cost 15 + +define-item Tent (2 people) + cost 30 + +define-item Cloak + cost 15 + +define-item Hat + cost 10 + +define-item Water bottle + cost 5 + +define-item Compass + cost 20 + +define-item Quill and ink + cost 5 + +define-item Parchment + cost 5 + +define-item Blanket + cost 5 + +define-item Book of Legends + cost 55 + +define-item Book of Lore + cost 55 + +define-item Medicinal herbs + cost 10 + +define-item Bandages (3x) + cost 5 + +define-item Tea leaves + cost 5 + +define-item Sleeping potion + cost 15 + +define-item Leather pouch + cost 2 + +define-item Face mask + cost 10 + +define-item Dye + cost 5 + +define-item Cloth + cost 5 + +define-item Scissors + cost 15 + +define-item Needle and thread + cost 3 + +define-item Canvas + cost 8 + +define-item String + cost 2 + +define-item Hatchet + cost 20 + +define-item Map + cost 35 + +define-item Pony + cost 100 + +define-item Horse + cost 180 + +define-item Saddle and bridle + cost 45 + +define-item Saddlebag + cost 35 + +define-item Handmirror + cost 20 + +define-item Magnifying glass + cost 20 + +define-item Telescope + cost 40 + +define-item Rope ladder + cost 15 + +define-item Torches (3x) + cost 10 + +define-item Staff + cost 10 + +define-item Cooking pot + cost 8 + +define-item Soap + cost 2 + +define-item Towel + cost 5 + +define-item Boots + cost 10 \ No newline at end of file diff --git a/ATL/lisp-test.atl b/ATL/lisp-test.atl index 7ec9840..5687b44 100644 --- a/ATL/lisp-test.atl +++ b/ATL/lisp-test.atl @@ -1,4 +1,4 @@ -; This is a simple test ATL file to test whatever I have implemented so far. +; This is a simple ATL file to test whatever I have implemented so far. ; @author Daniel Vedder ; @date 04/05/2015 @@ -24,7 +24,7 @@ monster "Fury" define-place "Fields of Asphodel" - description "Nothing special. Really, nothing special at all. + description "Nothing special. Really, nothing special at all. Just a whole load of dead people..." neighbour "Fields of Punishment" neighbour "Elysium" @@ -41,5 +41,6 @@ load-file lisp-test.atl ;Testing whether recursive loading is prevented load-file races-classes.atl load-file game-objects.atl +load-file creator-test.atl -start-place "Nowhere" \ No newline at end of file +start-place "Styx" \ No newline at end of file diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index d16bccc..2d248a4 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -7,7 +7,7 @@ ;;; date: 09/05/2015 ;;; -(defconstant ATLANTIS-VERSION '(0 1 2)) +(defconstant ATLANTIS-VERSION '(0 1 3)) (load "util.lisp") (load "game-objects.lisp") @@ -15,7 +15,7 @@ (load "world.lisp") (load "interpreter.lisp") (load "ui.lisp") - +(load "creator.lisp") (defvar *debugging* NIL) @@ -34,6 +34,13 @@ 'player (player-name player)) (play-game (player-name player)))) +(defun not-available () + "Before I tackle networking..." + (format t "~&Sorry, multiplayer is currently not supported!") + (format t "~&Please press ENTER") + (y-or-n-p "~&OK?") + (start-menu)) + (defun start-server () "Start a new game on a server" ;; TODO Doesn't actually start a server yet @@ -96,17 +103,18 @@ (print-text-file "banner.txt") (format t "~&~%Welcome! What do you want to do?") (setf options '("Start a server" "Join a game" "Play single-player" - "Develop" "About" "Exit")) + "Create worlds" "Develop" "About" "Exit")) (case (choose-number-option options) - (0 (start-server)) - (1 (join-game)) + (0 (not-available)) + (1 (not-available)) (2 (single-player)) - (3 (development)) - (4 (print-version) + (3 (world-creator)) + (4 (development)) + (5 (print-version) (when (y-or-n-p "Show the license text?") (print-text-file "../LICENSE")) (start-menu)) - (5 (format t "~&Goodbye!") + (6 (format t "~&Goodbye!") (quit)))) (defun cmd-parameter (name &optional truth-value) diff --git a/lisp/creator.lisp b/lisp/creator.lisp new file mode 100644 index 0000000..e0bb854 --- /dev/null +++ b/lisp/creator.lisp @@ -0,0 +1,56 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; This is an ATL code-generating module to ease the world creation +;;; process for non-coders (and those too lazy to write more than +;;; necessary...). +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 20/06/2015 +;;; + +(defun import-spreadsheet (spreadsheet atl-file) + "Import and convert a spreadsheet (requires LibreOffice)" + (let* ((ods-pathname (parse-namestring spreadsheet)) + (csv-pathname (make-pathname + :directory (pathname-directory ods-pathname) + :name (pathname-name ods-pathname) + :type "csv"))) + ;; Convert the spreadsheet to csv (only works with clisp!) + (ext:shell (format nil "libreoffice --headless --convert-to csv ~A~A~A" + (namestring ods-pathname) " --outdir " + (namestring (make-pathname :directory + (pathname-directory ods-pathname))))) + (csv-to-atl csv-pathname atl-file))) + +(defun csv-to-atl (csv-pathname atl-file &aux (atl-code "")) + "Convert a csv file to ATL" + (setf atl-code ";; This code has been automatically generated by the +;; Atlantis world creator.") + (do* ((csv-file (load-text-file csv-pathname)) (line-nr 2 (1+ line-nr)) + (object-type (read-from-string + (first (split-string (first csv-file) #\,)))) + (object-characteristics (split-string (second csv-file) #\,)) + (line (nth line-nr csv-file) (nth line-nr csv-file)) + (line-values (split-string line #\,) (split-string line #\,))) + ((null line) NIL) + ;; Start a new define-command + (setf atl-code (format NIL "~A~&~%~A" atl-code + (concatenate 'string "define-" + (string-downcase (to-string object-type)) + " " (first line-values)))) + ;; Enter the value for each characteristic + (dotimes (i (1- (length object-characteristics))) + (setf atl-code (format NIL "~A~&~A" atl-code + (concatenate 'string (to-string #\tab) + (nth (1+ i) object-characteristics) " " + (nth (1+ i) line-values)))))) + ;; Write the generated code to file + (with-open-file (atl atl-file :direction :output) + (format atl "~A" atl-code))) + +(defun world-creator () + "The UI for the functions in this module" + (format t "~&Sorry, not yet available!")) diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index c2f6917..47e400c 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -38,6 +38,7 @@ (defstruct item (name "") (description "") + (cost 0) (weapon "no") (function NIL)) diff --git a/lisp/interpreter.lisp b/lisp/interpreter.lisp index dbb06af..f5d5656 100644 --- a/lisp/interpreter.lisp +++ b/lisp/interpreter.lisp @@ -9,6 +9,10 @@ ;;; date: 09/05/2015 ;;; +;; A list of ATL language constructs +;; (Note: not complete - each (defcommand) appends to this list) +(defvar *atl-commands* + '(load-file start-place name-world)) (defun build-define-command (object-type) "Build a new define command function for the specified object type" @@ -18,6 +22,8 @@ (funcall (build-symbol "make-" object-type) :name name))) (defmacro defcommand (command-name object-type) + ;; XXX Macros should not have side-effects? + (setf *atl-commands* (cons command-name *atl-commands*)) `(defun ,command-name (name) (funcall ,(build-define-command object-type) name))) @@ -76,13 +82,15 @@ ((not (or (eql (aref line 0) #\;) (eql (aref line 0) #\SPACE) (eql (aref line 0) #\TAB))) - ;; TODO Catch syntax errors - (setf current-object (funcall (symbol-function - (read-from-string line)) - ;; this is a kludge to work around a clisp bug (not - ;; recognizing the :start keyword in read-from-string) - (read-from-string (second - (cut-string line (position #\space line))))))) + (let ((def-cmd (read-from-string line))) + (if (member def-cmd *atl-commands*) + (setf current-object + (funcall def-cmd + ;; clisp doesn't recognize the :start + ;; keyword in read-from-string + (read-from-string (second (cut-string line + (position #\space line)))))) + (error "~&ERROR: unrecognized syntax: '~A'" line)))) ;; interpret an option command ((or (eql (aref line 0) #\Space) (eql (aref line 0) #\Tab)) @@ -90,6 +98,6 @@ (set-object-attribute current-object (read-from-string line) (read-from-string (second (cut-string line (position #\space line)))))) - (T (error "~&ERROR: unrecognized syntax on line ~A: '~A'" - ;; can't happen - (1+ line-nr) line)))))) + (T ;; can't happen + (error "~&ERROR: unrecognized syntax: '~A'" line)))))) + diff --git a/lisp/ui.lisp b/lisp/ui.lisp index 509d606..f8cb7cf 100644 --- a/lisp/ui.lisp +++ b/lisp/ui.lisp @@ -115,7 +115,7 @@ (defvar *commands* '(help place player goto pickup drop talk - weapon fight shoot + equip fight shoot about save clear)) ;;; The following commands don't take any arguments except for a player @@ -134,22 +134,23 @@ talk - Talk to an NPC pickup - Pick up an item lying around drop - Drop the item +equip - Equip this item as your weapon shoot - Take a shot at a monster fight - Fight a monster save - Save the game to file") (format t "~A" help-text)) +(defun clear (player) + "Clear the screen (wrapper function)" + (clear-screen) + (place player)) + ;; XXX Will the following two functions give problems? (Their name is ;; identical with the struct name) Probably not, but best to be aware. (defun place (player) "Describe the player's current location (wrapper function)" (describe-place (player-place player))) -(defun clear (player) - "Clear the screen (wrapper function)" - (clear-screen) - (place player)) - (defun player (p) "Print a description of this player" (let ((tab (string #\tab))) @@ -214,37 +215,25 @@ (unless object-name (format t "~&Please specify the object you wish to inspect!") (return-from about)) - ;; TODO There's got to be a more elegant way of doing this... + ;; TODO What about objects that the player is carrying? + ;; And there's probably a more elegant way of doing this... (let ((place (get-game-object 'place (player-place player))) (description NIL)) - (macrolet ((set-descr (place-object place-description object-type) - `(when (member object-name (,place-object place) - :test #'equalp) - (setf description (,place-description - (get-game-object - ',object-type - object-name)))))) - (set-descr place-item item-description item) - (set-descr place-monster monster-description monster) - (set-descr place-npc npc-description npc)) + (macrolet ((set-descr (type) + (let ((place-descr (build-symbol type "-description")) + (place-object (build-symbol "place-" type))) + `(when (member object-name (,place-object place) + :test #'equalp) + (setf description (,place-descr + (get-game-object ',type + object-name))))))) + (set-descr item) + (set-descr monster) + (set-descr npc)) (if description (format t "~&(~A) ~A" object-name description) (format t "~&Could not find ~A!" object-name)))) - - ;; (cond ((member object-name (place-item place)) - ;; (setf description (item-description - ;; (get-game-object 'item object-name)))) - ;; ((member object-name (place-monster place)) - ;; (setf description (monster-description - ;; (get-game-object 'monster object-name)))) - ;; ((member object-name (place-monster place)) - ;; (setf description (monster-description - ;; (get-game-object 'monster object-name)))) - ;; (t (format t "~&Could not find ~A!" object-name) - ;; (return-from about))) - ;; (format t "~&~A" description))) - (defun talk (player &optional npc-name) "Talk to the desired NPC" ;; TODO Add interactive facility @@ -289,7 +278,7 @@ (format t "~&You have dropped: ~A" item)) (format t "~&You do not possess this item!"))) -(defun weapon (player &optional new-weapon) +(defun equip (player &optional new-weapon) "The player sets another item to be his weapon" (when (or (not new-weapon) (equalp new-weapon "none")) (setf (player-weapon player) "") diff --git a/lisp/util.lisp b/lisp/util.lisp index 7ea5102..4437124 100644 --- a/lisp/util.lisp +++ b/lisp/util.lisp @@ -120,6 +120,15 @@ (T (concatenate 'string (to-string (first lst)) (to-string separator) (string-from-list (cdr lst) separator))))) +(defun split-string (str separator) + "Split the string up into a list of strings along the separator character" + (cond ((equalp str (to-string separator)) NIL) + ((zerop (count-instances separator str)) (list str)) + (T (let ((split-elt (cut-string str (position separator str)))) + (cons (first split-elt) + (split-string (second (cut-string (second split-elt) 1)) + separator)))))) + (defun cut-string (s i) "Cut string s in two at index i and return the two substrings in a list" (do* ((c 0 (1+ c)) (letter (aref s c) (aref s c))