;;;; ;;;; Naledi ya Africa ("Star of Africa") is a rogue-like survival game ;;;; set in Africa. ;;;; ;;;; This file stores all game data. ;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; ;;; PATCHES (let ((world NIL)) (defun set-world (w) (setf world w)) (defun world-size () (length world)) (defun save-topography (file-name) ;XXX (re)move this? "Save the world topography as a text file" (debugging "~&Saving world to file ~A" file-name) ;debug (with-open-file (tf file-name :direction :output) (dolist (row world) (format stream "~&~A~%" (string-from-list (mapcar #'(lambda (p) (biome-char (patch-biome p))) row) ""))))) (defun coord (x y) "Return the patch at the given coordinates or NIL if out of bounds" (unless (or (< x 0) (< y 0) (> x (length world)) (> y (length world))) (nth x (nth y world))))) ;;; BIOMES (let ((biome-list NIL)) (defun register-biome (symbol-name biome-object) (setf biome-list (cons (list symbol-name biome-object) biome-list))) (defun available-biomes () (keys biome-list)) (defun get-biome (symbol-name) (cassoc symbol-name biome-list))) (defmacro new-biome (name &body body) `(register-biome ',name (make-biome :name ,(symbol-to-string name) ,@body))) ;;; ITEMS (let ((item-list NIL)) (defun register-item (symbol-name item-object) (setf item-list (cons (list symbol-name item-object) item-list))) (defun get-item-type (symbol-name) (cassoc symbol-name item-list)) (defun get-item (symbol-name) ;;FIXME copy-item doesn't work with CLOS (copy-item (get-item-type symbol-name)))) (defmacro new-item (type name &body body) `(register-item ',name (make-instance ',type :name ,(symbol-to-string name) ,@body))) ;;; ANIMALS & SPECIES (let ((species-list NIL)) (defun register-species (symbol-name species-object) (setf species-list (cons (list symbol-name species-object) species-list))) (defun get-species (symbol-name) (cassoc symbol-name species-list))) (defmacro new-species (name &body body) `(register-species ',name (make-instance 'species :name ,(symbol-to-string name) ,@body))) (let ((max-id 0) (animals NIL)) (defun add-animal (species position) "Create a new animal of the given species" (let ((a (make-animal :id max-id :pos position :species species :health (.max-health species)))) (incf max-id) (setf animals (append animals a)))) (defun get-animal (id) "Return the animal with this ID number" (dolist (a animals) (when (= (.id a) id) (return-from get-animal a)))) (defun remove-animal (id) "Remove the animal with this ID from the game" ;;XXX Can't we just do this with `remove-if'? (do ((al animals (cdr al))) ((null al)) (when (= (.id (car al)) id) (setf (cdr al) (cddr al))))))