1 /* $NetBSD: draw.c,v 1.3 2003/06/11 12:00:22 wiz Exp $ */ 2 /* 3 * Copyright (c) 1983-2003, Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * + Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * + Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * + Neither the name of the University of California, San Francisco nor 16 * the names of its contributors may be used to endorse or promote 17 * products derived from this software without specific prior written 18 * permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 #ifndef lint 35 __RCSID("$NetBSD: draw.c,v 1.3 2003/06/11 12:00:22 wiz Exp $"); 36 #endif /* not lint */ 37 38 # include "hunt.h" 39 40 void 41 drawmaze(pp) 42 PLAYER *pp; 43 { 44 int x; 45 char *sp; 46 int y; 47 char *endp; 48 49 clrscr(pp); 50 outstr(pp, pp->p_maze[0], WIDTH); 51 for (y = 1; y < HEIGHT - 1; y++) { 52 endp = &pp->p_maze[y][WIDTH]; 53 for (x = 0, sp = pp->p_maze[y]; sp < endp; x++, sp++) 54 if (*sp != SPACE) { 55 cgoto(pp, y, x); 56 if (pp->p_x == x && pp->p_y == y) 57 outch(pp, translate(*sp)); 58 else if (isplayer(*sp)) 59 outch(pp, player_sym(pp, y, x)); 60 else 61 outch(pp, *sp); 62 } 63 } 64 cgoto(pp, HEIGHT - 1, 0); 65 outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH); 66 drawstatus(pp); 67 } 68 69 /* 70 * drawstatus - put up the status lines (this assumes the screen 71 * size is 80x24 with the maze being 64x24) 72 */ 73 void 74 drawstatus(pp) 75 PLAYER *pp; 76 { 77 int i; 78 PLAYER *np; 79 80 cgoto(pp, STAT_AMMO_ROW, STAT_LABEL_COL); 81 outstr(pp, "Ammo:", 5); 82 (void) sprintf(Buf, "%3d", pp->p_ammo); 83 cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); 84 outstr(pp, Buf, 3); 85 86 cgoto(pp, STAT_GUN_ROW, STAT_LABEL_COL); 87 outstr(pp, "Gun:", 4); 88 cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); 89 outstr(pp, (pp->p_ncshot < MAXNCSHOT) ? " ok" : " ", 3); 90 91 cgoto(pp, STAT_DAM_ROW, STAT_LABEL_COL); 92 outstr(pp, "Damage:", 7); 93 (void) sprintf(Buf, "%2d/%2d", pp->p_damage, pp->p_damcap); 94 cgoto(pp, STAT_DAM_ROW, STAT_VALUE_COL); 95 outstr(pp, Buf, 5); 96 97 cgoto(pp, STAT_KILL_ROW, STAT_LABEL_COL); 98 outstr(pp, "Kills:", 6); 99 (void) sprintf(Buf, "%3d", (pp->p_damcap - MAXDAM) / 2); 100 cgoto(pp, STAT_KILL_ROW, STAT_VALUE_COL); 101 outstr(pp, Buf, 3); 102 103 cgoto(pp, STAT_PLAY_ROW, STAT_LABEL_COL); 104 outstr(pp, "Player:", 7); 105 for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++) { 106 (void) sprintf(Buf, "%5.2f%c%-10.10s %c", np->p_ident->i_score, 107 stat_char(np), np->p_ident->i_name, 108 np->p_ident->i_team); 109 cgoto(pp, i++, STAT_NAME_COL); 110 outstr(pp, Buf, STAT_NAME_LEN); 111 } 112 113 # ifdef MONITOR 114 cgoto(pp, STAT_MON_ROW, STAT_LABEL_COL); 115 outstr(pp, "Monitor:", 8); 116 for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++) { 117 (void) sprintf(Buf, "%5.5s %-10.10s %c", " ", 118 np->p_ident->i_name, np->p_ident->i_team); 119 cgoto(pp, i++, STAT_NAME_COL); 120 outstr(pp, Buf, STAT_NAME_LEN); 121 } 122 # endif 123 } 124 125 void 126 look(pp) 127 PLAYER *pp; 128 { 129 int x, y; 130 131 x = pp->p_x; 132 y = pp->p_y; 133 134 check(pp, y - 1, x - 1); 135 check(pp, y - 1, x ); 136 check(pp, y - 1, x + 1); 137 check(pp, y , x - 1); 138 check(pp, y , x ); 139 check(pp, y , x + 1); 140 check(pp, y + 1, x - 1); 141 check(pp, y + 1, x ); 142 check(pp, y + 1, x + 1); 143 144 switch (pp->p_face) { 145 case LEFTS: 146 see(pp, LEFTS); 147 see(pp, ABOVE); 148 see(pp, BELOW); 149 break; 150 case RIGHT: 151 see(pp, RIGHT); 152 see(pp, ABOVE); 153 see(pp, BELOW); 154 break; 155 case ABOVE: 156 see(pp, ABOVE); 157 see(pp, LEFTS); 158 see(pp, RIGHT); 159 break; 160 case BELOW: 161 see(pp, BELOW); 162 see(pp, LEFTS); 163 see(pp, RIGHT); 164 break; 165 # ifdef FLY 166 case FLYER: 167 break; 168 # endif 169 } 170 cgoto(pp, y, x); 171 } 172 173 void 174 see(pp, face) 175 PLAYER *pp; 176 int face; 177 { 178 char *sp; 179 int y, x, i, cnt; 180 181 x = pp->p_x; 182 y = pp->p_y; 183 184 switch (face) { 185 case LEFTS: 186 sp = &Maze[y][x]; 187 for (i = 0; See_over[(int)*--sp]; i++) 188 continue; 189 190 if (i == 0) 191 break; 192 193 cnt = i; 194 x = pp->p_x - 1; 195 --y; 196 while (i--) 197 check(pp, y, --x); 198 i = cnt; 199 x = pp->p_x - 1; 200 ++y; 201 while (i--) 202 check(pp, y, --x); 203 i = cnt; 204 x = pp->p_x - 1; 205 ++y; 206 while (i--) 207 check(pp, y, --x); 208 break; 209 case RIGHT: 210 sp = &Maze[y][++x]; 211 for (i = 0; See_over[(int)*sp++]; i++) 212 continue; 213 214 if (i == 0) 215 break; 216 217 cnt = i; 218 x = pp->p_x + 1; 219 --y; 220 while (i--) 221 check(pp, y, ++x); 222 i = cnt; 223 x = pp->p_x + 1; 224 ++y; 225 while (i--) 226 check(pp, y, ++x); 227 i = cnt; 228 x = pp->p_x + 1; 229 ++y; 230 while (i--) 231 check(pp, y, ++x); 232 break; 233 case ABOVE: 234 sp = &Maze[--y][x]; 235 if (!See_over[(int)*sp]) 236 break; 237 do { 238 --y; 239 sp -= sizeof Maze[0]; 240 check(pp, y, x - 1); 241 check(pp, y, x ); 242 check(pp, y, x + 1); 243 } while (See_over[(int)*sp]); 244 break; 245 case BELOW: 246 sp = &Maze[++y][x]; 247 if (!See_over[(int)*sp]) 248 break; 249 do { 250 y++; 251 sp += sizeof Maze[0]; 252 check(pp, y, x - 1); 253 check(pp, y, x ); 254 check(pp, y, x + 1); 255 } while (See_over[(int)*sp]); 256 break; 257 } 258 } 259 260 void 261 check(pp, y, x) 262 PLAYER *pp; 263 int y, x; 264 { 265 int index; 266 int ch; 267 PLAYER *rpp; 268 269 index = y * sizeof Maze[0] + x; 270 ch = ((char *) Maze)[index]; 271 if (ch != ((char *) pp->p_maze)[index]) { 272 rpp = pp; 273 cgoto(rpp, y, x); 274 if (x == rpp->p_x && y == rpp->p_y) 275 outch(rpp, translate(ch)); 276 else if (isplayer(ch)) 277 outch(rpp, player_sym(rpp, y, x)); 278 else 279 outch(rpp, ch); 280 ((char *) rpp->p_maze)[index] = ch; 281 } 282 } 283 284 /* 285 * showstat 286 * Update the status of players 287 */ 288 void 289 showstat(pp) 290 PLAYER *pp; 291 { 292 PLAYER *np; 293 int y; 294 char c; 295 296 y = STAT_PLAY_ROW + 1 + (pp - Player); 297 c = stat_char(pp); 298 # ifdef MONITOR 299 for (np = Monitor; np < End_monitor; np++) { 300 cgoto(np, y, STAT_SCAN_COL); 301 outch(np, c); 302 } 303 # endif 304 for (np = Player; np < End_player; np++) { 305 cgoto(np, y, STAT_SCAN_COL); 306 outch(np, c); 307 } 308 } 309 310 /* 311 * drawplayer: 312 * Draw the player on the screen and show him to everyone who's scanning 313 * unless he is cloaked. 314 */ 315 void 316 drawplayer(pp, draw) 317 PLAYER *pp; 318 FLAG draw; 319 { 320 PLAYER *newp; 321 int x, y; 322 323 x = pp->p_x; 324 y = pp->p_y; 325 Maze[y][x] = draw ? pp->p_face : pp->p_over; 326 327 # ifdef MONITOR 328 for (newp = Monitor; newp < End_monitor; newp++) 329 check(newp, y, x); 330 # endif 331 332 for (newp = Player; newp < End_player; newp++) { 333 if (!draw || newp == pp) { 334 check(newp, y, x); 335 continue; 336 } 337 if (newp->p_scan == 0) { 338 newp->p_scan--; 339 showstat(newp); 340 } 341 else if (newp->p_scan > 0) { 342 if (pp->p_cloak < 0) 343 check(newp, y, x); 344 newp->p_scan--; 345 } 346 } 347 if (!draw || pp->p_cloak < 0) 348 return; 349 if (pp->p_cloak-- == 0) 350 showstat(pp); 351 } 352 353 void 354 message(pp, s) 355 PLAYER *pp; 356 char *s; 357 { 358 cgoto(pp, HEIGHT, 0); 359 outstr(pp, s, strlen(s)); 360 ce(pp); 361 } 362 363 /* 364 * translate: 365 * Turn a character into the right direction character if we are 366 * looking at the current player. 367 */ 368 char 369 translate(ch) 370 char ch; 371 { 372 switch (ch) { 373 case LEFTS: 374 return '<'; 375 case RIGHT: 376 return '>'; 377 case ABOVE: 378 return '^'; 379 case BELOW: 380 return 'v'; 381 } 382 return ch; 383 } 384 385 /* 386 * player_sym: 387 * Return the player symbol 388 */ 389 int 390 player_sym(pp, y, x) 391 PLAYER *pp; 392 int y, x; 393 { 394 PLAYER *npp; 395 396 npp = play_at(y, x); 397 if (npp->p_ident->i_team == ' ') 398 return Maze[y][x]; 399 #ifdef MONITOR 400 if (pp->p_ident->i_team == '*') 401 return npp->p_ident->i_team; 402 #endif 403 if (pp->p_ident->i_team != npp->p_ident->i_team) 404 return Maze[y][x]; 405 return pp->p_ident->i_team; 406 } 407