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 -------------------------------------------------*/