a9e87b7e266e2c85174fbdcb11bacaca3898f926
3 * $Id: cell.c,v 1.1 2003/12/12 10:55:30 mdw Exp $
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 /*----- Revision history --------------------------------------------------*
32 * Revision 1.1 2003/12/12 10:55:30 mdw
33 * Initial checkin. Not there yet.
37 /*----- Header files ------------------------------------------------------*/
41 /*----- Global variables --------------------------------------------------*/
43 const cellinfo
*cellmap
[UCHAR_MAX
];
45 /*----- Object behaviour --------------------------------------------------*/
49 static void player_hit(game_state
*g
, int x
, int y
, int hx
, int hy
)
56 static void hbomb_hit(game_state
*g
, int x
, int y
, int hx
, int hy
)
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
);
68 static void vbomb_hit(game_state
*g
, int x
, int y
, int hx
, int hy
)
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
);
82 static int exit_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
84 if (g
->l
->m
== g
->l
->mtot
) {
85 g
->f
|= GF_QUIT
| GF_WIN
;
93 static int mask_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
100 static int switch_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
109 /* --- Map segments --- */
111 static int map_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
114 g
->l
->f
|= LF_NWMAP
<< (CELL(g
->l
, x
, y
) - C_NWMAP
);
118 /* --- Chickens and fish --- */
120 static int chicken_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
123 if (!(cellmap
[CELL(g
->l
, x
, y
+ dy
) & CF_CELLMASK
]->f
& CF_VPASS
))
125 game_moveobj(g
, x
, y
, x
, y
+ dy
);
129 static int fish_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
132 if (!(cellmap
[CELL(g
->l
, x
+ dx
, y
) & CF_CELLMASK
]->f
& CF_HPASS
))
134 game_moveobj(g
, x
, y
, x
+ dx
, y
);
138 static int chicken_moveh(game_state
*g
, int x
, int y
)
143 c
= CELL(l
, x
- 1, y
) & CF_CELLMASK
;
144 if (!(cellmap
[c
]->f
& CF_HPASS
))
146 game_moveobj(g
, x
, y
, x
- 1, y
);
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
);
154 CELLCLRFL(l
, x
, y
, CF_INFLIGHT
);
158 static int fish_movev(game_state
*g
, int x
, int y
)
163 c
= CELL(l
, x
, y
+ 1) & CF_CELLMASK
;
164 if (!(cellmap
[c
]->f
& CF_VPASS
))
166 game_moveobj(g
, x
, y
, x
, y
+ 1);
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
);
174 CELLCLRFL(l
, x
, y
, CF_INFLIGHT
);
178 /* --- Dollies --- */
180 static int dolly_nudge(game_state
*g
, int x
, int y
, int dx
, int dy
)
182 if (CELL(g
->l
, x
+ dx
, y
+ dy
) != C_EMPTY
)
184 game_moveobj(g
, x
, y
, 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
);
195 static int dolly_moveh(game_state
*g
, int x
, int y
)
197 int c
= CELL(g
->l
, x
, y
);
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;
206 game_moveobj(g
, x
, y
, x
+ dx
, y
);
208 if (CELL(g
->l
, x
+ dx
, y
) != C_EMPTY
)
209 CELLCLRFL(g
->l
, x
, y
, CF_DOLLYMASK
| CF_INFLIGHT
);
213 static int dolly_movev(game_state
*g
, int x
, int y
)
215 int c
= CELL(g
->l
, x
, y
);
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;
224 game_moveobj(g
, x
, y
, x
, y
+ dy
);
226 if (CELL(g
->l
, x
, y
+ dy
) != C_EMPTY
)
227 CELLCLRFL(g
->l
, x
, y
, CF_DOLLYMASK
| CF_INFLIGHT
);
231 /*----- The object table --------------------------------------------------*/
233 static cellinfo celltab
[] = {
235 { /* cell type */ C_PLAYER
,
236 /* flags */ CF_PLAYER
,
237 /* hit */ player_hit
,
243 { /* cell type */ C_SPARE
,
244 /* flags */ CF_PLAYER
,
245 /* hit */ player_hit
,
251 { /* cell type */ C_WALL
,
252 /* flags */ CF_HIDE
| CF_MAP
,
259 { /* cell type */ C_EXIT
,
262 /* nudge */ exit_nudge
,
267 { /* cell type */ C_EMPTY
,
268 /* flags */ CF_HPASS
| CF_VPASS
,
275 { /* cell type */ C_MASK
,
276 /* flags */ CF_MASK
| CF_MAP
,
278 /* nudge */ mask_nudge
,
283 { /* cell type */ C_NWMAP
,
286 /* nudge */ map_nudge
,
291 { /* cell type */ C_NEMAP
,
294 /* nudge */ map_nudge
,
299 { /* cell type */ C_SWMAP
,
302 /* nudge */ map_nudge
,
307 { /* cell type */ C_SEMAP
,
310 /* nudge */ map_nudge
,
315 { /* cell type */ C_DOT
,
316 /* flags */ CF_HPASS
,
323 { /* cell type */ C_WAVE
,
324 /* flags */ CF_VPASS
,
331 { /* cell type */ C_CHICKEN
,
334 /* nudge */ chicken_nudge
,
335 /* horiz move */ chicken_moveh
,
339 { /* cell type */ C_FISH
,
342 /* nudge */ fish_nudge
,
344 /* vert move */ fish_movev
,
347 { /* cell type */ C_HBOMB
,
350 /* nudge */ chicken_nudge
,
351 /* horiz move */ chicken_moveh
,
355 { /* cell type */ C_VBOMB
,
358 /* nudge */ fish_nudge
,
360 /* vert move */ fish_movev
,
363 { /* cell type */ C_DOLLY
,
366 /* nudge */ dolly_nudge
,
367 /* horiz move */ dolly_moveh
,
368 /* vert move */ dolly_movev
,
371 { /* cell type */ C_SWITCH
,
372 /* flags */ CF_MASK
| CF_MAP
,
374 /* nudge */ switch_nudge
,
379 { /* cell type */ C_BMUS
,
396 void cellinfo_init(void)
400 for (i
= 0; celltab
[i
].c
; i
++) cellmap
[celltab
[i
].c
] = &celltab
[i
];
403 /*----- That's all, folks -------------------------------------------------*/