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 /*----- Main code ---------------------------------------------------------*/
35 #define G_CELLSET(g, x, y, c) do { \
36 undo_cell((g), (x), (y), (c)); \
37 CELLSET((g)->l, (x), (y), (c)); \
40 void game_die(game_state
*g
, int x
, int y
)
44 for (p
= g
->p
; p
&& (p
->x
!= x
|| p
->y
!= y
); p
= p
->next
) ;
49 G_CELLSET(g
, p
->x
, p
->y
, C_EMPTY
);
50 for (p
= g
->p
; p
&& (p
->f
& PF_DEAD
); p
= p
->next
) ;
51 if (p
) ui_message(g
->p
->u
, "Whoops!");
52 else ui_message(g
->p
->u
, "Gotcha!");
55 void game_explode(game_state
*g
, const point
*pt
, int n
)
59 ui_explode(g
->p
->u
, pt
, n
);
60 for (i
= 0; i
< n
; i
++) game_die(g
, pt
[i
].x
, pt
[i
].y
);
61 for (i
= 0; i
< n
; i
++) G_CELLSET(g
, pt
[i
].x
, pt
[i
].y
, C_EMPTY
);
64 void game_moveobj(game_state
*g
, int x
, int y
, int xx
, int yy
)
66 int c
= CELL(g
->l
, x
, y
);
67 G_CELLSET(g
, x
, y
, C_EMPTY
);
68 G_CELLSET(g
, xx
, yy
, c
);
71 static int doupdateh(game_state
*g
)
77 for (j
= 0; j
< l
->h
; j
++) {
78 for (i
= 0; i
< l
->w
; i
++) {
79 c
= CELL(l
, i
, j
) & CF_CELLMASK
;
80 if (cellmap
[c
]->moveh
&& cellmap
[c
]->moveh(g
, i
, j
)) rc
= 1;
83 if (rc
) ui_frame(g
->p
->u
);
87 static int doupdatev(game_state
*g
)
93 for (i
= 0; i
< l
->w
; i
++) {
94 for (j
= l
->h
- 1; j
>= 0; j
--) {
95 c
= CELL(l
, i
, j
) & CF_CELLMASK
;
96 if (cellmap
[c
]->movev
&& cellmap
[c
]->movev(g
, i
, j
)) rc
= 1;
99 if (rc
) ui_frame(g
->p
->u
);
103 static void updatev(game_state
*g
) { while (doupdatev(g
) || doupdateh(g
)) ; }
104 static void updateh(game_state
*g
) { while (doupdateh(g
) || doupdatev(g
)) ; }
106 void game_switchto(game_state
*g
, game_player
*p
)
108 /* --- Don't stash undo records here --- */
110 if (!(g
->p
->f
& PF_DEAD
))
111 CELLSET(g
->l
, g
->p
->x
, g
->p
->y
, C_SPARE
);
112 g
->p
->prev
= g
->ptail
;
114 g
->ptail
->next
= g
->p
;
118 CELLSET(g
->l
, g
->p
->x
, g
->p
->y
, C_PLAYER
);
122 int game_switch(game_state
*g
)
128 for (p
= g
->p
->next
; p
&& (p
->f
& PF_DEAD
); p
= p
->next
)
131 if (g
->l
->v
>= g
->l
->vtot
) return (1);
138 void game_move(game_state
*g
, int dx
, int dy
)
142 int c
= CELL(g
->l
, x
+ dx
, y
+ dy
) & CF_CELLMASK
;
144 if (g
->p
->f
& PF_DEAD
) return;
145 if (g
->l
->v
>= g
->l
->vtot
) return;
146 if ((cellmap
[c
]->f
& ((dx ? CF_HPASS
: 0) | (dy ? CF_VPASS
: 0))) ||
147 (cellmap
[c
]->nudge
&&
148 cellmap
[c
]->nudge(g
, x
+ dx
, y
+ dy
, dx
, dy
) > 0)) {
150 game_moveobj(g
, x
, y
, x
+ dx
, y
+ dy
);
154 ui_track(g
->p
->u
, x
+ dx
, y
+ dy
);
155 if (dx
) updatev(g
); else updateh(g
);
157 if (g
->p
->f
& PF_DEAD
) game_switch(g
);
161 void game_quit(game_state
*g
) { g
->f
|= GF_QUIT
; }
163 static void addplayer(game_state
*g
, int x
, int y
)
165 game_player
*p
= CREATE(game_player
);
169 p
->u
= ui_start(g
->l
, x
, y
);
172 if (g
->ptail
) g
->ptail
->next
= p
; else g
->p
= p
;
176 void game_go(level
*l
)
182 lev_write(g
.l
, stdout
);
185 lev_findcell(l
, C_PLAYER
, &x
, &y
);
187 if (lev_findcell(l
, C_SPARE
, &x
, &y
)) {
190 while (lev_findnext(l
, C_SPARE
, &x
, &y
));
194 while (!(g
.f
& GF_QUIT
)) {
203 /*----- That's all, folks -------------------------------------------------*/