937969ec48e5aa20e5cfabe5491a56d5ce5294ae
3 * $Id: game.c,v 1.1 2003/12/12 10:55:30 mdw Exp $
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 /*----- Main code ---------------------------------------------------------*/
43 #define G_CELLSET(g, x, y, c) do { \
44 undo_cell((g), (x), (y), (c)); \
45 CELLSET((g)->l, (x), (y), (c)); \
48 void game_die(game_state
*g
, int x
, int y
)
52 for (p
= g
->p
; p
&& (p
->x
!= x
|| p
->y
!= y
); p
= p
->next
) ;
57 G_CELLSET(g
, p
->x
, p
->y
, C_EMPTY
);
58 for (p
= g
->p
; p
&& (p
->f
& PF_DEAD
); p
= p
->next
) ;
59 if (p
) ui_message(g
->p
->u
, "Whoops!");
60 else ui_message(g
->p
->u
, "Gotcha!");
63 void game_explode(game_state
*g
, const point
*pt
, int n
)
67 ui_explode(g
->p
->u
, pt
, n
);
68 for (i
= 0; i
< n
; i
++) game_die(g
, pt
[i
].x
, pt
[i
].y
);
69 for (i
= 0; i
< n
; i
++) G_CELLSET(g
, pt
[i
].x
, pt
[i
].y
, C_EMPTY
);
72 void game_moveobj(game_state
*g
, int x
, int y
, int xx
, int yy
)
74 int c
= CELL(g
->l
, x
, y
);
75 G_CELLSET(g
, x
, y
, C_EMPTY
);
76 G_CELLSET(g
, xx
, yy
, c
);
79 static int doupdateh(game_state
*g
)
85 for (j
= 0; j
< l
->h
; j
++) {
86 for (i
= 0; i
< l
->w
; i
++) {
87 c
= CELL(l
, i
, j
) & CF_CELLMASK
;
88 if (cellmap
[c
]->moveh
&& cellmap
[c
]->moveh(g
, i
, j
)) rc
= 1;
91 if (rc
) ui_frame(g
->p
->u
);
95 static int doupdatev(game_state
*g
)
101 for (i
= 0; i
< l
->w
; i
++) {
102 for (j
= l
->h
- 1; j
>= 0; j
--) {
103 c
= CELL(l
, i
, j
) & CF_CELLMASK
;
104 if (cellmap
[c
]->movev
&& cellmap
[c
]->movev(g
, i
, j
)) rc
= 1;
107 if (rc
) ui_frame(g
->p
->u
);
111 static void updatev(game_state
*g
) { while (doupdatev(g
) || doupdateh(g
)) ; }
112 static void updateh(game_state
*g
) { while (doupdateh(g
) || doupdatev(g
)) ; }
114 void game_switchto(game_state
*g
, game_player
*p
)
116 /* --- Don't stash undo records here --- */
118 if (!(g
->p
->f
& PF_DEAD
))
119 CELLSET(g
->l
, g
->p
->x
, g
->p
->y
, C_SPARE
);
120 g
->p
->prev
= g
->ptail
;
122 g
->ptail
->next
= g
->p
;
127 CELLSET(g
->l
, g
->p
->x
, g
->p
->y
, C_PLAYER
);
131 int game_switch(game_state
*g
)
137 for (p
= g
->p
->next
; p
&& (p
->f
& PF_DEAD
); p
= p
->next
)
140 if (g
->l
->v
>= g
->l
->vtot
) return (1);
146 void game_move(game_state
*g
, int dx
, int dy
)
150 int c
= CELL(g
->l
, x
+ dx
, y
+ dy
) & CF_CELLMASK
;
152 if (g
->p
->f
& PF_DEAD
) return;
153 if (g
->l
->v
>= g
->l
->vtot
) return;
154 if ((cellmap
[c
]->f
& ((dx ? CF_HPASS
: 0) | (dy ? CF_VPASS
: 0))) ||
155 (cellmap
[c
]->nudge
&&
156 cellmap
[c
]->nudge(g
, x
+ dx
, y
+ dy
, dx
, dy
) > 0)) {
158 game_moveobj(g
, x
, y
, x
+ dx
, y
+ dy
);
162 ui_track(g
->p
->u
, x
+ dx
, y
+ dy
);
163 if (dx
) updatev(g
); else updateh(g
);
165 if (g
->p
->f
& PF_DEAD
) game_switch(g
);
169 void game_quit(game_state
*g
) { g
->f
|= GF_QUIT
; }
171 static void addplayer(game_state
*g
, int x
, int y
)
173 game_player
*p
= CREATE(game_player
);
177 p
->u
= ui_start(g
->l
, x
, y
);
180 if (g
->ptail
) g
->ptail
->next
= p
; else g
->p
= p
;
184 void game_go(level
*l
)
190 lev_write(g
.l
, stdout
);
193 lev_findcell(l
, C_PLAYER
, &x
, &y
);
195 if (lev_findcell(l
, C_SPARE
, &x
, &y
)) {
198 while (lev_findnext(l
, C_SPARE
, &x
, &y
));
202 while (!(g
.f
& GF_QUIT
)) {
211 /*----- That's all, folks -------------------------------------------------*/