diff --git a/TODO b/TODO index fffab95..98e4bae 100644 --- a/TODO +++ b/TODO @@ -12,6 +12,10 @@ GAME +* add animals + +* introduce multithreading, update functions + * (I am legion...) @@ -19,13 +23,7 @@ -> SEVERE -* The last debug print statement from world creation is only printed after - the UI has been created... - -* The player coordinates (+/- 1) are displayed in the player panel - -* The screen is not automatically redrawn when entering (user-interface) - +* ... -> HEISENBUGS diff --git a/TODO b/TODO index fffab95..98e4bae 100644 --- a/TODO +++ b/TODO @@ -12,6 +12,10 @@ GAME +* add animals + +* introduce multithreading, update functions + * (I am legion...) @@ -19,13 +23,7 @@ -> SEVERE -* The last debug print statement from world creation is only printed after - the UI has been created... - -* The player coordinates (+/- 1) are displayed in the player panel - -* The screen is not automatically redrawn when entering (user-interface) - +* ... -> HEISENBUGS diff --git a/naledi.lisp b/naledi.lisp index 06d8c25..5c5f380 100644 --- a/naledi.lisp +++ b/naledi.lisp @@ -8,7 +8,7 @@ ;;;; -(defvar *debugging* T) +(defparameter *debugging* T) (ql:quickload :croatoan) (use-package :croatoan) @@ -35,19 +35,22 @@ (xoff (halve (- width 80)))) (clear scr) (dolist (l logo) - (setf (.cursor-position scr) (list y xoff)) + (move scr y xoff) (add-string scr l) (incf y)) - (setf (.cursor-position scr) (list (1- height) 0)) + (move scr (1- height) 0) (add-string scr "Press any key to continue.") + (move scr (1- height) (- width 22)) + (add-string scr "(c) 2018 Daniel Vedder") (event-case (scr event) (otherwise (return-from event-case))))) (defun user-interface (scr) "Create the screen on the ncurses interface and hand over to window functions" - ;(clear scr) (let* ((width (.width scr)) (height (1- (.height scr))) (me (list (round (/ width 4)) (halve height)))) + (clear scr) + (refresh scr) (with-windows ((mapwin :position '(0 0) :input-blocking t :border t :width (- width 51) :height height) (playerwin :position (list 0 (- width 50)) @@ -60,7 +63,6 @@ :position (list height 0) :width width :height 1)) (update-ui mapwin playerwin placewin newswin me) - ;(refresh scr) ;;TODO (event-case (scr event) (#\q (return-from event-case)) @@ -77,7 +79,6 @@ (defun update-ui (mapwin playerwin placewin newswin me) "Update all four UI elements" - ;;TODO implement missing functions (draw-map mapwin me) (draw-player-panel playerwin) (draw-place-panel placewin me) @@ -85,21 +86,21 @@ (defun draw-map (win me) "Draw a portion of the game map in an ncurses window" - ;;FIXME do I have a transpose bug here? (setf (.color-pair win) '(:white :black)) (box win) - (setf (.cursor-position win) '(1 1)) - (let ((x0 (- (first me) (halve (.width win)))) + (move win 1 1) + (let ((x0 (- (first me) (round (/ (.width win) 4)))) (y0 (- (second me) (halve (.height win))))) + ;; NB. x0 and w are calculated differently to y0 and h because we insert + ;; a space after each character (dotimes (h (1- (.height win))) (dotimes (w (- (halve (.width win) 'floor) 2)) - (let ((p (coord (+ w x0 1) (+ h y0 1)))) + (let ((p (coord (+ w x0 3) (+ h y0 1)))) (if (null p) (add-char win #\space) (if (and (= (first (patch-pos p)) (first me)) (= (second (patch-pos p)) (second me))) - ;;FIXME `me' is not drawn (progn (setf (.color-pair win) '(:white :black)) - (add-char win #\X)) + (add-char win #\@)) (if (patch-occupant p) (progn (setf (.color-pair win) @@ -113,28 +114,27 @@ (add-char win (biome-char (patch-biome p))))))) (add-char win #\space))) - (setf (.cursor-position win) (list (1+ h) 1))) + (move win (1+ h) 1)) (refresh win))) (defun draw-player-panel (win) "Draw a panel with information about the player character." ;;TODO (box win) - (setf (.cursor-position win) '(1 1)) + (move win 1 1) (add-string win "This is the player panel.") (refresh win)) (defun draw-place-panel (win me) "Draw a panel with information about the player's current location." - (debugging "~&~S" me) - (let* ((p (coord (first me) (second me))) (descr (describe-patch p))) + (let* ((p (coord (first me) (second me))) + (descr (when p (describe-patch p)))) (clear win) (box win) - (setf (.cursor-position win) '(1 1)) + (move win 1 1) (dolist (d descr) (add-string win d) - (setf (.cursor-position win) - (list (1+ (first (.cursor-position win))) 1))) + (move win (1+ (first (.cursor-position win))) 1)) (refresh win))) (let ((news '("Press h for help."))) @@ -142,14 +142,16 @@ "Draw a thin panel at the bottom of the screen to display news items." ;;TODO (clear win) - (setf (.cursor-position win) '(0 0)) + (move win 0 0) (add-string win (car news)) (refresh win)) - (defun notify (news-string) + (defun notify (news-string &rest formats) "Append a string to the news to notify the user." - ;;FIXME This needs to support (format) - (setf news (cons news-string news))) + ;;A bit of a kluge, but means that `notify' supports formatting + (setf news + (cons (apply #'format (cons NIL (cons news-string formats))) + news))) (defun message-window () "Return a dialog window with the last game messages." diff --git a/TODO b/TODO index fffab95..98e4bae 100644 --- a/TODO +++ b/TODO @@ -12,6 +12,10 @@ GAME +* add animals + +* introduce multithreading, update functions + * (I am legion...) @@ -19,13 +23,7 @@ -> SEVERE -* The last debug print statement from world creation is only printed after - the UI has been created... - -* The player coordinates (+/- 1) are displayed in the player panel - -* The screen is not automatically redrawn when entering (user-interface) - +* ... -> HEISENBUGS diff --git a/naledi.lisp b/naledi.lisp index 06d8c25..5c5f380 100644 --- a/naledi.lisp +++ b/naledi.lisp @@ -8,7 +8,7 @@ ;;;; -(defvar *debugging* T) +(defparameter *debugging* T) (ql:quickload :croatoan) (use-package :croatoan) @@ -35,19 +35,22 @@ (xoff (halve (- width 80)))) (clear scr) (dolist (l logo) - (setf (.cursor-position scr) (list y xoff)) + (move scr y xoff) (add-string scr l) (incf y)) - (setf (.cursor-position scr) (list (1- height) 0)) + (move scr (1- height) 0) (add-string scr "Press any key to continue.") + (move scr (1- height) (- width 22)) + (add-string scr "(c) 2018 Daniel Vedder") (event-case (scr event) (otherwise (return-from event-case))))) (defun user-interface (scr) "Create the screen on the ncurses interface and hand over to window functions" - ;(clear scr) (let* ((width (.width scr)) (height (1- (.height scr))) (me (list (round (/ width 4)) (halve height)))) + (clear scr) + (refresh scr) (with-windows ((mapwin :position '(0 0) :input-blocking t :border t :width (- width 51) :height height) (playerwin :position (list 0 (- width 50)) @@ -60,7 +63,6 @@ :position (list height 0) :width width :height 1)) (update-ui mapwin playerwin placewin newswin me) - ;(refresh scr) ;;TODO (event-case (scr event) (#\q (return-from event-case)) @@ -77,7 +79,6 @@ (defun update-ui (mapwin playerwin placewin newswin me) "Update all four UI elements" - ;;TODO implement missing functions (draw-map mapwin me) (draw-player-panel playerwin) (draw-place-panel placewin me) @@ -85,21 +86,21 @@ (defun draw-map (win me) "Draw a portion of the game map in an ncurses window" - ;;FIXME do I have a transpose bug here? (setf (.color-pair win) '(:white :black)) (box win) - (setf (.cursor-position win) '(1 1)) - (let ((x0 (- (first me) (halve (.width win)))) + (move win 1 1) + (let ((x0 (- (first me) (round (/ (.width win) 4)))) (y0 (- (second me) (halve (.height win))))) + ;; NB. x0 and w are calculated differently to y0 and h because we insert + ;; a space after each character (dotimes (h (1- (.height win))) (dotimes (w (- (halve (.width win) 'floor) 2)) - (let ((p (coord (+ w x0 1) (+ h y0 1)))) + (let ((p (coord (+ w x0 3) (+ h y0 1)))) (if (null p) (add-char win #\space) (if (and (= (first (patch-pos p)) (first me)) (= (second (patch-pos p)) (second me))) - ;;FIXME `me' is not drawn (progn (setf (.color-pair win) '(:white :black)) - (add-char win #\X)) + (add-char win #\@)) (if (patch-occupant p) (progn (setf (.color-pair win) @@ -113,28 +114,27 @@ (add-char win (biome-char (patch-biome p))))))) (add-char win #\space))) - (setf (.cursor-position win) (list (1+ h) 1))) + (move win (1+ h) 1)) (refresh win))) (defun draw-player-panel (win) "Draw a panel with information about the player character." ;;TODO (box win) - (setf (.cursor-position win) '(1 1)) + (move win 1 1) (add-string win "This is the player panel.") (refresh win)) (defun draw-place-panel (win me) "Draw a panel with information about the player's current location." - (debugging "~&~S" me) - (let* ((p (coord (first me) (second me))) (descr (describe-patch p))) + (let* ((p (coord (first me) (second me))) + (descr (when p (describe-patch p)))) (clear win) (box win) - (setf (.cursor-position win) '(1 1)) + (move win 1 1) (dolist (d descr) (add-string win d) - (setf (.cursor-position win) - (list (1+ (first (.cursor-position win))) 1))) + (move win (1+ (first (.cursor-position win))) 1)) (refresh win))) (let ((news '("Press h for help."))) @@ -142,14 +142,16 @@ "Draw a thin panel at the bottom of the screen to display news items." ;;TODO (clear win) - (setf (.cursor-position win) '(0 0)) + (move win 0 0) (add-string win (car news)) (refresh win)) - (defun notify (news-string) + (defun notify (news-string &rest formats) "Append a string to the news to notify the user." - ;;FIXME This needs to support (format) - (setf news (cons news-string news))) + ;;A bit of a kluge, but means that `notify' supports formatting + (setf news + (cons (apply #'format (cons NIL (cons news-string formats))) + news))) (defun message-window () "Return a dialog window with the last game messages." diff --git a/util.lisp b/util.lisp index 643512d..d7bb60d 100644 --- a/util.lisp +++ b/util.lisp @@ -14,7 +14,8 @@ "If *debugging* is true, print str" `(when *debugging* (format t ,str ,@format-args))) -;; XXX potentially inefficient if called often +;;TODO write `logging' macro + (defmacro set-list (value &rest var-list) "Set each symbol in var-list to value" (do* ((expr (list 'setf)) (vl var-list (cdr vl)) (var (car vl) (car vl)))