# HG changeset patch # User Steve Losh # Date 1483876581 0 # Node ID 8fc9b2aad98bd240971c714a9b6884023c46dfac # Parent 0c407f78da0e143b3c78863057e1da60097743df Add eating diff -r 0c407f78da0e -r 8fc9b2aad98b .lispwords --- a/.lispwords Sun Jan 08 11:34:45 2017 +0000 +++ b/.lispwords Sun Jan 08 11:56:21 2017 +0000 @@ -1,2 +1,3 @@ (1 with-panel-and-window with-panels-and-windows with-dims) (1 create-entity) +(1 when-select-item) diff -r 0c407f78da0e -r 8fc9b2aad98b package.lisp --- a/package.lisp Sun Jan 08 11:34:45 2017 +0000 +++ b/package.lisp Sun Jan 08 11:56:21 2017 +0000 @@ -52,10 +52,12 @@ :player-inventory-empty-p :player-get :player-drop + :player-eat :food :make-food :food/energy + :random-food-taste :clothing :make-clothing diff -r 0c407f78da0e -r 8fc9b2aad98b src/entities/food.lisp --- a/src/entities/food.lisp Sun Jan 08 11:34:45 2017 +0000 +++ b/src/entities/food.lisp Sun Jan 08 11:56:21 2017 +0000 @@ -17,6 +17,23 @@ (random-elt #("can" "tin" "package")) (random-elt *foods*))) +(defun random-food-taste () + (format nil "It tastes ~A." + (random-elt #("delicious" + "okay" + "wonderful" + "decent" + "musty" + "salty" + "awful" + "better than nothing" + "questionable" + "pretty nice" + "expensive" + "horrifying" + "like mice" + "like an old sock")))) + (defun make-food (x y) (create-entity 'food :coords/x x diff -r 0c407f78da0e -r 8fc9b2aad98b src/entities/player.lisp --- a/src/entities/player.lisp Sun Jan 08 11:34:45 2017 +0000 +++ b/src/entities/player.lisp Sun Jan 08 11:56:21 2017 +0000 @@ -16,7 +16,8 @@ ((< energy-value 50.0) "very hungry") ((< energy-value 80.0) "hungry") ((< energy-value 95.0) "peckish") - ((<= energy-value 100.0) "full"))) + ((< energy-value 100.0) "full") + (t "stuffed"))) (define-entity player (coords visible) @@ -34,7 +35,7 @@ (defun tick-player (player) - (zapf (player/energy player) (clamp 0.0 100.0 (- % 0.1)) + (zapf (player/energy player) (clamp 0.0 140.0 (- % 0.1)) (player/health player) (clamp 0.0 100.0 (+ % (if (minusp (player/energy player)) -0.1 @@ -59,3 +60,9 @@ (setf (coords/x entity) (coords/x player) (coords/y entity) (coords/y player)) (coords-insert-entity entity)) + +(defun player-eat (player food) + (incf (player/energy player) + (food/energy food)) + (removef (player/inventory player) food) + (destroy-entity food)) diff -r 0c407f78da0e -r 8fc9b2aad98b src/main.lisp --- a/src/main.lisp Sun Jan 08 11:34:45 2017 +0000 +++ b/src/main.lisp Sun Jan 08 11:56:21 2017 +0000 @@ -204,8 +204,10 @@ (defun spawn-player () (setf *player* (make-player)) - (iterate (repeat 2) - (player-get *player* (make-clothing 0 0)))) + (iterate (repeat (random-range-inclusive 0 2)) + (player-get *player* (make-clothing 0 0))) + (iterate (repeat (random-range-inclusive 1 3)) + (player-get *player* (make-food 0 0)))) (defun place-things (density constructor) (iterate @@ -253,7 +255,7 @@ ;;;; Popups ------------------------------------------------------------------- (defun popup (contents) (let ((lines (cl-strings:split contents #\newline))) - (with-dims ((+ 3 (apply #'max 13 (mapcar #'length lines))) + (with-dims ((+ 2 (apply #'max 11 (mapcar #'length lines))) (+ 3 (length lines))) (with-panel-and-window (pan win *width* *height* @@ -264,7 +266,8 @@ (write-lines-left win lines 1 1) (write-string-centered win "Press space" (1- *height*)) (redraw) - (iterate (until (eql #\space (charms:get-char win)))))))) + (iterate (until (eql #\space (charms:get-char win))))))) + nil) ;;;; Selection Menu ----------------------------------------------------------- @@ -300,6 +303,11 @@ (redraw) (choose win items))))) +(defmacro when-select-item ((symbol prompt items description-function) &body body) + `(let ((,symbol (menu ,prompt ,items ,description-function))) + (when ,symbol + ,@body))) + ;;;; World Map ---------------------------------------------------------------- (defun terrain-char (height) @@ -419,8 +427,7 @@ (cond ((null items) nil) ((player-inventory-full-p *player*) - (popup "You can't carry any more items.") - nil) + (popup "You can't carry any more items.")) ((= 1 (length items)) (player-get *player* (first items)) :tick) @@ -433,15 +440,25 @@ (defun drop-items () (if (player-inventory-empty-p *player*) - (progn (popup "You don't have anything to drop.") - nil) - (let ((item (menu "What do you want to drop?" - (player/inventory *player*) - #'holdable/description))) - (if item - (progn (player-drop *player* item) - :tick) - nil)))) + (popup "You don't have anything to drop.") + (when-select-item + (item "What do you want to drop?" (player/inventory *player*) #'holdable/description) + (player-drop *player* item) + :tick))) + +(defun eat () + (let ((food (remove-if-not (rcurry #'typep 'food) + (append (player/inventory *player*) + (coords-nearby *player* 0))))) + (cond ((null food) + (popup "You don't have anything to eat.")) + ((> (player/energy *player*) 100.0) + (popup "You are too full to eat any more.")) + (t (when-select-item + (item "What do you want to eat?" food #'holdable/description) + (player-eat *player* item) + (popup (random-food-taste)) + :tick))))) (defun world-map-input (window) @@ -450,6 +467,7 @@ (#\h :help) (#\g (get-items)) (#\d (drop-items)) + (#\e (eat)) (:left (move-player -1 0) :tick) (:right (move-player 1 0) :tick) (:up (move-player 0 -1) :tick)