draw.c revision 1.2 1 /* $NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $ */
2 /*
3 * Hunt
4 * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
5 * San Francisco, California
6 */
7
8 #include <sys/cdefs.h>
9 #ifndef lint
10 __RCSID("$NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $");
11 #endif /* not lint */
12
13 # include "hunt.h"
14
15 void
16 drawmaze(pp)
17 PLAYER *pp;
18 {
19 int x;
20 char *sp;
21 int y;
22 char *endp;
23
24 clrscr(pp);
25 outstr(pp, pp->p_maze[0], WIDTH);
26 for (y = 1; y < HEIGHT - 1; y++) {
27 endp = &pp->p_maze[y][WIDTH];
28 for (x = 0, sp = pp->p_maze[y]; sp < endp; x++, sp++)
29 if (*sp != SPACE) {
30 cgoto(pp, y, x);
31 if (pp->p_x == x && pp->p_y == y)
32 outch(pp, translate(*sp));
33 else if (isplayer(*sp))
34 outch(pp, player_sym(pp, y, x));
35 else
36 outch(pp, *sp);
37 }
38 }
39 cgoto(pp, HEIGHT - 1, 0);
40 outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH);
41 drawstatus(pp);
42 }
43
44 /*
45 * drawstatus - put up the status lines (this assumes the screen
46 * size is 80x24 with the maze being 64x24)
47 */
48 void
49 drawstatus(pp)
50 PLAYER *pp;
51 {
52 int i;
53 PLAYER *np;
54
55 cgoto(pp, STAT_AMMO_ROW, STAT_LABEL_COL);
56 outstr(pp, "Ammo:", 5);
57 (void) sprintf(Buf, "%3d", pp->p_ammo);
58 cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
59 outstr(pp, Buf, 3);
60
61 cgoto(pp, STAT_GUN_ROW, STAT_LABEL_COL);
62 outstr(pp, "Gun:", 4);
63 cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
64 outstr(pp, (pp->p_ncshot < MAXNCSHOT) ? " ok" : " ", 3);
65
66 cgoto(pp, STAT_DAM_ROW, STAT_LABEL_COL);
67 outstr(pp, "Damage:", 7);
68 (void) sprintf(Buf, "%2d/%2d", pp->p_damage, pp->p_damcap);
69 cgoto(pp, STAT_DAM_ROW, STAT_VALUE_COL);
70 outstr(pp, Buf, 5);
71
72 cgoto(pp, STAT_KILL_ROW, STAT_LABEL_COL);
73 outstr(pp, "Kills:", 6);
74 (void) sprintf(Buf, "%3d", (pp->p_damcap - MAXDAM) / 2);
75 cgoto(pp, STAT_KILL_ROW, STAT_VALUE_COL);
76 outstr(pp, Buf, 3);
77
78 cgoto(pp, STAT_PLAY_ROW, STAT_LABEL_COL);
79 outstr(pp, "Player:", 7);
80 for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++) {
81 (void) sprintf(Buf, "%5.2f%c%-10.10s %c", np->p_ident->i_score,
82 stat_char(np), np->p_ident->i_name,
83 np->p_ident->i_team);
84 cgoto(pp, i++, STAT_NAME_COL);
85 outstr(pp, Buf, STAT_NAME_LEN);
86 }
87
88 # ifdef MONITOR
89 cgoto(pp, STAT_MON_ROW, STAT_LABEL_COL);
90 outstr(pp, "Monitor:", 8);
91 for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++) {
92 (void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
93 np->p_ident->i_name, np->p_ident->i_team);
94 cgoto(pp, i++, STAT_NAME_COL);
95 outstr(pp, Buf, STAT_NAME_LEN);
96 }
97 # endif
98 }
99
100 void
101 look(pp)
102 PLAYER *pp;
103 {
104 int x, y;
105
106 x = pp->p_x;
107 y = pp->p_y;
108
109 check(pp, y - 1, x - 1);
110 check(pp, y - 1, x );
111 check(pp, y - 1, x + 1);
112 check(pp, y , x - 1);
113 check(pp, y , x );
114 check(pp, y , x + 1);
115 check(pp, y + 1, x - 1);
116 check(pp, y + 1, x );
117 check(pp, y + 1, x + 1);
118
119 switch (pp->p_face) {
120 case LEFTS:
121 see(pp, LEFTS);
122 see(pp, ABOVE);
123 see(pp, BELOW);
124 break;
125 case RIGHT:
126 see(pp, RIGHT);
127 see(pp, ABOVE);
128 see(pp, BELOW);
129 break;
130 case ABOVE:
131 see(pp, ABOVE);
132 see(pp, LEFTS);
133 see(pp, RIGHT);
134 break;
135 case BELOW:
136 see(pp, BELOW);
137 see(pp, LEFTS);
138 see(pp, RIGHT);
139 break;
140 # ifdef FLY
141 case FLYER:
142 break;
143 # endif
144 }
145 cgoto(pp, y, x);
146 }
147
148 void
149 see(pp, face)
150 PLAYER *pp;
151 int face;
152 {
153 char *sp;
154 int y, x, i, cnt;
155
156 x = pp->p_x;
157 y = pp->p_y;
158
159 switch (face) {
160 case LEFTS:
161 sp = &Maze[y][x];
162 for (i = 0; See_over[(int)*--sp]; i++)
163 continue;
164
165 if (i == 0)
166 break;
167
168 cnt = i;
169 x = pp->p_x - 1;
170 --y;
171 while (i--)
172 check(pp, y, --x);
173 i = cnt;
174 x = pp->p_x - 1;
175 ++y;
176 while (i--)
177 check(pp, y, --x);
178 i = cnt;
179 x = pp->p_x - 1;
180 ++y;
181 while (i--)
182 check(pp, y, --x);
183 break;
184 case RIGHT:
185 sp = &Maze[y][++x];
186 for (i = 0; See_over[(int)*sp++]; i++)
187 continue;
188
189 if (i == 0)
190 break;
191
192 cnt = i;
193 x = pp->p_x + 1;
194 --y;
195 while (i--)
196 check(pp, y, ++x);
197 i = cnt;
198 x = pp->p_x + 1;
199 ++y;
200 while (i--)
201 check(pp, y, ++x);
202 i = cnt;
203 x = pp->p_x + 1;
204 ++y;
205 while (i--)
206 check(pp, y, ++x);
207 break;
208 case ABOVE:
209 sp = &Maze[--y][x];
210 if (!See_over[(int)*sp])
211 break;
212 do {
213 --y;
214 sp -= sizeof Maze[0];
215 check(pp, y, x - 1);
216 check(pp, y, x );
217 check(pp, y, x + 1);
218 } while (See_over[(int)*sp]);
219 break;
220 case BELOW:
221 sp = &Maze[++y][x];
222 if (!See_over[(int)*sp])
223 break;
224 do {
225 y++;
226 sp += sizeof Maze[0];
227 check(pp, y, x - 1);
228 check(pp, y, x );
229 check(pp, y, x + 1);
230 } while (See_over[(int)*sp]);
231 break;
232 }
233 }
234
235 void
236 check(pp, y, x)
237 PLAYER *pp;
238 int y, x;
239 {
240 int index;
241 int ch;
242 PLAYER *rpp;
243
244 index = y * sizeof Maze[0] + x;
245 ch = ((char *) Maze)[index];
246 if (ch != ((char *) pp->p_maze)[index]) {
247 rpp = pp;
248 cgoto(rpp, y, x);
249 if (x == rpp->p_x && y == rpp->p_y)
250 outch(rpp, translate(ch));
251 else if (isplayer(ch))
252 outch(rpp, player_sym(rpp, y, x));
253 else
254 outch(rpp, ch);
255 ((char *) rpp->p_maze)[index] = ch;
256 }
257 }
258
259 /*
260 * showstat
261 * Update the status of players
262 */
263 void
264 showstat(pp)
265 PLAYER *pp;
266 {
267 PLAYER *np;
268 int y;
269 char c;
270
271 y = STAT_PLAY_ROW + 1 + (pp - Player);
272 c = stat_char(pp);
273 # ifdef MONITOR
274 for (np = Monitor; np < End_monitor; np++) {
275 cgoto(np, y, STAT_SCAN_COL);
276 outch(np, c);
277 }
278 # endif
279 for (np = Player; np < End_player; np++) {
280 cgoto(np, y, STAT_SCAN_COL);
281 outch(np, c);
282 }
283 }
284
285 /*
286 * drawplayer:
287 * Draw the player on the screen and show him to everyone who's scanning
288 * unless he is cloaked.
289 */
290 void
291 drawplayer(pp, draw)
292 PLAYER *pp;
293 FLAG draw;
294 {
295 PLAYER *newp;
296 int x, y;
297
298 x = pp->p_x;
299 y = pp->p_y;
300 Maze[y][x] = draw ? pp->p_face : pp->p_over;
301
302 # ifdef MONITOR
303 for (newp = Monitor; newp < End_monitor; newp++)
304 check(newp, y, x);
305 # endif
306
307 for (newp = Player; newp < End_player; newp++) {
308 if (!draw || newp == pp) {
309 check(newp, y, x);
310 continue;
311 }
312 if (newp->p_scan == 0) {
313 newp->p_scan--;
314 showstat(newp);
315 }
316 else if (newp->p_scan > 0) {
317 if (pp->p_cloak < 0)
318 check(newp, y, x);
319 newp->p_scan--;
320 }
321 }
322 if (!draw || pp->p_cloak < 0)
323 return;
324 if (pp->p_cloak-- == 0)
325 showstat(pp);
326 }
327
328 void
329 message(pp, s)
330 PLAYER *pp;
331 char *s;
332 {
333 cgoto(pp, HEIGHT, 0);
334 outstr(pp, s, strlen(s));
335 ce(pp);
336 }
337
338 /*
339 * translate:
340 * Turn a character into the right direction character if we are
341 * looking at the current player.
342 */
343 char
344 translate(ch)
345 char ch;
346 {
347 switch (ch) {
348 case LEFTS:
349 return '<';
350 case RIGHT:
351 return '>';
352 case ABOVE:
353 return '^';
354 case BELOW:
355 return 'v';
356 }
357 return ch;
358 }
359
360 /*
361 * player_sym:
362 * Return the player symbol
363 */
364 int
365 player_sym(pp, y, x)
366 PLAYER *pp;
367 int y, x;
368 {
369 PLAYER *npp;
370
371 npp = play_at(y, x);
372 if (npp->p_ident->i_team == ' ')
373 return Maze[y][x];
374 #ifdef MONITOR
375 if (pp->p_ident->i_team == '*')
376 return npp->p_ident->i_team;
377 #endif
378 if (pp->p_ident->i_team != npp->p_ident->i_team)
379 return Maze[y][x];
380 return pp->p_ident->i_team;
381 }
382