diff --git a/terranostra.lisp b/terranostra.lisp index cba9b40..d25e20c 100644 --- a/terranostra.lisp +++ b/terranostra.lisp @@ -39,15 +39,15 @@ (defun dir2patch (herex herey therex therey) "Calculate the direction to a patch" (cond ((> herex therex) - (cond ((> herey therey) 'SE) - ((< herey therey) 'NE) - (T 'E))) + (cond ((> herey therey) 'NW) + ((< herey therey) 'SW) + (T 'W))) ((< herex therex) - (cond ((> herey therey) 'SW) - ((< herey therey) 'NW) - (T 'W))) - (T (cond ((> herey therey) 'S) - ((< herey therey) 'N) + (cond ((> herey therey) 'NE) + ((< herey therey) 'SE) + (T 'E))) + (T (cond ((> herey therey) 'N) + ((< herey therey) 'S) (T NIL))))) (defun coordsindir (x y dir) @@ -80,32 +80,49 @@ ;; XXX This would be quicker with (string-from-list), but I ;; don't want to use util.lisp just yet (do ((x 0 (1+ x)) (xstr "")) - ((= x (length world)) (format tf "~&~S~%" xstr)) + ((= x (length world)) (format tf "~&~A~%" xstr)) (setf xstr (concatenate 'string xstr (unless (= x 0) ",") (format NIL "~S" (patch-alt (nth x row))))))))) (defun create-mountains (world &optional (montaneity 2)) - "Create mountains and hills. Montaneity determines their number and height." + "Create mountains and hills. Montaneity determines number and height." (do ((n 0 (1+ n)) (npeaks (random (* (/ montaneity 100) (* (length world) - (length (first world))))))) - ((= n npeaks) world) - (setf world (create-peak (random (first world)) (random (length world)) - (random (* montaneity 100)) world)))) + (length world)))))) + ((= n npeaks)) + (create-peak (random (length world)) (random (length world)) + (+ *base-height* (random (* montaneity 100))) montaneity world))) -(defun create-peak (x y height world) +(defun create-peak (xcoord ycoord height montaneity world) "Create a mountain peak at the specified location" - ;;TODO - ) + (format t "~&Creating a peak of ~Sm at ~S/~S" height xcoord ycoord) + (setf (patch-alt (coord xcoord ycoord world)) height) + (do ((dist 1 (1+ dist)) (levelp NIL)) + (levelp) + (do ((x (- xcoord dist) (1+ x))) + ((> x (+ xcoord dist))) + (do* ((y (- ycoord dist) (1+ y)) + (p (coord x y world) (coord x y world)) + (np (when p (neighbour p (dir2patch x y xcoord ycoord))) + (when p (neighbour p (dir2patch x y xcoord ycoord))))) + ((> y (+ ycoord dist))) + (when (and p (or (= (abs (- xcoord x)) dist) + (= (abs (- ycoord y)) dist))) + (let ((new-alt (- (patch-alt np) + (random (* montaneity 5))))) + (if (> new-alt *base-height*) + (progn (setf (patch-alt p) new-alt) + (setf levelp NIL)) + (setf levelp T)))) + (unless p (setf levelp T)))))) ;boundary check (defun create-valleys (world &optional (aqueousness 5)) "Create valleys through streams. Aqueousness determines their number." (do ((n 0 (1+ n)) (nstreams (random (* (/ aqueousness 100) (* (length world) - (length (first world))))))) - ((= n nstreams) world) - (create-stream (random (first world)) - (random (length world)) world))) + (length world)))))) + ((= n nstreams)) + (create-stream (random (length world)) (random (length world)) world))) (defun create-stream (x y world) "Create a stream, starting at x/y" @@ -117,7 +134,7 @@ (let* ((np (patchindir x y d)) (alt (when np (patch-alt np)))) (when (and np (not (eq d (patch-stream-in here))) (or (< alt minheight) - (and (= alt minheight) (zerop (random 2))))) + (and (= alt minheight) (> 2 (random 10))))) (setf minheight alt) (setf dir d nextpatch np)))) ;;Erode this patch @@ -127,7 +144,6 @@ (patch-alt here)))) (setf (patch-alt here) (- maxheight (random (round (/ maxheight 10)))))) - (format t "~&Creating a stream at ~S/~S, flowing ~S." x y dir) ;; Test for break conditions (hitting another stream or the edge ;; of the world) (unless (and dir nextpatch (null (patch-stream-out nextpatch)))