diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/client.lisp b/lisp/client.lisp new file mode 100644 index 0000000..3e56313 --- /dev/null +++ b/lisp/client.lisp @@ -0,0 +1,31 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; The client module is responsible for the actual user interface presented +;;; to a player. (Warning: this will likely change significantly, currently +;;; I am only implementing a mock-up before I get the networking part working.) +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 09/05/2015 +;;; + +(let ((player NIL)) + (defun play-game (&optional player-name) + "The main game loop" + ;; Initialize the player if necessary + (when (null player) + (if player-name + (setf player (get-game-object 'player player-name)) + (error "~&No player name specified!"))) + (when (null player) + (create-player player-name)))) + +(defun create-player (player-name) + "The user creates a new player" + (let ((race NIL) (class NIL) + (strength 0) (dexterity 0) + (constitution 0) (intelligence 0) + (items NIL) (weapons NIL) (character-points NIL)) + )) ;; TODO diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/client.lisp b/lisp/client.lisp new file mode 100644 index 0000000..3e56313 --- /dev/null +++ b/lisp/client.lisp @@ -0,0 +1,31 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; The client module is responsible for the actual user interface presented +;;; to a player. (Warning: this will likely change significantly, currently +;;; I am only implementing a mock-up before I get the networking part working.) +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 09/05/2015 +;;; + +(let ((player NIL)) + (defun play-game (&optional player-name) + "The main game loop" + ;; Initialize the player if necessary + (when (null player) + (if player-name + (setf player (get-game-object 'player player-name)) + (error "~&No player name specified!"))) + (when (null player) + (create-player player-name)))) + +(defun create-player (player-name) + "The user creates a new player" + (let ((race NIL) (class NIL) + (strength 0) (dexterity 0) + (constitution 0) (intelligence 0) + (items NIL) (weapons NIL) (character-points NIL)) + )) ;; TODO diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index b71a1a3..959a76b 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -39,13 +39,10 @@ (defun set-object-attribute (game-object property value) "Set the attribute 'property' of 'game-object' to 'value'" ;; Here follows Lisp magic :D (that took ages to get right...) + ;; [And half the magic is gone after being outsourced to build-symbol :-(] ;; I'm not sure how elegant it is to call (eval) explicitly, but in this ;; case I couldn't avoid it - I needed a mix between a macro and a function - (let ((command (read-from-string - (concatenate 'string - (symbol-name (type-of game-object)) - "-" (if (stringp property) property - (symbol-name property)))))) + (let ((command (build-symbol (type-of game-object) "-" property))) ;; XXX This following section is rather ugly... (eval `(if (or (null (,command ,game-object)) (listp (,command ,game-object))) diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/client.lisp b/lisp/client.lisp new file mode 100644 index 0000000..3e56313 --- /dev/null +++ b/lisp/client.lisp @@ -0,0 +1,31 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; The client module is responsible for the actual user interface presented +;;; to a player. (Warning: this will likely change significantly, currently +;;; I am only implementing a mock-up before I get the networking part working.) +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 09/05/2015 +;;; + +(let ((player NIL)) + (defun play-game (&optional player-name) + "The main game loop" + ;; Initialize the player if necessary + (when (null player) + (if player-name + (setf player (get-game-object 'player player-name)) + (error "~&No player name specified!"))) + (when (null player) + (create-player player-name)))) + +(defun create-player (player-name) + "The user creates a new player" + (let ((race NIL) (class NIL) + (strength 0) (dexterity 0) + (constitution 0) (intelligence 0) + (items NIL) (weapons NIL) (character-points NIL)) + )) ;; TODO diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index b71a1a3..959a76b 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -39,13 +39,10 @@ (defun set-object-attribute (game-object property value) "Set the attribute 'property' of 'game-object' to 'value'" ;; Here follows Lisp magic :D (that took ages to get right...) + ;; [And half the magic is gone after being outsourced to build-symbol :-(] ;; I'm not sure how elegant it is to call (eval) explicitly, but in this ;; case I couldn't avoid it - I needed a mix between a macro and a function - (let ((command (read-from-string - (concatenate 'string - (symbol-name (type-of game-object)) - "-" (if (stringp property) property - (symbol-name property)))))) + (let ((command (build-symbol (type-of game-object) "-" property))) ;; XXX This following section is rather ugly... (eval `(if (or (null (,command ,game-object)) (listp (,command ,game-object))) diff --git a/lisp/player.lisp b/lisp/player.lisp index 03f2333..c0c3e9c 100644 --- a/lisp/player.lisp +++ b/lisp/player.lisp @@ -19,7 +19,7 @@ (intelligence 0) (items NIL) (weapons NIL) - (place)) + (place "")) (defstruct race diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/client.lisp b/lisp/client.lisp new file mode 100644 index 0000000..3e56313 --- /dev/null +++ b/lisp/client.lisp @@ -0,0 +1,31 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; The client module is responsible for the actual user interface presented +;;; to a player. (Warning: this will likely change significantly, currently +;;; I am only implementing a mock-up before I get the networking part working.) +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 09/05/2015 +;;; + +(let ((player NIL)) + (defun play-game (&optional player-name) + "The main game loop" + ;; Initialize the player if necessary + (when (null player) + (if player-name + (setf player (get-game-object 'player player-name)) + (error "~&No player name specified!"))) + (when (null player) + (create-player player-name)))) + +(defun create-player (player-name) + "The user creates a new player" + (let ((race NIL) (class NIL) + (strength 0) (dexterity 0) + (constitution 0) (intelligence 0) + (items NIL) (weapons NIL) (character-points NIL)) + )) ;; TODO diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index b71a1a3..959a76b 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -39,13 +39,10 @@ (defun set-object-attribute (game-object property value) "Set the attribute 'property' of 'game-object' to 'value'" ;; Here follows Lisp magic :D (that took ages to get right...) + ;; [And half the magic is gone after being outsourced to build-symbol :-(] ;; I'm not sure how elegant it is to call (eval) explicitly, but in this ;; case I couldn't avoid it - I needed a mix between a macro and a function - (let ((command (read-from-string - (concatenate 'string - (symbol-name (type-of game-object)) - "-" (if (stringp property) property - (symbol-name property)))))) + (let ((command (build-symbol (type-of game-object) "-" property))) ;; XXX This following section is rather ugly... (eval `(if (or (null (,command ,game-object)) (listp (,command ,game-object))) diff --git a/lisp/player.lisp b/lisp/player.lisp index 03f2333..c0c3e9c 100644 --- a/lisp/player.lisp +++ b/lisp/player.lisp @@ -19,7 +19,7 @@ (intelligence 0) (items NIL) (weapons NIL) - (place)) + (place "")) (defstruct race diff --git a/lisp/util.lisp b/lisp/util.lisp index e5434a8..03f8092 100644 --- a/lisp/util.lisp +++ b/lisp/util.lisp @@ -86,6 +86,11 @@ ((= ,index (length ,vector)) ,return-variable) ,@body))) +;; TODO ? +;; (defmacro call-function (function-name &rest args) +;; "Save myself some quoting when calling a function from a generated symbol" +;; `(eval + ;;; FUNCTIONS @@ -140,3 +145,12 @@ (file-lines (list line) (append file-lines (list line)))) ((null line) file-lines)))) +(defun build-symbol (&rest components) + "Concatenate the passed components into a single symbol" + ;; A very useful function illustrating the power of Lisp :-) + (let ((comps components)) + (dotimes (i (length comps)) + (when (symbolp (nth i comps)) + (setf (nth i comps) (symbol-name (nth i comps))))) + (eval `(read-from-string (concatenate 'string ,@comps))))) + diff --git a/lisp/atlantis.lisp b/lisp/atlantis.lisp index 288cd46..74fbeaa 100644 --- a/lisp/atlantis.lisp +++ b/lisp/atlantis.lisp @@ -11,6 +11,7 @@ (load 'util.lisp) (load 'interpreter.lisp) +;(load 'client.lisp) (defun start-server () @@ -33,7 +34,10 @@ (format t "~&What port does the game run on?") (while (not (numberp (input port))) (format t "~&Not a number: ~A. Please reenter:" port)) - (format t "~&Joining game on ~A:~A" ip port)) + (format t "~&What is your player name?") + (input-string name) + (format t "~&Joining game on ~A:~A as ~A" ip port name) + (play-game name)) (defun print-version () diff --git a/lisp/client.lisp b/lisp/client.lisp new file mode 100644 index 0000000..3e56313 --- /dev/null +++ b/lisp/client.lisp @@ -0,0 +1,31 @@ +;;; +;;; Atlantis is a framework for creating multi-user dungeon worlds. +;;; This is the Common Lisp implementation. +;;; +;;; The client module is responsible for the actual user interface presented +;;; to a player. (Warning: this will likely change significantly, currently +;;; I am only implementing a mock-up before I get the networking part working.) +;;; +;;; Licensed under the terms of the MIT license. +;;; author: Daniel Vedder +;;; date: 09/05/2015 +;;; + +(let ((player NIL)) + (defun play-game (&optional player-name) + "The main game loop" + ;; Initialize the player if necessary + (when (null player) + (if player-name + (setf player (get-game-object 'player player-name)) + (error "~&No player name specified!"))) + (when (null player) + (create-player player-name)))) + +(defun create-player (player-name) + "The user creates a new player" + (let ((race NIL) (class NIL) + (strength 0) (dexterity 0) + (constitution 0) (intelligence 0) + (items NIL) (weapons NIL) (character-points NIL)) + )) ;; TODO diff --git a/lisp/game-objects.lisp b/lisp/game-objects.lisp index b71a1a3..959a76b 100644 --- a/lisp/game-objects.lisp +++ b/lisp/game-objects.lisp @@ -39,13 +39,10 @@ (defun set-object-attribute (game-object property value) "Set the attribute 'property' of 'game-object' to 'value'" ;; Here follows Lisp magic :D (that took ages to get right...) + ;; [And half the magic is gone after being outsourced to build-symbol :-(] ;; I'm not sure how elegant it is to call (eval) explicitly, but in this ;; case I couldn't avoid it - I needed a mix between a macro and a function - (let ((command (read-from-string - (concatenate 'string - (symbol-name (type-of game-object)) - "-" (if (stringp property) property - (symbol-name property)))))) + (let ((command (build-symbol (type-of game-object) "-" property))) ;; XXX This following section is rather ugly... (eval `(if (or (null (,command ,game-object)) (listp (,command ,game-object))) diff --git a/lisp/player.lisp b/lisp/player.lisp index 03f2333..c0c3e9c 100644 --- a/lisp/player.lisp +++ b/lisp/player.lisp @@ -19,7 +19,7 @@ (intelligence 0) (items NIL) (weapons NIL) - (place)) + (place "")) (defstruct race diff --git a/lisp/util.lisp b/lisp/util.lisp index e5434a8..03f8092 100644 --- a/lisp/util.lisp +++ b/lisp/util.lisp @@ -86,6 +86,11 @@ ((= ,index (length ,vector)) ,return-variable) ,@body))) +;; TODO ? +;; (defmacro call-function (function-name &rest args) +;; "Save myself some quoting when calling a function from a generated symbol" +;; `(eval + ;;; FUNCTIONS @@ -140,3 +145,12 @@ (file-lines (list line) (append file-lines (list line)))) ((null line) file-lines)))) +(defun build-symbol (&rest components) + "Concatenate the passed components into a single symbol" + ;; A very useful function illustrating the power of Lisp :-) + (let ((comps components)) + (dotimes (i (length comps)) + (when (symbolp (nth i comps)) + (setf (nth i comps) (symbol-name (nth i comps))))) + (eval `(read-from-string (concatenate 'string ,@comps))))) + diff --git a/lisp/world.lisp b/lisp/world.lisp index 3a01bdc..1f44806 100644 --- a/lisp/world.lisp +++ b/lisp/world.lisp @@ -32,12 +32,23 @@ "Add 'game-object' to *world*" ;; XXX: Very similar in structure to the function set-object-attribute in ;; game-objects.lisp. Can that be abstracted away into a macro or some such? - (let ((world-list (read-from-string - (concatenate 'string "world-" - (symbol-name (type-of game-object)) "s")))) + (let ((world-list (build-symbol "world-" (type-of game-object) "s"))) (eval `(setf (,world-list *world*) (append (,world-list *world*) (list ,game-object)))))) -; TODO -(defun get-game-object (object-name)) +(defun get-game-object (object-type object-name) + "Return the desired game object" + (let ((get-world-objects (build-symbol "world-" object-type "s")) + (get-object-name (build-symbol object-type "-name"))) + (dolist (object (eval `(,get-world-objects *world*)) NIL) + (when (equalp (eval `(,get-object-name ,object)) object-name) + (return object))))) + +(defun list-objects (object-type) + "Return a list of the names of all objects of the specified type" + (let ((get-world-objects (build-symbol "world-" object-type "s")) + (get-object-name (build-symbol object-type "-name")) + (name-list NIL)) + (dolist (object (eval `(,get-world-objects *world*)) name-list) + (setf name-list (cons (eval `(,get-object-name ,object)) name-list)))))