#include <sys/select.h>
#include <string.h>
#include "conf.h"
#include "hunt.h"
#include "server.h"
static char translate(char);
static int player_sym(PLAYER *, int, int);
static void drawstatus(PLAYER *);
static void see(PLAYER *, int);
void
drawmaze(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 (is_player(*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);
}
static void
drawstatus(PLAYER *pp)
{
int i;
PLAYER *np;
outyx(pp, STAT_AMMO_ROW, STAT_LABEL_COL, "Ammo:");
ammo_update(pp);
outyx(pp, STAT_GUN_ROW, STAT_LABEL_COL, "Gun:");
outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, "%3s",
(pp->p_ncshot < conf_maxncshot) ? "ok" : "");
outyx(pp, STAT_DAM_ROW, STAT_LABEL_COL, "Damage:");
outyx(pp, STAT_DAM_ROW, STAT_VALUE_COL, "%2d/%2d",
pp->p_damage, pp->p_damcap);
outyx(pp, STAT_KILL_ROW, STAT_LABEL_COL, "Kills:");
outyx(pp, STAT_KILL_ROW, STAT_VALUE_COL, "%3d",
(pp->p_damcap - conf_maxdam) / 2);
outyx(pp, STAT_PLAY_ROW, STAT_LABEL_COL, "Player:");
for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++, i++) {
outyx(pp, i, STAT_NAME_COL, "%5.2f%c%-10.10s %c",
np->p_ident->i_score, stat_char(np),
np->p_ident->i_name, np->p_ident->i_team);
}
outyx(pp, STAT_MON_ROW, STAT_LABEL_COL, "Monitor:");
for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++, i++) {
outyx(pp, i++, STAT_NAME_COL, "%5.5s %-10.10s %c",
" ", np->p_ident->i_name, np->p_ident->i_team);
}
}
void
look(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;
case FLYER:
break;
}
cgoto(pp, y, x);
}
static void
see(PLAYER *pp, int face)
{
char *sp;
int y, x;
x = pp->p_x;
y = pp->p_y;
#define seewalk(dx, dy) \
x += (dx); \
y += (dy); \
sp = &Maze[y][x]; \
while (See_over[(int)*sp]) { \
x += (dx); \
y += (dy); \
sp += ((dx) + (dy) * sizeof Maze[0]); \
check(pp, y + dx, x + dy); \
check(pp, y, x); \
check(pp, y - dx, x - dy); \
}
switch (face) {
case LEFTS:
seewalk(-1, 0); break;
case RIGHT:
seewalk(1, 0); break;
case ABOVE:
seewalk(0, -1); break;
case BELOW:
seewalk(0, 1); break;
}
}
void
check(PLAYER *pp, int y, int x)
{
int index;
int ch;
PLAYER *rpp;
if (pp == ALL_PLAYERS) {
for (pp = Player; pp < End_player; pp++)
check(pp, y, x);
for (pp = Monitor; pp < End_monitor; pp++)
check(pp, y, x);
return;
}
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 (is_player(ch))
outch(rpp, player_sym(rpp, y, x));
else
outch(rpp, ch);
((char *) rpp->p_maze)[index] = ch;
}
}
void
showstat(PLAYER *pp)
{
outyx(ALL_PLAYERS,
STAT_PLAY_ROW + 1 + (pp - Player), STAT_SCAN_COL,
"%c", stat_char(pp));
}
void
drawplayer(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;
for (newp = Monitor; newp < End_monitor; newp++)
check(newp, y, x);
for (newp = Player; newp < End_player; newp++) {
if (!draw) {
check(newp, y, x);
continue;
}
if (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) {
pp->p_cloak--;
if (pp->p_cloak < 0)
showstat(pp);
}
}
void
message(PLAYER *pp, char *s)
{
cgoto(pp, HEIGHT, 0);
outstr(pp, s, strlen(s));
ce(pp);
}
static char
translate(char ch)
{
switch (ch) {
case LEFTS:
return '<';
case RIGHT:
return '>';
case ABOVE:
return '^';
case BELOW:
return 'v';
}
return ch;
}
static int
player_sym(PLAYER *pp, int y, int x)
{
PLAYER *npp;
npp = play_at(y, x);
if (npp->p_ident->i_team == ' ')
return Maze[y][x];
if (pp->p_ident->i_team == '*')
return npp->p_ident->i_team;
if (pp->p_ident->i_team != npp->p_ident->i_team)
return Maze[y][x];
return pp->p_ident->i_team;
}