X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=src%2Fgacela_mobs.scm;h=5ae3296ab0287601d48b91062623f2e5aa3930b4;hb=b50916459d90f604043ea688750c55a516636796;hp=3e3e17a907aebf7dcd0d46b1f47f9f173a1d3b2c;hpb=44cea6ad0255b8bda0cd3ea74441d47d8efc5eb5;p=gacela.git diff --git a/src/gacela_mobs.scm b/src/gacela_mobs.scm index 3e3e17a..5ae3296 100755 --- a/src/gacela_mobs.scm +++ b/src/gacela_mobs.scm @@ -17,54 +17,122 @@ ;;; Mobs Factory -(define add-mob-symbol #f) -(define kill-mob-symbol #f) +(define show-mob-hash #f) +(define hide-mob-hash #f) (define get-active-mobs #f) -(define reload-mobs? #f) -(define mobs-reloaded #f) +(define mobs-changed? #f) -(let ((active-mobs '()) (reload #f)) - (set! add-mob-symbol - (lambda (mob) - (pushnew mob active-mobs) - (set! reload #t))) +(let ((active-mobs (make-hash-table)) (changed #f)) + (set! show-mob-hash + (lambda (key mob) + (hash-set! active-mobs key mob) + (set! changed #t))) - (set! kill-mob-symbol - (lambda (mob) - (set! active-mobs (lset-difference eq? active-mobs (list mob))) - (set! reload #t))) + (set! hide-mob-hash + (lambda (key) + (hash-remove! key) + (set! changed #t))) (set! get-active-mobs - (lambda () active-mobs)) + (lambda* (#:optional (refreshed #t)) + (set! changed (not refreshed)) + (hash-map->list (lambda (k v) v) active-mobs))) - (set! reload-mobs? - (lambda () reload)) + (set! mobs-changed? + (lambda () changed))) - (set! mobs-reloaded - (lambda () (set! reload #f)))) -(define-macro (add-mob mob) - `(add-mob-symbol ',mob)) +(define-macro (show-mob mob) + `(show-mob-hash ',mob (lambda (option) (,mob option)))) -(define-macro (kill-mob mob) - `(kill-mob-symbol ',mob)) +(define-macro (hide-mob mob) + `(hide-mob-hash ',mob)) -(define-macro (get-mobs-function) - (let ((mobs (get-active-mobs))) - (cond ((null? mobs) - `(lambda () #f)) +(define (process-mobs mobs) + (for-each (lambda (m) (m #:render)) mobs)) + + +;;; Actions and looks for mobs + +(define (get-attr list name default) + (let ((value (assoc-ref list name))) + (cond (value (car value)) + (else default)))) + +(define (attr-def attr) + (let ((name (car attr)) + (value (cadr attr))) + `(,name (get-attr attributes ',name ',value)))) + +(define (attr-save attr) + (let ((name (car attr))) + `(set! attributes (assoc-set! attributes ',name (list ,name))))) + +(define-macro (define-action action-head . code) + (let ((name (car action-head)) (attr (cdr action-head))) + `(define ,name + (lambda-action ,attr ,@code)))) + +(define-macro (lambda-action attr . code) + `(lambda (attributes) + (let ,(map attr-def attr) + ,@code + ,(cons 'begin (map attr-save attr)) + attributes))) + +(define-macro (lambda-look attr . look) + (define (process-look look) + (cond ((null? look) (values '() '())) (else - `(lambda () ,@(map (lambda (mob) `(,mob #:render)) mobs)))))) + (let ((line (car look))) + (receive (lines images) (process-look (cdr look)) + (cond ((string? line) + (let ((var (gensym))) + (values (cons `(draw-texture ,var) lines) + (cons `(,var (load-texture ,line)) images)))) + (else + (values (cons line lines) + images)))))))) + + (receive (look-lines look-images) (process-look look) + `(let ,look-images + (lambda (attributes) + (let ,(map attr-def attr) + (glPushMatrix) + ,@look-lines + (glPopMatrix)))))) + + +;;; Making mobs (define-macro (define-mob mob-head . look) (let ((name (car mob-head)) (attr (cdr mob-head))) - `(begin - (define ,name #f) - (let ((attr ',attr)) - (set! ,name - (lambda (option) - (case option - ((#:render) - (glPushMatrix) - ,@(map (lambda (x) (if (string? x) `(draw-image ,x) x)) look) - (glPopMatrix))))))))) + `(define ,name + (lambda-mob ,attr ,@look)))) + +(define-macro (lambda-mob attr . look) + `(let ((mob #f)) + (set! mob + (let ((attr ',attr) (actions '()) (renders '())) + (lambda (option . params) + (case option + ((get-attr) + attr) + ((set-attr) + (if (not (null? params)) (set! attr (car params)))) + ((get-actions) + actions) + ((set-actions) + (if (not (null? params)) (set! actions (car params)))) + ((get-renders) + renders) + ((set-renders) + (if (not (null? params)) (set! renders (car params)))) + ((render) + (for-each (lambda (render) ((cdr render) attr)) renders)))))) + (cond ((not (null? ',look)) + (mob 'set-renders + (list (cons + 'default-look + (lambda-look ,attr ,@look)))))) + mob))