xref: /netbsd/games/hunt/huntd/draw.c (revision bf9ec67e)
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