--- 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)
--- 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
--- 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
--- 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))
--- 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)