5 * Cell attributes and behaviour
7 * (c) 2003 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of XOR.
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.
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.
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.
29 /*----- Header files ------------------------------------------------------*/
33 /*----- Global variables --------------------------------------------------*/
35 const cellinfo *cellmap[UCHAR_MAX];
37 /*----- Object behaviour --------------------------------------------------*/
41 static void player_hit(game_state *g, int x, int y, int hx, int hy)
48 static void hbomb_hit(game_state *g, int x, int y, int hx, int hy)
53 pt[n].x = x; pt[n].y = y; n++;
54 pt[n].x = x; pt[n].y = y + 1; n++;
55 pt[n].x = x; pt[n].y = y - 1; n++;
56 if (hx != x) { pt[n].x = hx; pt[n].y = hy; n++; }
57 game_explode(g, pt, n);
60 static void vbomb_hit(game_state *g, int x, int y, int hx, int hy)
65 pt[n].x = x; pt[n].y = y; n++;
66 pt[n].x = x - 1; pt[n].y = y; n++;
67 pt[n].x = x + 1; pt[n].y = y; n++;
68 if (hy != y) { pt[n].x = hx; pt[n].y = hy; n++; }
69 game_explode(g, pt, n);
74 static int exit_nudge(game_state *g, int x, int y, int dx, int dy)
76 if (g->l->m == g->l->mtot) {
77 g->f |= GF_QUIT | GF_WIN;
85 static int mask_nudge(game_state *g, int x, int y, int dx, int dy)
92 static int switch_nudge(game_state *g, int x, int y, int dx, int dy)
101 /* --- Map segments --- */
103 static int map_nudge(game_state *g, int x, int y, int dx, int dy)
106 g->l->f |= LF_NWMAP << (CELL(g->l, x, y) - C_NWMAP);
110 /* --- Chickens and fish --- */
112 static int chicken_nudge(game_state *g, int x, int y, int dx, int dy)
115 if (!(cellmap[CELL(g->l, x, y + dy) & CF_CELLMASK]->f & CF_VPASS))
117 game_moveobj(g, x, y, x, y + dy);
121 static int fish_nudge(game_state *g, int x, int y, int dx, int dy)
124 if (!(cellmap[CELL(g->l, x + dx, y) & CF_CELLMASK]->f & CF_HPASS))
126 game_moveobj(g, x, y, x + dx, y);
130 static int chicken_moveh(game_state *g, int x, int y)
135 c = CELL(l, x - 1, y) & CF_CELLMASK;
136 if (!(cellmap[c]->f & CF_HPASS))
138 game_moveobj(g, x, y, x - 1, y);
140 c = CELL(l, x - 1, y);
141 if (!(c & CF_INFLIGHT) && cellmap[c & CF_CELLMASK]->hit)
142 cellmap[c & CF_CELLMASK]->hit(g, x - 1, y, x, y);
143 if (cellmap[CELL(l, x - 1, y) & CF_CELLMASK]->f & CF_HPASS)
144 CELLSETFL(l, x, y, CF_INFLIGHT);
146 CELLCLRFL(l, x, y, CF_INFLIGHT);
150 static int fish_movev(game_state *g, int x, int y)
155 c = CELL(l, x, y + 1) & CF_CELLMASK;
156 if (!(cellmap[c]->f & CF_VPASS))
158 game_moveobj(g, x, y, x, y + 1);
160 c = CELL(l, x, y + 1);
161 if (!(c & CF_INFLIGHT) && cellmap[c & CF_CELLMASK]->hit)
162 cellmap[c & CF_CELLMASK]->hit(g, x, y + 1, x, y);
163 if (cellmap[CELL(l, x, y + 1) & CF_CELLMASK]->f & CF_VPASS)
164 CELLSETFL(l, x, y, CF_INFLIGHT);
166 CELLCLRFL(l, x, y, CF_INFLIGHT);
170 /* --- Dollies --- */
172 static int dolly_nudge(game_state *g, int x, int y, int dx, int dy)
174 if (CELL(g->l, x + dx, y + dy) != C_EMPTY)
176 game_moveobj(g, x, y, x + dx, y + dy);
178 if (CELL(g->l, x + dx, y + dy) == C_EMPTY) {
179 if (dx < 0) CELLSETFL(g->l, x, y, CF_DOLLYLEFT | CF_INFLIGHT);
180 else if (dx > 0) CELLSETFL(g->l, x, y, CF_DOLLYRIGHT | CF_INFLIGHT);
181 else if (dy < 0) CELLSETFL(g->l, x, y, CF_DOLLYUP | CF_INFLIGHT);
182 else if (dy > 0) CELLSETFL(g->l, x, y, CF_DOLLYDOWN | CF_INFLIGHT);
187 static int dolly_moveh(game_state *g, int x, int y)
189 int c = CELL(g->l, x, y);
192 if (!(c & CF_INFLIGHT)) return (0);
193 switch (c & CF_DOLLYMASK) {
194 case CF_DOLLYLEFT: dx = -1; break;
195 case CF_DOLLYRIGHT: dx = +1; break;
198 game_moveobj(g, x, y, x + dx, y);
200 if (CELL(g->l, x + dx, y) != C_EMPTY)
201 CELLCLRFL(g->l, x, y, CF_DOLLYMASK | CF_INFLIGHT);
205 static int dolly_movev(game_state *g, int x, int y)
207 int c = CELL(g->l, x, y);
210 if (!(c & CF_INFLIGHT)) return (0);
211 switch (c & CF_DOLLYMASK) {
212 case CF_DOLLYUP: dy = -1; break;
213 case CF_DOLLYDOWN: dy = +1; break;
216 game_moveobj(g, x, y, x, y + dy);
218 if (CELL(g->l, x, y + dy) != C_EMPTY)
219 CELLCLRFL(g->l, x, y, CF_DOLLYMASK | CF_INFLIGHT);
223 /*----- The object table --------------------------------------------------*/
225 static cellinfo celltab[] = {
227 { /* cell type */ C_PLAYER,
228 /* flags */ CF_PLAYER,
229 /* hit */ player_hit,
235 { /* cell type */ C_SPARE,
236 /* flags */ CF_PLAYER,
237 /* hit */ player_hit,
243 { /* cell type */ C_WALL,
244 /* flags */ CF_HIDE | CF_MAP,
251 { /* cell type */ C_EXIT,
254 /* nudge */ exit_nudge,
259 { /* cell type */ C_EMPTY,
260 /* flags */ CF_HPASS | CF_VPASS,
267 { /* cell type */ C_MASK,
268 /* flags */ CF_MASK | CF_MAP,
270 /* nudge */ mask_nudge,
275 { /* cell type */ C_NWMAP,
278 /* nudge */ map_nudge,
283 { /* cell type */ C_NEMAP,
286 /* nudge */ map_nudge,
291 { /* cell type */ C_SWMAP,
294 /* nudge */ map_nudge,
299 { /* cell type */ C_SEMAP,
302 /* nudge */ map_nudge,
307 { /* cell type */ C_DOT,
308 /* flags */ CF_HPASS,
315 { /* cell type */ C_WAVE,
316 /* flags */ CF_VPASS,
323 { /* cell type */ C_CHICKEN,
326 /* nudge */ chicken_nudge,
327 /* horiz move */ chicken_moveh,
331 { /* cell type */ C_FISH,
334 /* nudge */ fish_nudge,
336 /* vert move */ fish_movev,
339 { /* cell type */ C_HBOMB,
342 /* nudge */ chicken_nudge,
343 /* horiz move */ chicken_moveh,
347 { /* cell type */ C_VBOMB,
350 /* nudge */ fish_nudge,
352 /* vert move */ fish_movev,
355 { /* cell type */ C_DOLLY,
358 /* nudge */ dolly_nudge,
359 /* horiz move */ dolly_moveh,
360 /* vert move */ dolly_movev,
363 { /* cell type */ C_SWITCH,
364 /* flags */ CF_MASK | CF_MAP,
366 /* nudge */ switch_nudge,
371 { /* cell type */ C_BMUS,
388 void cellinfo_init(void)
392 for (i = 0; celltab[i].c; i++) cellmap[celltab[i].c] = &celltab[i];
395 /*----- That's all, folks -------------------------------------------------*/