Initial checkin. Not there yet.
[xor] / cell.c
CommitLineData
fc27aa70 1/* -*-c-*-
2 *
3 * $Id: cell.c,v 1.1 2003/12/12 10:55:30 mdw Exp $
4 *
5 * Cell attributes and behaviour
6 *
7 * (c) 2003 Straylight/Edgeware
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of XOR.
13 *
14 * XOR is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * XOR is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with XOR; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: cell.c,v $
32 * Revision 1.1 2003/12/12 10:55:30 mdw
33 * Initial checkin. Not there yet.
34 *
35 */
36
37/*----- Header files ------------------------------------------------------*/
38
39#include "xor.h"
40
41/*----- Global variables --------------------------------------------------*/
42
43const cellinfo *cellmap[UCHAR_MAX];
44
45/*----- Object behaviour --------------------------------------------------*/
46
47/* --- Player --- */
48
49static void player_hit(game_state *g, int x, int y, int hx, int hy)
50{
51 game_die(g, x, y);
52}
53
54/* --- Bombs --- */
55
56static void hbomb_hit(game_state *g, int x, int y, int hx, int hy)
57{
58 point pt[4];
59 int n = 0;
60
61 pt[n].x = x; pt[n].y = y; n++;
62 pt[n].x = x; pt[n].y = y + 1; n++;
63 pt[n].x = x; pt[n].y = y - 1; n++;
64 if (hx != x) { pt[n].x = hx; pt[n].y = hy; n++; }
65 game_explode(g, pt, n);
66}
67
68static void vbomb_hit(game_state *g, int x, int y, int hx, int hy)
69{
70 point pt[4];
71 int n = 0;
72
73 pt[n].x = x; pt[n].y = y; n++;
74 pt[n].x = x - 1; pt[n].y = y; n++;
75 pt[n].x = x + 1; pt[n].y = y; n++;
76 if (hy != y) { pt[n].x = hx; pt[n].y = hy; n++; }
77 game_explode(g, pt, n);
78}
79
80/* --- Exit --- */
81
82static int exit_nudge(game_state *g, int x, int y, int dx, int dy)
83{
84 if (g->l->m == g->l->mtot) {
85 g->f |= GF_QUIT | GF_WIN;
86 return (1);
87 }
88 return (0);
89}
90
91/* --- Masks --- */
92
93static int mask_nudge(game_state *g, int x, int y, int dx, int dy)
94{
95 undo_mask(g);
96 g->l->m++;
97 return (1);
98}
99
100static int switch_nudge(game_state *g, int x, int y, int dx, int dy)
101{
102 undo_mask(g);
103 undo_levelf(g);
104 g->l->f ^= LF_DARK;
105 g->l->m++;
106 return (1);
107}
108
109/* --- Map segments --- */
110
111static int map_nudge(game_state *g, int x, int y, int dx, int dy)
112{
113 undo_levelf(g);
114 g->l->f |= LF_NWMAP << (CELL(g->l, x, y) - C_NWMAP);
115 return (1);
116}
117
118/* --- Chickens and fish --- */
119
120static int chicken_nudge(game_state *g, int x, int y, int dx, int dy)
121{
122 if (dx) return (0);
123 if (!(cellmap[CELL(g->l, x, y + dy) & CF_CELLMASK]->f & CF_VPASS))
124 return (0);
125 game_moveobj(g, x, y, x, y + dy);
126 return (1);
127}
128
129static int fish_nudge(game_state *g, int x, int y, int dx, int dy)
130{
131 if (dy) return (0);
132 if (!(cellmap[CELL(g->l, x + dx, y) & CF_CELLMASK]->f & CF_HPASS))
133 return (0);
134 game_moveobj(g, x, y, x + dx, y);
135 return (1);
136}
137
138static int chicken_moveh(game_state *g, int x, int y)
139{
140 level *l = g->l;
141 int c;
142
143 c = CELL(l, x - 1, y) & CF_CELLMASK;
144 if (!(cellmap[c]->f & CF_HPASS))
145 return (0);
146 game_moveobj(g, x, y, x - 1, y);
147 x--;
148 c = CELL(l, x - 1, y);
149 if (!(c & CF_INFLIGHT) && cellmap[c & CF_CELLMASK]->hit)
150 cellmap[c & CF_CELLMASK]->hit(g, x - 1, y, x, y);
151 if (cellmap[CELL(l, x - 1, y) & CF_CELLMASK]->f & CF_HPASS)
152 CELLSETFL(l, x, y, CF_INFLIGHT);
153 else
154 CELLCLRFL(l, x, y, CF_INFLIGHT);
155 return (1);
156}
157
158static int fish_movev(game_state *g, int x, int y)
159{
160 level *l = g->l;
161 int c;
162
163 c = CELL(l, x, y + 1) & CF_CELLMASK;
164 if (!(cellmap[c]->f & CF_VPASS))
165 return (0);
166 game_moveobj(g, x, y, x, y + 1);
167 y++;
168 c = CELL(l, x, y + 1);
169 if (!(c & CF_INFLIGHT) && cellmap[c & CF_CELLMASK]->hit)
170 cellmap[c & CF_CELLMASK]->hit(g, x, y + 1, x, y);
171 if (cellmap[CELL(l, x, y + 1) & CF_CELLMASK]->f & CF_VPASS)
172 CELLSETFL(l, x, y, CF_INFLIGHT);
173 else
174 CELLCLRFL(l, x, y, CF_INFLIGHT);
175 return (1);
176}
177
178/* --- Dollies --- */
179
180static int dolly_nudge(game_state *g, int x, int y, int dx, int dy)
181{
182 if (CELL(g->l, x + dx, y + dy) != C_EMPTY)
183 return (0);
184 game_moveobj(g, x, y, x + dx, y + dy);
185 x += dx; y += dy;
186 if (CELL(g->l, x + dx, y + dy) == C_EMPTY) {
187 if (dx < 0) CELLSETFL(g->l, x, y, CF_DOLLYLEFT | CF_INFLIGHT);
188 else if (dx > 0) CELLSETFL(g->l, x, y, CF_DOLLYRIGHT | CF_INFLIGHT);
189 else if (dy < 0) CELLSETFL(g->l, x, y, CF_DOLLYUP | CF_INFLIGHT);
190 else if (dy > 0) CELLSETFL(g->l, x, y, CF_DOLLYDOWN | CF_INFLIGHT);
191 }
192 return (1);
193}
194
195static int dolly_moveh(game_state *g, int x, int y)
196{
197 int c = CELL(g->l, x, y);
198 int dx;
199
200 if (!(c & CF_INFLIGHT)) return (0);
201 switch (c & CF_DOLLYMASK) {
202 case CF_DOLLYLEFT: dx = -1; break;
203 case CF_DOLLYRIGHT: dx = +1; break;
204 default: return (0);
205 }
206 game_moveobj(g, x, y, x + dx, y);
207 x += dx;
208 if (CELL(g->l, x + dx, y) != C_EMPTY)
209 CELLCLRFL(g->l, x, y, CF_DOLLYMASK | CF_INFLIGHT);
210 return (1);
211}
212
213static int dolly_movev(game_state *g, int x, int y)
214{
215 int c = CELL(g->l, x, y);
216 int dy;
217
218 if (!(c & CF_INFLIGHT)) return (0);
219 switch (c & CF_DOLLYMASK) {
220 case CF_DOLLYUP: dy = -1; break;
221 case CF_DOLLYDOWN: dy = +1; break;
222 default: return (0);
223 }
224 game_moveobj(g, x, y, x, y + dy);
225 y += dy;
226 if (CELL(g->l, x, y + dy) != C_EMPTY)
227 CELLCLRFL(g->l, x, y, CF_DOLLYMASK | CF_INFLIGHT);
228 return (1);
229}
230
231/*----- The object table --------------------------------------------------*/
232
233static cellinfo celltab[] = {
234
235 { /* cell type */ C_PLAYER,
236 /* flags */ CF_PLAYER,
237 /* hit */ player_hit,
238 /* nudge */ 0,
239 /* horiz move */ 0,
240 /* vert move */ 0,
241 },
242
243 { /* cell type */ C_SPARE,
244 /* flags */ CF_PLAYER,
245 /* hit */ player_hit,
246 /* nudge */ 0,
247 /* horiz move */ 0,
248 /* vert move */ 0,
249 },
250
251 { /* cell type */ C_WALL,
252 /* flags */ CF_HIDE | CF_MAP,
253 /* hit */ 0,
254 /* nudge */ 0,
255 /* horiz move */ 0,
256 /* vert move */ 0,
257 },
258
259 { /* cell type */ C_EXIT,
260 /* flags */ CF_MAP,
261 /* hit */ 0,
262 /* nudge */ exit_nudge,
263 /* horiz move */ 0,
264 /* vert move */ 0,
265 },
266
267 { /* cell type */ C_EMPTY,
268 /* flags */ CF_HPASS | CF_VPASS,
269 /* hit */ 0,
270 /* nudge */ 0,
271 /* horiz move */ 0,
272 /* vert move */ 0,
273 },
274
275 { /* cell type */ C_MASK,
276 /* flags */ CF_MASK | CF_MAP,
277 /* hit */ 0,
278 /* nudge */ mask_nudge,
279 /* horiz move */ 0,
280 /* vert move */ 0,
281 },
282
283 { /* cell type */ C_NWMAP,
284 /* flags */ 0,
285 /* hit */ 0,
286 /* nudge */ map_nudge,
287 /* horiz move */ 0,
288 /* vert move */ 0,
289 },
290
291 { /* cell type */ C_NEMAP,
292 /* flags */ 0,
293 /* hit */ 0,
294 /* nudge */ map_nudge,
295 /* horiz move */ 0,
296 /* vert move */ 0,
297 },
298
299 { /* cell type */ C_SWMAP,
300 /* flags */ 0,
301 /* hit */ 0,
302 /* nudge */ map_nudge,
303 /* horiz move */ 0,
304 /* vert move */ 0,
305 },
306
307 { /* cell type */ C_SEMAP,
308 /* flags */ 0,
309 /* hit */ 0,
310 /* nudge */ map_nudge,
311 /* horiz move */ 0,
312 /* vert move */ 0,
313 },
314
315 { /* cell type */ C_DOT,
316 /* flags */ CF_HPASS,
317 /* hit */ 0,
318 /* nudge */ 0,
319 /* horiz move */ 0,
320 /* vert move */ 0,
321 },
322
323 { /* cell type */ C_WAVE,
324 /* flags */ CF_VPASS,
325 /* hit */ 0,
326 /* nudge */ 0,
327 /* horiz move */ 0,
328 /* vert move */ 0,
329 },
330
331 { /* cell type */ C_CHICKEN,
332 /* flags */ 0,
333 /* hit */ 0,
334 /* nudge */ chicken_nudge,
335 /* horiz move */ chicken_moveh,
336 /* vert move */ 0,
337 },
338
339 { /* cell type */ C_FISH,
340 /* flags */ 0,
341 /* hit */ 0,
342 /* nudge */ fish_nudge,
343 /* horiz move */ 0,
344 /* vert move */ fish_movev,
345 },
346
347 { /* cell type */ C_HBOMB,
348 /* flags */ 0,
349 /* hit */ hbomb_hit,
350 /* nudge */ chicken_nudge,
351 /* horiz move */ chicken_moveh,
352 /* vert move */ 0,
353 },
354
355 { /* cell type */ C_VBOMB,
356 /* flags */ 0,
357 /* hit */ vbomb_hit,
358 /* nudge */ fish_nudge,
359 /* horiz move */ 0,
360 /* vert move */ fish_movev,
361 },
362
363 { /* cell type */ C_DOLLY,
364 /* flags */ 0,
365 /* hit */ 0,
366 /* nudge */ dolly_nudge,
367 /* horiz move */ dolly_moveh,
368 /* vert move */ dolly_movev,
369 },
370
371 { /* cell type */ C_SWITCH,
372 /* flags */ CF_MASK | CF_MAP,
373 /* hit */ 0,
374 /* nudge */ switch_nudge,
375 /* horiz move */ 0,
376 /* vert move */ 0,
377 },
378
379 { /* cell type */ C_BMUS,
380 /* flags */ 0,
381 /* hit */ 0,
382 /* nudge */ 0,
383 /* horiz move */ 0,
384 /* vert move */ 0,
385 },
386
387 { /* cell type */ 0,
388 /* flags */ 0,
389 /* hit */ 0,
390 /* nudge */ 0,
391 /* horiz move */ 0,
392 /* vert move */ 0,
393 }
394};
395
396void cellinfo_init(void)
397{
398 int i;
399
400 for (i = 0; celltab[i].c; i++) cellmap[celltab[i].c] = &celltab[i];
401}
402
403/*----- That's all, folks -------------------------------------------------*/