]> git.jsancho.org Git - gacela.git/blob - src/gacela_mobs.scm
(no commit message)
[gacela.git] / src / gacela_mobs.scm
1 ;;; Gacela, a GNU Guile extension for fast games development
2 ;;; Copyright (C) 2009 by Javier Sancho Fernandez <jsf at jsancho dot org>
3 ;;;
4 ;;; This program is free software: you can redistribute it and/or modify
5 ;;; it under the terms of the GNU General Public License as published by
6 ;;; the Free Software Foundation, either version 3 of the License, or
7 ;;; (at your option) any later version.
8 ;;;
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ;;; GNU General Public License for more details.
13 ;;;
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17
18 ;;; Mobs Factory
19
20 (define show-mob-hash #f)
21 (define hide-mob-hash #f)
22 (define get-active-mobs #f)
23 (define mobs-changed? #f)
24
25 (let ((active-mobs (make-hash-table)) (changed #f))
26   (set! show-mob-hash
27         (lambda (key mob)
28           (hash-set! active-mobs key mob)
29           (set! changed #t)))
30
31   (set! hide-mob-hash
32         (lambda (key)
33           (hash-remove! key)
34           (set! changed #t)))
35
36   (set! get-active-mobs
37         (lambda* (#:optional (refreshed #t))
38           (set! changed (not refreshed))
39           (hash-map->list (lambda (k v) v) active-mobs)))
40
41   (set! mobs-changed?
42         (lambda () changed)))
43
44
45 (define-macro (show-mob mob)
46   `(show-mob-hash ',mob (lambda (option) (,mob option))))
47
48 (define-macro (hide-mob mob)
49   `(hide-mob-hash ',mob))
50
51 (define (run-mob-actions mobs)
52   (for-each (lambda (m) (m 'run-actions)) mobs))
53
54 (define (render-mobs mobs)
55   (for-each (lambda (m) (m 'render)) mobs))
56
57
58 ;;; Actions and looks for mobs
59
60 (define (get-attr list name default)
61   (let ((value (assoc-ref list name)))
62     (cond (value (car value))
63           (else default))))
64
65 (define (attr-def attr)
66   (let ((name (car attr))
67         (value (cadr attr)))
68     `(,name (get-attr attributes ',name ',value))))
69
70 (define (attr-save attr)
71   (let ((name (car attr)))
72     `(set! attributes (assoc-set! attributes ',name (list ,name)))))
73
74 (define-macro (define-action action-head . code)
75   (let ((name (car action-head)) (attr (cdr action-head)))
76     `(define ,name
77        (lambda-action ,attr ,@code))))
78
79 (define-macro (lambda-action attr . code)
80   `(lambda (attributes)
81      (let ,(map attr-def attr)
82        ,@code
83        ,(cons 'begin (map attr-save attr))
84        attributes)))
85
86 (define-macro (lambda-look attr . look)
87   (define (process-look look)
88     (cond ((null? look) (values '() '()))
89           (else
90            (let ((line (car look)))
91              (receive (lines images) (process-look (cdr look))
92                       (cond ((string? line)
93                              (let ((var (gensym)))
94                                (values (cons `(draw-texture ,var) lines)
95                                        (cons `(,var (load-texture ,line)) images))))
96                             (else
97                              (values (cons line lines)
98                                      images))))))))
99
100   (receive (look-lines look-images) (process-look look)
101            `(let ,look-images
102                 (lambda (attributes)
103                   (let ,(map attr-def attr)
104                     (glPushMatrix)
105                     ,@look-lines
106                     (glPopMatrix))))))
107
108
109 ;;; Making mobs
110
111 (define-macro (define-mob mob-head . look)
112   (let ((name (car mob-head)) (attr (cdr mob-head)))
113     `(define ,name
114        (lambda-mob ,attr ,@look))))
115
116 (define-macro (lambda-mob attr . look)
117   `(let ((mob #f))
118      (set! mob
119            (let ((attr ',attr) (actions '()) (looks '()))
120              (lambda (option . params)
121                (case option
122                  ((get-attr)
123                   attr)
124                  ((set-attr)
125                   (if (not (null? params)) (set! attr (car params))))
126                  ((get-actions)
127                   actions)
128                  ((set-actions)
129                   (if (not (null? params)) (set! actions (car params))))
130                  ((get-looks)
131                   looks)
132                  ((set-looks)
133                   (if (not (null? params)) (set! looks (car params))))
134                  ((run-actions)
135                   (for-each
136                    (lambda (action)
137                      (set! attr ((cdr action) attr)))
138                    actions))
139                  ((render)
140                   (for-each
141                    (lambda (look)
142                      ((cdr look) attr))
143                    looks))))))
144      (cond ((not (null? ',look))
145             (mob 'set-looks
146                  (list (cons
147                         'default-look
148                         (lambda-look ,attr ,@look))))))
149      mob))
150
151 (define (get-mob-attr mob var)
152   (let ((value (assoc-ref (mob 'get-attr) var)))
153     (if value (car value) #f)))
154
155 (define (set-mob-attr! mob var value)
156   (mob 'set-attr (assoc-set! (mob 'get-attr) var (list value))))
157
158 (define (add-mob-action mob name action)
159   (mob 'set-actions (assoc-set! (mob 'get-actions) name action)))
160
161 (define (quit-mob-action mob name)
162   (mob 'set-actions (assoc-remove! (mob 'get-actions) name)))
163
164 (define (add-mob-look mob name look)
165   (mob 'set-looks (assoc-set! (mob 'get-looks) name look)))
166
167 (define (quit-mob-look mob name)
168   (mob 'set-looks (assoc-remove! (mob 'get-looks) name)))