home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume5
/
mazewar-V
/
daemon.c
next >
Wrap
C/C++ Source or Header
|
1990-12-13
|
8KB
|
338 lines
/*
* This file is part of "mazewar", an interactive
* multiuser action game for non-BSD-Unix-systems.
* Copyright (C) 1988 Hans Korneder korn@altger.uucp
* Permission is granted to the public
* to copy all parts of the source, as long as no money
* is made out of it, and the copyrightmessage is not removed.
*/
#include <signal.h>
#include <pwd.h>
#include "globals.h"
#define N_PLAYERS 10
struct player
{
int p_pid;
int p_fd;
int p_uid;
int p_x_pos;
int p_y_pos;
char p_name[9];
char p_richtg;
long p_score;
char p_pipe[32];
int last_x[N_PLAYERS];
int last_y[N_PLAYERS];
int last_r[N_PLAYERS];
long last_s[N_PLAYERS];
} players[N_PLAYERS];
int delta_x[4] = { 1,0,-1,0 };
int delta_y[4] = { 0,-1,0,1 };
int player;
int user_pipe_fd, score_fd;
catch(s)
int s;
{
signal(s,catch);
}
get_user_info(uid)
int uid;
{
extern struct passwd *getpwuid();
struct passwd *pwd;
pwd = getpwuid(uid);
if ( pwd ) strcpy(players[player].p_name,pwd->pw_name);
else sprintf(players[player].p_name,"*%06d*",uid);
if ( score_fd >= 0 )
{
lseek(score_fd,((long)uid)*sizeof(long),0);
read(score_fd,&(players[player].p_score),sizeof(long));
}
else players[player].p_score = 0L;
}
main()
{
extern long time();
setpgrp();
catch(SIGALRM);
catch(SIGPIPE);
nice(-10); nice(-10); nice(-10); nice(-10);
srand((unsigned)time((long *)0));
umask(0);
score_fd = open(MAZE_SCORES,2);
for(;;)
{
unlink(MAZE_DAEMON);
mknod(MAZE_DAEMON,010622,0);
user_pipe_fd = open(MAZE_DAEMON,0);
if ( user_pipe_fd < 0 ) exit(1);
for(player=0; player<N_PLAYERS; player++)
players[player].p_pid = 0;
while(process_mesg());
close(user_pipe_fd);
sleep(2);
}
}
reposition_player(p)
int p;
{
extern int rand();
int y,x;
do {
x = rand() % MAZE_COLS;
y = rand() % MAZE_ROWS;
} while ( maze[y][x] != ' ' );
players[p].p_x_pos = x;
players[p].p_y_pos = y;
players[p].p_richtg = rand()%4;
}
int process_mesg()
{
struct bewegung bew;
if ( read(user_pipe_fd,&bew,sizeof(bew))<=0 ) return 0;
switch ( bew.be_magic )
{
case ANMELD:
{
int p;
char answer_pipe[32];
read(user_pipe_fd,answer_pipe,sizeof(answer_pipe));
for(player=0; player<N_PLAYERS; player++)
if ( ! players[player].p_pid ) break;
if ( player==N_PLAYERS ) break;
strcpy(players[player].p_pipe,answer_pipe);
players[player].p_fd = open(players[player].p_pipe,1);
if ( players[player].p_fd<0 ) break;
players[player].p_pid = bew.be_pid;
players[player].p_uid = bew.be_code;
get_user_info(bew.be_code);
reposition_player(player);
for(p=0; p<N_PLAYERS; p++)
players[player].last_x[p] = -1,
players[player].last_s[p] = -1000000000;
determine_visibility();
break;
}
case BEWEGUNG:
for(player=0; player<N_PLAYERS; player++)
if ( players[player].p_pid==bew.be_pid ) break;
if ( player==N_PLAYERS ) break;
do_cmd(bew.be_code);
determine_visibility();
break;
}
return 1;
}
send_player_info(p1,p2,x,y,sicht) /* send info 'bout p1 to p2 */
int p1,p2,x,y,sicht;
{
struct sp_anzeige spa;
spa.sp_magic = SP_ANZ;
spa.sp_pid = players[p1].p_pid;
spa.sp_lfd_nr = p1;
spa.sp_flag = sicht|1;
spa.sp_score = players[p1].p_score;
spa.sp_x_pos = x;
spa.sp_y_pos = y;
spa.sp_richtg = players[p1].p_richtg;
strcpy(spa.sp_name,players[p1].p_name);
tell(p2,spa);
}
do_cmd(cmd)
int cmd;
{
int p;
switch ( cmd )
{
case EXIT: /* leave game */
log_out(player);
break;
case 'S': /* shoot */
{
int new_x, new_y, p;
players[player].p_score -= 1; /* one shot costs 1 pt */
new_x=players[player].p_x_pos;
new_y=players[player].p_y_pos;
for(;;)
{
new_x += delta_x[players[player].p_richtg];
new_y += delta_y[players[player].p_richtg];
if ( maze[new_y][new_x] != ' ' ) break;
for(p=0; p<N_PLAYERS; p++)
if( players[p].p_pid &&
player!=p &&
players[p].p_x_pos==new_x &&
players[p].p_y_pos==new_y )
{
players[p].p_score -= 10;
reposition_player(p);
players[player].p_score += 10;
}
}
break;
}
case 'A': /* turn right */
players[player].p_richtg = (players[player].p_richtg+1)%4;
break;
case 'D': /* turn left */
players[player].p_richtg = (players[player].p_richtg+3)%4;
break;
case 'X': /* turn back */
players[player].p_richtg = (players[player].p_richtg+2)%4;
break;
case 'R': /* reposition */
players[player].p_score -= 5; /* one repos costs 5 pts */
reposition_player(player);
break;
case 'W': /* walk */
{
int new_x, new_y;
new_x = players[player].p_x_pos +
delta_x[players[player].p_richtg];
new_y = players[player].p_y_pos +
delta_y[players[player].p_richtg];
if ( maze[new_y][new_x] == ' ' )
{
players[player].p_x_pos = new_x;
players[player].p_y_pos = new_y;
}
break;
}
case ' ': /* backwalk */
{
int new_x, new_y;
new_x = players[player].p_x_pos +
delta_x[(players[player].p_richtg+2)%4];
new_y = players[player].p_y_pos +
delta_y[(players[player].p_richtg+2)%4];
if ( maze[new_y][new_x] == ' ' )
{
players[player].p_x_pos = new_x;
players[player].p_y_pos = new_y;
}
break;
}
break;
}
}
log_out(p)
int p;
{
int play;
/* recursion can occur, therefore use local structs ! */
struct sp_anzeige raus;
if ( score_fd >= 0 )
{
lseek(score_fd,((long)players[p].p_uid)*sizeof(long),0);
write(score_fd,&(players[player].p_score),sizeof(long));
}
raus.sp_magic = SP_ANZ;
raus.sp_pid = players[p].p_pid;
raus.sp_lfd_nr = p;
raus.sp_x_pos = players[p].p_x_pos;
raus.sp_y_pos = players[p].p_y_pos;
raus.sp_flag = 0;
for(play=0; play<N_PLAYERS; play++)
tell(play,raus);
close (players[p].p_fd );
unlink(players[p].p_pipe);
players[p].p_pid = 0;
}
tell(p,spa)
int p;
struct sp_anzeige spa;
{
if ( players[p].p_pid )
{
int n_bytes;
alarm(3);
n_bytes = write(players[p].p_fd,&spa,sizeof(spa));
alarm(0);
if ( n_bytes<1 )
{
players[p].p_pid = 0; /* avoid endless recursion */
log_out(p); /* recursion */
}
}
}
determine_visibility()
{
register i,j; /* speedup */
for(i=0; i<N_PLAYERS; i++)
if ( players[i].p_pid )
for(j=0; j<N_PLAYERS; j++)
if ( players[j].p_pid )
{
int visibel;
register struct player *pi, *pj; /* speedup */
pi = players + i; pj = players + j;
visibel = (pi->p_x_pos == pj->p_x_pos)
|| (pi->p_y_pos == pj->p_y_pos) ;
if ( visibel )
{
/* i can view j. */
/* did he see him before
at the same position ? */
if ( (pj->p_x_pos == pi->last_x[j]) &&
(pj->p_y_pos == pi->last_y[j]) &&
(pj->p_richtg== pi->last_r[j]) &&
(pj->p_score == pi->last_s[j]) )
{ /* then: nothing to do. */ }
else /* he was somewhere else before. */
{
/* was he in the game at all ? */
if ( pi->last_x[j]>=0 )
/* did he just look in another direction? */
if ( (pj->p_x_pos == pi->last_x[j]) &&
(pj->p_y_pos == pi->last_y[j]) )
{ /* nothing to erase then. */ }
else
/* his last position has to be erased
on the screen. */
send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
/* store new position and send it. */
pi->last_x[j] = pj->p_x_pos;
pi->last_y[j] = pj->p_y_pos;
pi->last_r[j] = pj->p_richtg;
pi->last_s[j] = pj->p_score;
send_player_info(j,i,pi->last_x[j],pi->last_y[j],2);
}
}
else
{
/* i cannot view j. did he not see him before? */
if ( pi->last_x[j]<0 )
/* if score changed, display though */
if ( pi->last_s[j] == pj->p_score )
{ /* nothing to do here */ }
else
{
send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
pi->last_s[j] = pj->p_score;
}
else /* he was visibel before. */
{
/* his last position on the screen has to be erased */
send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
pi->last_x[j] = -1;
}
}
}
}
/* END */