;;;; ;;;; Naledi ya Africa ("Star of Africa") is an ncurses-based survival game ;;;; set in Africa. ;;;; ;;;; This file defines all CLOS methods used in the game for the different ;;;; item classes (human methods are separate in player.lisp). ;;;; ;;;; (c) 2018 Daniel Vedder, MIT license ;;;; (in-package :naledi-ya-africa) (defmethod move ((a animal) dir) "An animal moves one space in the specified direction, if possible" (let* ((here (coord (.x a) (.y a))) (target (coordsindir (.x a) (.y a) dir)) (target-patch (coord (first target) (second target)))) ;;XXX more conditions? (cond ((null target-patch) (logf 3 "~S is attempting to move out of bounds ~S" a target) 'OUT-OF-BOUNDS) ((patch-occupant target-patch) (logf 3 "~S is moving onto occupied patch ~S (~S)" a target (patch-occupant target-patch)) 'PATCH-OCCUPIED) (T (setf (patch-occupant here) NIL) (setf (patch-occupant target-patch) a) (setf (.x a) (first target) (.y a) (second target)) T)))) ;; Default `update' and `action' methods are NOP (defmethod update ((i item))) (defmethod action ((i item))) (defmethod attack ((d destructable) (tl tool)) "Attack a destructable item with a tool or weapon" ;;Returns either the damaged item or the items it drops when destroyed (if (member (class-of tl) (.destructors d)) (if (>= 0 (decf (.health d) (random (* 10 (.level tl))))) (.drops d) d) (progn (notify "You cannot attack ~A with ~A." ;;FIXME remove `notify' (leading-vowl (.name d)) (leading-vowel (.name tl))) NIL))) ;;TODO (defmethod attack ((at attacker) (f feature) (tl tool))) ;;TODO (defmethod attack ((at attacker) (an animal) (w weapon))) (defmethod update ((a animal)) (when (> (age-of-the-world) (.last-move a)) (random-move a) (incf (.last-move a)))) (defmethod habitat-p ((a animal) b) "Is the biome b a possible habitat of animal a?" ;;XXX Don't quite like this, but it works (when (eq (.habitat a) T) (return-from habitat-p T)) (dolist (h (.habitat a)) (when (equalp (symbol-to-string h) (biome-name b)) (return T)))) (defmethod random-move ((a animal)) "Move in a random direction within the species' habitat niche" (do* ((dir (random-elt *directions*) (random-elt *directions*)) (next-patch (patchindir (.x a) (.y a) dir) (patchindir (.x a) (.y a) dir)) (ttl 10 (1- ttl))) ((zerop ttl) NIL) (when (and next-patch (null (patch-occupant next-patch)) (habitat-p a (patch-biome next-patch))) (move a dir) (return-from random-move a))))