;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; General Game Definitions ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Classes ;;; All game objects are subclasses of this. (defclass () ;; symbol used by players to refer to the object (nickname :type :accessor nick :initarg :nick) ;; its printed name (name :type :accessor name :initarg :name) ;; a longer description - a list of strings (description :type :accessor description :initarg :description :initvalue '())) ;;; Objects that contain other objects. (defclass () (contents :type ; (of s) :accessor contents :initarg :contents :initvalue '())) ;;; Objects that can be in containers. (defclass () (location :type :accessor location :initarg :location)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Interface ;;; Use this to show an object with its nickname so players know how to ;;; refer to this object. (defgeneric (name+nick game-object)) ;;; This function gets a list of s and returns the one with ;;; the given nickname, or #f of none found. ;;; (define (nick-find nickname list) ...) ;;; Move an object to a different location. (defgeneric (transfer obj source target)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Implementation ;;; This specialize the way that objects are created - ;;; updating the holding container automatically. ;;; initialize is a built-in standard generic that is called on every ;;; object that is created, so you must call the next method to do what ;;; it was supposed to do, then add stuff. (defmethod (initialize (o ) initargs) (call-next-method) ; must call this ;; this prevents errors when there is no initial location value ;; (slot-bound can test if there is any value in the location slot) (when (slot-bound? o 'location) (set! (contents (location o)) (cons o (contents (location o)))))) ;;; Using this method will produce uniform output that players can use. (defmethod (name+nick (obj )) (add (name obj) " [" (as (nick obj)) "]")) ;;; Search for an object by its nickname, nickname can be anything, but ;;; only symbols will be found. (define (nick-find nickname list) (find-if (lambda (x) (eq? (nick x) nickname)) list)) ;;; Move an object to a different location. Using only this method to ;;; make sure that you don't get inconsistencies. (defmethod (transfer (obj ) (from ) (to )) (unless (eq? from to) (set! (contents from) (remq obj (contents from))) (set! (location obj) to) (set! (contents to) (cons obj (contents to)))))