--- a/antipodes.asd Sat Jan 07 16:32:09 2017 +0000
+++ b/antipodes.asd Sat Jan 07 17:08:58 2017 +0000
@@ -26,6 +26,7 @@
:components ((:file "world")))
(:module "aspects" :serial t
:components ((:file "coordinates")
+ (:file "holdable")
(:file "visible")))
(:module "entities" :serial t
:components ((:file "player")))
--- a/package.lisp Sat Jan 07 16:32:09 2017 +0000
+++ b/package.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -50,10 +50,16 @@
(:export
:player
:make-player
+ :tick-player
:player/health
:health-description
:player/energy
:energy-description
+ :player/inventory
+ :player-inventory-full-p
+ :player-inventory-empty-p
+ :player-get
+ :player-drop
:coords
:coords/x
@@ -62,6 +68,10 @@
:coords-lookup
:coords-move-entity
+ :holdable
+ :holdable?
+ :holdable/description
+
:visible
:visible?
:visible/glyph
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aspects/holdable.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -0,0 +1,4 @@
+(in-package :ap.entities)
+
+(define-aspect holdable
+ description)
--- a/src/entities/player.lisp Sat Jan 07 16:32:09 2017 +0000
+++ b/src/entities/player.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -1,23 +1,29 @@
(in-package :ap.entities)
+(define-constant +inventory-size+ 10)
+
+
(defun health-description (health-value)
- (cond ((< health-value 0.0) "dead")
+ (cond ((<= health-value 0.0) "dead")
((< health-value 10.0) "almost dead")
((< health-value 50.0) "in bad shape")
((< health-value 70.0) "feeling decent")
((<= health-value 100.0) "feeling healthy")))
(defun energy-description (energy-value)
- (cond ((< energy-value 0.0) "starving")
+ (cond ((<= energy-value 0.0) "starving")
((< energy-value 30.0) "famished")
((< energy-value 50.0) "very hungry")
- ((< energy-value 70.0) "hungry")
- ((< energy-value 80.0) "peckish")
+ ((< energy-value 80.0) "hungry")
+ ((< energy-value 95.0) "peckish")
((<= energy-value 100.0) "full")))
+
(define-entity player (coords visible)
(health :accessor player/health :initform 100.0)
- (energy :accessor player/energy :initform 100.0))
+ (energy :accessor player/energy :initform 100.0)
+ (inventory :accessor player/inventory :initform nil))
+
(defun make-player ()
(create-entity 'player
@@ -25,3 +31,28 @@
:coords/y (round (* 0.9 ap.generation::*map-size*))
:visible/glyph "@"
:visible/color ap::+black-white+))
+
+
+(defun tick-player (player)
+ (zapf (player/energy player) (clamp 0.0 100.0 (- % 0.1))
+ (player/health player) (clamp 0.0 100.0 (+ % 0.1))))
+
+
+(defun player-inventory-full-p (player)
+ (= +inventory-size+ (length (player/inventory player))))
+
+(defun player-inventory-empty-p (player)
+ (zerop (length (player/inventory player))))
+
+(defun player-get (player entity)
+ (assert (holdable? entity) () "Entity ~S is not holdable")
+ (assert (coords? entity) () "Entity ~S has no coords")
+ (assert (not (player-inventory-full-p player)) () "Player's inventory is full")
+ (coords-remove-entity entity)
+ (push entity (player/inventory player)))
+
+(defun player-drop (player entity)
+ (removef entity (player/inventory player))
+ (setf (coords/x entity) (coords/x player)
+ (coords/y entity) (coords/y player))
+ (coords-insert-entity entity))
--- a/src/main.lisp Sat Jan 07 16:32:09 2017 +0000
+++ b/src/main.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -170,14 +170,23 @@
(defun render-sidebar (window)
(charms:clear-window window)
(border window)
- (write-string-left window
- (format nil "You are ~A" (health-description
- (player/health *player*)))
- 1 1)
- (write-string-left window
- (format nil " ~A" (energy-description
- (player/energy *player*)))
- 1 2))
+ (let ((p *player*))
+ (write-string-left window (format nil "You are ~A" (health-description
+ (player/health p)))
+ 1 1)
+ (write-string-left window (format nil " ~A" (energy-description
+ (player/energy p)))
+ 1 2)
+ (write-string-left window (format nil "You are carrying:") 1 4)
+ (if (player-inventory-empty-p p)
+ (write-string-left window (format nil "Nothing") 3 5)
+ (iterate
+ (for item :in (player/inventory p))
+ (for y :from 5)
+ (write-lines-left window
+ (cl-strings:shorten (holdable/description item)
+ (- *width* 2 2 3 1))
+ 3 y)))))
(defun move-player (dx dy)
@@ -189,10 +198,10 @@
(defun world-map-input (window)
(case (charms:get-char window)
(#\q :quit)
- (:left (move-player -1 0))
- (:right (move-player 1 0))
- (:up (move-player 0 -1))
- (:down (move-player 0 1))))
+ (:left (move-player -1 0) :tick)
+ (:right (move-player 1 0) :tick)
+ (:up (move-player 0 -1) :tick)
+ (:down (move-player 0 1) :tick)))
(defun world-map ()
@@ -207,7 +216,9 @@
(center-view-on-player *width* *height*)
(render-map map-win))
(redraw)
- (until (eql :quit (world-map-input bar-win))))))
+ (case (world-map-input bar-win)
+ (:tick (tick-player *player*))
+ (:quit (return))))))
nil)
--- a/vendor/make-quickutils.lisp Sat Jan 07 16:32:09 2017 +0000
+++ b/vendor/make-quickutils.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -12,6 +12,7 @@
:once-only
:rcurry
:read-file-into-string
+ :removef
:symb
:with-gensyms
--- a/vendor/quickutils.lisp Sat Jan 07 16:32:09 2017 +0000
+++ b/vendor/quickutils.lisp Sat Jan 07 17:08:58 2017 +0000
@@ -2,7 +2,7 @@
;;;; See http://quickutil.org for details.
;;;; To regenerate:
-;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:COMPOSE :CURRY :DEFINE-CONSTANT :DELETEF :MKSTR :ONCE-ONLY :RCURRY :READ-FILE-INTO-STRING :SYMB :WITH-GENSYMS) :ensure-package T :package "AP.QUICKUTILS")
+;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:COMPOSE :CURRY :DEFINE-CONSTANT :DELETEF :MKSTR :ONCE-ONLY :RCURRY :READ-FILE-INTO-STRING :REMOVEF :SYMB :WITH-GENSYMS) :ensure-package T :package "AP.QUICKUTILS")
(eval-when (:compile-toplevel :load-toplevel :execute)
(unless (find-package "AP.QUICKUTILS")
@@ -17,7 +17,7 @@
:COMPOSE :CURRY :DEFINE-CONSTANT
:DELETEF :MKSTR :ONCE-ONLY :RCURRY
:WITH-OPEN-FILE* :WITH-INPUT-FROM-FILE
- :READ-FILE-INTO-STRING :SYMB
+ :READ-FILE-INTO-STRING :REMOVEF :SYMB
:STRING-DESIGNATOR :WITH-GENSYMS))))
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun make-gensym-list (length &optional (x "G"))
@@ -248,6 +248,16 @@
:while (= bytes-read buffer-size)))))))
+ (declaim (inline remove/swapped-arguments))
+ (defun remove/swapped-arguments (sequence item &rest keyword-arguments)
+ (apply #'remove item sequence keyword-arguments))
+
+ (define-modify-macro removef (item &rest remove-keywords)
+ remove/swapped-arguments
+ "Modify-macro for `remove`. Sets place designated by the first argument to
+the result of calling `remove` with `item`, place, and the `keyword-arguments`.")
+
+
(defun symb (&rest args)
"Receives any number of objects, concatenates all into one string with `#'mkstr` and converts them to symbol.
@@ -302,6 +312,6 @@
(eval-when (:compile-toplevel :load-toplevel :execute)
(export '(compose curry define-constant deletef mkstr once-only rcurry
- read-file-into-string symb with-gensyms with-unique-names)))
+ read-file-into-string removef symb with-gensyms with-unique-names)))
;;;; END OF quickutils.lisp ;;;;