;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Redefinitions & Foundation ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Globals (define *weapons* empty) (define *location* empty) (define *characters* empty) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Extra behavior ;;; We don't want to lose objects inside the characters, so this will ;;; prevent characters in general from getting objects (defmethod (transfer (o ) (from ) (to )) (call-next-method) (when (eq? (location o) to) (insert-event 60 (thunk (transfer o to (start-place o))))) #t) (defmethod (initialize (o ) initargs) (define (get-subs next lst) (let ((next (filter (lambda (x) (not (equal? x ""))) next))) (if (empty? next) lst (get-subs (map (lambda (x) (substring x 0 (sub1 (string-length x)))) next) (append lst next))))) (call-next-method) (when (slot-bound? o 'nickname) (set! (nick o) (map string->symbol (get-subs (map symbol->string (nick o)) empty))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Redefinitions ;;; **** This is redefined so that we can get a list of characters ;;; **** as a global (defmethod (initialize (a ) initargs) (define (character-loop) ;; this will do-something and insert the next event if the result is ;; a number. (let ((n (do-something a))) (when (and (number? n) (not (eq? (location a) *null-place*))) (insert-event n character-loop)))) (call-next-method) ; must call this (set! *characters* (cons a *characters*)) (let ((start (start-time a))) (when (number? start) ; add 1st event if got a number (insert-first-event start character-loop)))) ;;; **** This is fairly complicated code and was written after the ;;; **** problem set release ;;; Finds an object with a given nickname. Objects store their ;;; nicknames as a list of symbols. The first symbol in the nick name ;;; list is what the player sees. If the player types in any prefix ;;; or alternative name, we want to find those. This is done by looking ;;; at the first nickname of every object, if there's no match, we look ;;; at the second nickname of every object, and so forth. (define (nick-find nickname objects) ;; splits up the nicknames into two lists. The first is an associative ;; list of current nickname and object, and the second is an assoc ;; list of remaining nicknames and object. (define (get-next comps nocomps rest) (cond ((empty? rest) (list comps nocomps)) ((empty? (caar rest)) (get-next comps nocomps (tail rest))) (else (get-next (cons (list (caaar rest) (cadar rest)) comps) (cons (list (cdaar rest) (cadar rest)) nocomps) (tail rest))))) ;; objects is redefined to an associative list of nicks and objects (let ((objects (map (lambda (x) (list (nick x) x)) objects))) (let loop ((match-list (get-next empty empty objects))) (let ((found (assq nickname (first match-list)))) (cond (found (second found)) ((and (empty? (first match-list)) (empty? (second match-list))) #f) (else (loop (get-next empty empty (second match-list))))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Weapons ;;; Weapons just carry an extra bit of information that say ;;; how they would have murdered the victim (defclass () (effect :type :initarg :effect :accessor effect)) ;;; We need the list of weapons (defmethod (initialize (weapon ) inp) (call-next-method) (when (not (eq? (location weapon) *null-place*)) (set! *weapons* (cons weapon *weapons*)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Place global schtuff ;;; Locations are used to restrict the set of places where the ;;; murder could have taken place (defclass ()) (defmethod (initialize (place ) inp) (call-next-method) (set! *location* (cons place *location*)))