407 lines
8.1 KiB
C
407 lines
8.1 KiB
C
/* $NetBSD: draw.c,v 1.3 2003/06/11 12:00:22 wiz Exp $ */
|
|
/*
|
|
* Copyright (c) 1983-2003, Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* + Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* + Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* + Neither the name of the University of California, San Francisco nor
|
|
* the names of its contributors may be used to endorse or promote
|
|
* products derived from this software without specific prior written
|
|
* permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
#ifndef lint
|
|
__RCSID("$NetBSD: draw.c,v 1.3 2003/06/11 12:00:22 wiz Exp $");
|
|
#endif /* not lint */
|
|
|
|
# include "hunt.h"
|
|
|
|
void
|
|
drawmaze(pp)
|
|
PLAYER *pp;
|
|
{
|
|
int x;
|
|
char *sp;
|
|
int y;
|
|
char *endp;
|
|
|
|
clrscr(pp);
|
|
outstr(pp, pp->p_maze[0], WIDTH);
|
|
for (y = 1; y < HEIGHT - 1; y++) {
|
|
endp = &pp->p_maze[y][WIDTH];
|
|
for (x = 0, sp = pp->p_maze[y]; sp < endp; x++, sp++)
|
|
if (*sp != SPACE) {
|
|
cgoto(pp, y, x);
|
|
if (pp->p_x == x && pp->p_y == y)
|
|
outch(pp, translate(*sp));
|
|
else if (isplayer(*sp))
|
|
outch(pp, player_sym(pp, y, x));
|
|
else
|
|
outch(pp, *sp);
|
|
}
|
|
}
|
|
cgoto(pp, HEIGHT - 1, 0);
|
|
outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH);
|
|
drawstatus(pp);
|
|
}
|
|
|
|
/*
|
|
* drawstatus - put up the status lines (this assumes the screen
|
|
* size is 80x24 with the maze being 64x24)
|
|
*/
|
|
void
|
|
drawstatus(pp)
|
|
PLAYER *pp;
|
|
{
|
|
int i;
|
|
PLAYER *np;
|
|
|
|
cgoto(pp, STAT_AMMO_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Ammo:", 5);
|
|
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
|
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
|
outstr(pp, Buf, 3);
|
|
|
|
cgoto(pp, STAT_GUN_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Gun:", 4);
|
|
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
|
outstr(pp, (pp->p_ncshot < MAXNCSHOT) ? " ok" : " ", 3);
|
|
|
|
cgoto(pp, STAT_DAM_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Damage:", 7);
|
|
(void) sprintf(Buf, "%2d/%2d", pp->p_damage, pp->p_damcap);
|
|
cgoto(pp, STAT_DAM_ROW, STAT_VALUE_COL);
|
|
outstr(pp, Buf, 5);
|
|
|
|
cgoto(pp, STAT_KILL_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Kills:", 6);
|
|
(void) sprintf(Buf, "%3d", (pp->p_damcap - MAXDAM) / 2);
|
|
cgoto(pp, STAT_KILL_ROW, STAT_VALUE_COL);
|
|
outstr(pp, Buf, 3);
|
|
|
|
cgoto(pp, STAT_PLAY_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Player:", 7);
|
|
for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++) {
|
|
(void) sprintf(Buf, "%5.2f%c%-10.10s %c", np->p_ident->i_score,
|
|
stat_char(np), np->p_ident->i_name,
|
|
np->p_ident->i_team);
|
|
cgoto(pp, i++, STAT_NAME_COL);
|
|
outstr(pp, Buf, STAT_NAME_LEN);
|
|
}
|
|
|
|
# ifdef MONITOR
|
|
cgoto(pp, STAT_MON_ROW, STAT_LABEL_COL);
|
|
outstr(pp, "Monitor:", 8);
|
|
for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++) {
|
|
(void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
|
|
np->p_ident->i_name, np->p_ident->i_team);
|
|
cgoto(pp, i++, STAT_NAME_COL);
|
|
outstr(pp, Buf, STAT_NAME_LEN);
|
|
}
|
|
# endif
|
|
}
|
|
|
|
void
|
|
look(pp)
|
|
PLAYER *pp;
|
|
{
|
|
int x, y;
|
|
|
|
x = pp->p_x;
|
|
y = pp->p_y;
|
|
|
|
check(pp, y - 1, x - 1);
|
|
check(pp, y - 1, x );
|
|
check(pp, y - 1, x + 1);
|
|
check(pp, y , x - 1);
|
|
check(pp, y , x );
|
|
check(pp, y , x + 1);
|
|
check(pp, y + 1, x - 1);
|
|
check(pp, y + 1, x );
|
|
check(pp, y + 1, x + 1);
|
|
|
|
switch (pp->p_face) {
|
|
case LEFTS:
|
|
see(pp, LEFTS);
|
|
see(pp, ABOVE);
|
|
see(pp, BELOW);
|
|
break;
|
|
case RIGHT:
|
|
see(pp, RIGHT);
|
|
see(pp, ABOVE);
|
|
see(pp, BELOW);
|
|
break;
|
|
case ABOVE:
|
|
see(pp, ABOVE);
|
|
see(pp, LEFTS);
|
|
see(pp, RIGHT);
|
|
break;
|
|
case BELOW:
|
|
see(pp, BELOW);
|
|
see(pp, LEFTS);
|
|
see(pp, RIGHT);
|
|
break;
|
|
# ifdef FLY
|
|
case FLYER:
|
|
break;
|
|
# endif
|
|
}
|
|
cgoto(pp, y, x);
|
|
}
|
|
|
|
void
|
|
see(pp, face)
|
|
PLAYER *pp;
|
|
int face;
|
|
{
|
|
char *sp;
|
|
int y, x, i, cnt;
|
|
|
|
x = pp->p_x;
|
|
y = pp->p_y;
|
|
|
|
switch (face) {
|
|
case LEFTS:
|
|
sp = &Maze[y][x];
|
|
for (i = 0; See_over[(int)*--sp]; i++)
|
|
continue;
|
|
|
|
if (i == 0)
|
|
break;
|
|
|
|
cnt = i;
|
|
x = pp->p_x - 1;
|
|
--y;
|
|
while (i--)
|
|
check(pp, y, --x);
|
|
i = cnt;
|
|
x = pp->p_x - 1;
|
|
++y;
|
|
while (i--)
|
|
check(pp, y, --x);
|
|
i = cnt;
|
|
x = pp->p_x - 1;
|
|
++y;
|
|
while (i--)
|
|
check(pp, y, --x);
|
|
break;
|
|
case RIGHT:
|
|
sp = &Maze[y][++x];
|
|
for (i = 0; See_over[(int)*sp++]; i++)
|
|
continue;
|
|
|
|
if (i == 0)
|
|
break;
|
|
|
|
cnt = i;
|
|
x = pp->p_x + 1;
|
|
--y;
|
|
while (i--)
|
|
check(pp, y, ++x);
|
|
i = cnt;
|
|
x = pp->p_x + 1;
|
|
++y;
|
|
while (i--)
|
|
check(pp, y, ++x);
|
|
i = cnt;
|
|
x = pp->p_x + 1;
|
|
++y;
|
|
while (i--)
|
|
check(pp, y, ++x);
|
|
break;
|
|
case ABOVE:
|
|
sp = &Maze[--y][x];
|
|
if (!See_over[(int)*sp])
|
|
break;
|
|
do {
|
|
--y;
|
|
sp -= sizeof Maze[0];
|
|
check(pp, y, x - 1);
|
|
check(pp, y, x );
|
|
check(pp, y, x + 1);
|
|
} while (See_over[(int)*sp]);
|
|
break;
|
|
case BELOW:
|
|
sp = &Maze[++y][x];
|
|
if (!See_over[(int)*sp])
|
|
break;
|
|
do {
|
|
y++;
|
|
sp += sizeof Maze[0];
|
|
check(pp, y, x - 1);
|
|
check(pp, y, x );
|
|
check(pp, y, x + 1);
|
|
} while (See_over[(int)*sp]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
check(pp, y, x)
|
|
PLAYER *pp;
|
|
int y, x;
|
|
{
|
|
int index;
|
|
int ch;
|
|
PLAYER *rpp;
|
|
|
|
index = y * sizeof Maze[0] + x;
|
|
ch = ((char *) Maze)[index];
|
|
if (ch != ((char *) pp->p_maze)[index]) {
|
|
rpp = pp;
|
|
cgoto(rpp, y, x);
|
|
if (x == rpp->p_x && y == rpp->p_y)
|
|
outch(rpp, translate(ch));
|
|
else if (isplayer(ch))
|
|
outch(rpp, player_sym(rpp, y, x));
|
|
else
|
|
outch(rpp, ch);
|
|
((char *) rpp->p_maze)[index] = ch;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* showstat
|
|
* Update the status of players
|
|
*/
|
|
void
|
|
showstat(pp)
|
|
PLAYER *pp;
|
|
{
|
|
PLAYER *np;
|
|
int y;
|
|
char c;
|
|
|
|
y = STAT_PLAY_ROW + 1 + (pp - Player);
|
|
c = stat_char(pp);
|
|
# ifdef MONITOR
|
|
for (np = Monitor; np < End_monitor; np++) {
|
|
cgoto(np, y, STAT_SCAN_COL);
|
|
outch(np, c);
|
|
}
|
|
# endif
|
|
for (np = Player; np < End_player; np++) {
|
|
cgoto(np, y, STAT_SCAN_COL);
|
|
outch(np, c);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* drawplayer:
|
|
* Draw the player on the screen and show him to everyone who's scanning
|
|
* unless he is cloaked.
|
|
*/
|
|
void
|
|
drawplayer(pp, draw)
|
|
PLAYER *pp;
|
|
FLAG draw;
|
|
{
|
|
PLAYER *newp;
|
|
int x, y;
|
|
|
|
x = pp->p_x;
|
|
y = pp->p_y;
|
|
Maze[y][x] = draw ? pp->p_face : pp->p_over;
|
|
|
|
# ifdef MONITOR
|
|
for (newp = Monitor; newp < End_monitor; newp++)
|
|
check(newp, y, x);
|
|
# endif
|
|
|
|
for (newp = Player; newp < End_player; newp++) {
|
|
if (!draw || newp == pp) {
|
|
check(newp, y, x);
|
|
continue;
|
|
}
|
|
if (newp->p_scan == 0) {
|
|
newp->p_scan--;
|
|
showstat(newp);
|
|
}
|
|
else if (newp->p_scan > 0) {
|
|
if (pp->p_cloak < 0)
|
|
check(newp, y, x);
|
|
newp->p_scan--;
|
|
}
|
|
}
|
|
if (!draw || pp->p_cloak < 0)
|
|
return;
|
|
if (pp->p_cloak-- == 0)
|
|
showstat(pp);
|
|
}
|
|
|
|
void
|
|
message(pp, s)
|
|
PLAYER *pp;
|
|
char *s;
|
|
{
|
|
cgoto(pp, HEIGHT, 0);
|
|
outstr(pp, s, strlen(s));
|
|
ce(pp);
|
|
}
|
|
|
|
/*
|
|
* translate:
|
|
* Turn a character into the right direction character if we are
|
|
* looking at the current player.
|
|
*/
|
|
char
|
|
translate(ch)
|
|
char ch;
|
|
{
|
|
switch (ch) {
|
|
case LEFTS:
|
|
return '<';
|
|
case RIGHT:
|
|
return '>';
|
|
case ABOVE:
|
|
return '^';
|
|
case BELOW:
|
|
return 'v';
|
|
}
|
|
return ch;
|
|
}
|
|
|
|
/*
|
|
* player_sym:
|
|
* Return the player symbol
|
|
*/
|
|
int
|
|
player_sym(pp, y, x)
|
|
PLAYER *pp;
|
|
int y, x;
|
|
{
|
|
PLAYER *npp;
|
|
|
|
npp = play_at(y, x);
|
|
if (npp->p_ident->i_team == ' ')
|
|
return Maze[y][x];
|
|
#ifdef MONITOR
|
|
if (pp->p_ident->i_team == '*')
|
|
return npp->p_ident->i_team;
|
|
#endif
|
|
if (pp->p_ident->i_team != npp->p_ident->i_team)
|
|
return Maze[y][x];
|
|
return pp->p_ident->i_team;
|
|
}
|