;;; -*- Common Lisp -*- #| Copyright (c) 2007,2008 Gustavo Henrique Milar� This file is part of The Feebs War. The Feebs War is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. The Feebs War is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with The Feebs War. If not, see . |# (in-package :the-feebs-war) ;;; This file is an extension of system.lisp which handles vision ;;; -*- Vision Calculation -*- (defstruct feeb-image name facing peeking) (defstruct fireball-image direction) (defstruct (proximity (:conc-name nil)) my-square rear-square left-square right-square) ;;; Computes what the feeb is seeing (defun compute-vision (feeb) (let ((proximity (feeb-proximity feeb)) (vision (feeb-vision feeb)) (vision-left (feeb-vision-left feeb)) (vision-right (feeb-vision-right feeb)) (facing (feeb-facing feeb)) vision-dx vision-dy (x (feeb-x-position feeb)) (y (feeb-y-position feeb))) ;; First fill in proximity info. (setf (my-square proximity) (mapcar (rcurry #'imagify feeb :proximity) (aref *maze* x y)) (left-square proximity) (mapcar (rcurry #'imagify feeb :proximity) (aref *maze* (+ x (left-dx facing)) (+ y (left-dy facing)))) (right-square proximity) (mapcar (rcurry #'imagify feeb :proximity) (aref *maze* (+ x (right-dx facing)) (+ y (right-dy facing)))) (rear-square proximity) (mapcar (rcurry #'imagify feeb :proximity) (aref *maze* (+ x (behind-dx facing)) (+ y (behind-dy facing))))) ;; The vision vector starts in the square the feeb is facing. (setf x (+ x (forward-dx facing)) y (+ y (forward-dy facing))) ;; Figure out which direction to scan in. (case (feeb-peeking feeb) (:peek-left (setf facing (left-of facing))) (:peek-right (setf facing (right-of facing)))) (setf vision-dx (forward-dx facing) vision-dy (forward-dy facing)) ;; compute vision, vision-left and vision-right (do* ((x x (+ x vision-dx)) (y y (+ y vision-dy)) (left-wall-x (+ x (left-dx facing)) (+ left-wall-x vision-dx)) (left-wall-y (+ y (left-dy facing)) (+ left-wall-y vision-dy)) (right-wall-x (+ x (right-dx facing)) (+ right-wall-x vision-dx)) (right-wall-y (+ y (right-dy facing)) (+ right-wall-y vision-dy)) (index 0 (1+ index))) ((wallp (aref *maze* x y)) (setf (aref vision index) (list :rock) (aref vision-left index) (list :unknown) (aref vision-right index) (list :unknown) (feeb-line-of-sight feeb) index)) (setf (aref vision index) (mapcar (rcurry #'imagify feeb :vision) (aref *maze* x y)) (aref vision-left index) (mapcar (rcurry #'imagify feeb :left-vision) (aref *maze* left-wall-x left-wall-y)) (aref vision-right index) (mapcar (rcurry #'imagify feeb :right-vision) (aref *maze* right-wall-x right-wall-y)))))) ;;; This transforms what the feeb is seeing; (defgeneric imagify (feeb type thing) (:documentation "Defines how FEEB sees or feels THING. TYPE could be :vision, :left-vision :right-vision or :proximity") (:method (thing feeb type) thing) (:method ((thing feeb) feeb (type (eql :vision))) (make-feeb-image :name (feeb-name thing) :facing (feeb-facing thing) :peeking (feeb-peeking thing))) (:method ((thing feeb) feeb (type (eql :proximity))) (make-feeb-image :name (feeb-name thing) :facing (feeb-facing thing) :peeking (feeb-peeking thing))) (:method ((thing fireball) feeb (type (eql :vision))) (make-fireball-image :direction (fireball-direction thing))) (:method ((thing fireball) feeb (type (eql :proximity))) (make-fireball-image :direction (fireball-direction thing))) (:method (thing feeb (type (eql :left-vision))) (if (eq :rock thing) :rock)) (:method (thing feeb (type (eql :right-vision))) (if (eq :rock thing) :rock)) (:method ((thing feeb) feeb (type (eql :left-vision))) (and (feeb-p thing) (= (feeb-facing feeb) (left-of (feeb-facing thing))) (feeb-peeking thing))) (:method ((thing feeb) feeb (type (eql :right-vision))) (and (feeb-p thing) (= (feeb-facing feeb) (right-of (feeb-facing thing))) (feeb-peeking thing))) ) ; end of imagify generic function