Home | History | Annotate | Line # | Download | only in huntd
answer.c revision 1.7
      1  1.7      dsl /*	$NetBSD: answer.c,v 1.7 2004/11/05 21:30:32 dsl Exp $	*/
      2  1.1      mrg /*
      3  1.6      wiz  * Copyright (c) 1983-2003, Regents of the University of California.
      4  1.6      wiz  * All rights reserved.
      5  1.6      wiz  *
      6  1.6      wiz  * Redistribution and use in source and binary forms, with or without
      7  1.6      wiz  * modification, are permitted provided that the following conditions are
      8  1.6      wiz  * met:
      9  1.6      wiz  *
     10  1.6      wiz  * + Redistributions of source code must retain the above copyright
     11  1.6      wiz  *   notice, this list of conditions and the following disclaimer.
     12  1.6      wiz  * + Redistributions in binary form must reproduce the above copyright
     13  1.6      wiz  *   notice, this list of conditions and the following disclaimer in the
     14  1.6      wiz  *   documentation and/or other materials provided with the distribution.
     15  1.6      wiz  * + Neither the name of the University of California, San Francisco nor
     16  1.6      wiz  *   the names of its contributors may be used to endorse or promote
     17  1.6      wiz  *   products derived from this software without specific prior written
     18  1.6      wiz  *   permission.
     19  1.6      wiz  *
     20  1.6      wiz  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     21  1.6      wiz  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.6      wiz  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     23  1.6      wiz  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24  1.6      wiz  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25  1.6      wiz  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26  1.6      wiz  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.6      wiz  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.6      wiz  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.6      wiz  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  1.6      wiz  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1      mrg  */
     32  1.1      mrg 
     33  1.3    lukem #include <sys/cdefs.h>
     34  1.3    lukem #ifndef lint
     35  1.7      dsl __RCSID("$NetBSD: answer.c,v 1.7 2004/11/05 21:30:32 dsl Exp $");
     36  1.3    lukem #endif /* not lint */
     37  1.3    lukem 
     38  1.1      mrg # include	<ctype.h>
     39  1.1      mrg # include	<errno.h>
     40  1.1      mrg # include	<fcntl.h>
     41  1.3    lukem # include	<stdlib.h>
     42  1.3    lukem # include	<unistd.h>
     43  1.3    lukem # include	"hunt.h"
     44  1.1      mrg 
     45  1.1      mrg # define	SCOREDECAY	15
     46  1.1      mrg 
     47  1.1      mrg static char	Ttyname[NAMELEN];
     48  1.1      mrg 
     49  1.3    lukem int
     50  1.1      mrg answer()
     51  1.1      mrg {
     52  1.3    lukem 	PLAYER			*pp;
     53  1.3    lukem 	int			newsock;
     54  1.1      mrg 	static u_long		mode;
     55  1.1      mrg 	static char		name[NAMELEN];
     56  1.1      mrg 	static char		team;
     57  1.1      mrg 	static int		enter_status;
     58  1.1      mrg 	static int		socklen;
     59  1.1      mrg 	static u_long		machine;
     60  1.5      jdc 	static u_int32_t	uid;
     61  1.1      mrg 	static SOCKET		sockstruct;
     62  1.3    lukem 	char			*cp1, *cp2;
     63  1.1      mrg 	int			flags;
     64  1.5      jdc 	u_int32_t		version;
     65  1.4  mycroft 	int			i;
     66  1.1      mrg 
     67  1.1      mrg # ifdef INTERNET
     68  1.1      mrg 	socklen = sizeof sockstruct;
     69  1.1      mrg # else
     70  1.1      mrg 	socklen = sizeof sockstruct - 1;
     71  1.1      mrg # endif
     72  1.1      mrg 	errno = 0;
     73  1.1      mrg 	newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
     74  1.1      mrg 	if (newsock < 0)
     75  1.1      mrg 	{
     76  1.1      mrg 		if (errno == EINTR)
     77  1.1      mrg 			return FALSE;
     78  1.1      mrg # ifdef LOG
     79  1.1      mrg 		syslog(LOG_ERR, "accept: %m");
     80  1.1      mrg # else
     81  1.1      mrg 		perror("accept");
     82  1.1      mrg # endif
     83  1.1      mrg 		cleanup(1);
     84  1.1      mrg 	}
     85  1.1      mrg 
     86  1.1      mrg # ifdef INTERNET
     87  1.1      mrg 	machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
     88  1.1      mrg # else
     89  1.1      mrg 	if (machine == 0)
     90  1.1      mrg 		machine = gethostid();
     91  1.1      mrg # endif
     92  1.2      mrg 	version = htonl((u_int32_t) HUNT_VERSION);
     93  1.1      mrg 	(void) write(newsock, (char *) &version, LONGLEN);
     94  1.1      mrg 	(void) read(newsock, (char *) &uid, LONGLEN);
     95  1.1      mrg 	uid = ntohl((unsigned long) uid);
     96  1.1      mrg 	(void) read(newsock, name, NAMELEN);
     97  1.1      mrg 	(void) read(newsock, &team, 1);
     98  1.1      mrg 	(void) read(newsock, (char *) &enter_status, LONGLEN);
     99  1.1      mrg 	enter_status = ntohl((unsigned long) enter_status);
    100  1.1      mrg 	(void) read(newsock, Ttyname, NAMELEN);
    101  1.1      mrg 	(void) read(newsock, (char *) &mode, sizeof mode);
    102  1.1      mrg 	mode = ntohl(mode);
    103  1.1      mrg 
    104  1.1      mrg 	/*
    105  1.1      mrg 	 * Turn off blocking I/O, so a slow or dead terminal won't stop
    106  1.1      mrg 	 * the game.  All subsequent reads check how many bytes they read.
    107  1.1      mrg 	 */
    108  1.1      mrg 	flags = fcntl(newsock, F_GETFL, 0);
    109  1.1      mrg 	flags |= O_NDELAY;
    110  1.1      mrg 	(void) fcntl(newsock, F_SETFL, flags);
    111  1.1      mrg 
    112  1.1      mrg 	/*
    113  1.1      mrg 	 * Make sure the name contains only printable characters
    114  1.1      mrg 	 * since we use control characters for cursor control
    115  1.1      mrg 	 * between driver and player processes
    116  1.1      mrg 	 */
    117  1.1      mrg 	for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
    118  1.7      dsl 		if (isprint((unsigned char)*cp1) || *cp1 == ' ')
    119  1.1      mrg 			*cp2++ = *cp1;
    120  1.1      mrg 	*cp2 = '\0';
    121  1.1      mrg 
    122  1.1      mrg # ifdef INTERNET
    123  1.1      mrg 	if (mode == C_MESSAGE) {
    124  1.1      mrg 		char	buf[BUFSIZ + 1];
    125  1.1      mrg 		int	n;
    126  1.1      mrg 
    127  1.1      mrg 		if (team == ' ')
    128  1.1      mrg 			(void) sprintf(buf, "%s: ", name);
    129  1.1      mrg 		else
    130  1.1      mrg 			(void) sprintf(buf, "%s[%c]: ", name, team);
    131  1.1      mrg 		n = strlen(buf);
    132  1.1      mrg 		for (pp = Player; pp < End_player; pp++) {
    133  1.1      mrg 			cgoto(pp, HEIGHT, 0);
    134  1.1      mrg 			outstr(pp, buf, n);
    135  1.1      mrg 		}
    136  1.1      mrg 		while ((n = read(newsock, buf, BUFSIZ)) > 0)
    137  1.1      mrg 			for (pp = Player; pp < End_player; pp++)
    138  1.1      mrg 				outstr(pp, buf, n);
    139  1.1      mrg 		for (pp = Player; pp < End_player; pp++) {
    140  1.1      mrg 			ce(pp);
    141  1.1      mrg 			sendcom(pp, REFRESH);
    142  1.1      mrg 			sendcom(pp, READY, 0);
    143  1.1      mrg 			(void) fflush(pp->p_output);
    144  1.1      mrg 		}
    145  1.1      mrg 		(void) close(newsock);
    146  1.1      mrg 		return FALSE;
    147  1.1      mrg 	}
    148  1.1      mrg 	else
    149  1.1      mrg # endif
    150  1.1      mrg # ifdef MONITOR
    151  1.1      mrg 	if (mode == C_MONITOR)
    152  1.4  mycroft 		if (End_monitor < &Monitor[MAXMON]) {
    153  1.1      mrg 			pp = End_monitor++;
    154  1.4  mycroft 			i = pp - Monitor + MAXPL + 3;
    155  1.4  mycroft 		} else {
    156  1.1      mrg 			socklen = 0;
    157  1.1      mrg 			(void) write(newsock, (char *) &socklen,
    158  1.1      mrg 				sizeof socklen);
    159  1.1      mrg 			(void) close(newsock);
    160  1.1      mrg 			return FALSE;
    161  1.1      mrg 		}
    162  1.1      mrg 	else
    163  1.1      mrg # endif
    164  1.4  mycroft 		if (End_player < &Player[MAXPL]) {
    165  1.1      mrg 			pp = End_player++;
    166  1.4  mycroft 			i = pp - Player + 3;
    167  1.4  mycroft 		} else {
    168  1.1      mrg 			socklen = 0;
    169  1.1      mrg 			(void) write(newsock, (char *) &socklen,
    170  1.1      mrg 				sizeof socklen);
    171  1.1      mrg 			(void) close(newsock);
    172  1.1      mrg 			return FALSE;
    173  1.1      mrg 		}
    174  1.1      mrg 
    175  1.1      mrg #ifdef MONITOR
    176  1.1      mrg 	if (mode == C_MONITOR && team == ' ')
    177  1.1      mrg 		team = '*';
    178  1.1      mrg #endif
    179  1.1      mrg 	pp->p_ident = get_ident(machine, uid, name, team);
    180  1.1      mrg 	pp->p_output = fdopen(newsock, "w");
    181  1.1      mrg 	pp->p_death[0] = '\0';
    182  1.1      mrg 	pp->p_fd = newsock;
    183  1.4  mycroft 	fdset[i].fd = newsock;
    184  1.4  mycroft 	fdset[i].events = POLLIN;
    185  1.1      mrg 
    186  1.1      mrg 	pp->p_y = 0;
    187  1.1      mrg 	pp->p_x = 0;
    188  1.1      mrg 
    189  1.1      mrg # ifdef MONITOR
    190  1.1      mrg 	if (mode == C_MONITOR)
    191  1.1      mrg 		stmonitor(pp);
    192  1.1      mrg 	else
    193  1.1      mrg # endif
    194  1.1      mrg 		stplayer(pp, enter_status);
    195  1.1      mrg 	return TRUE;
    196  1.1      mrg }
    197  1.1      mrg 
    198  1.1      mrg # ifdef MONITOR
    199  1.3    lukem void
    200  1.1      mrg stmonitor(pp)
    201  1.3    lukem 	PLAYER	*pp;
    202  1.1      mrg {
    203  1.3    lukem 	int	line;
    204  1.3    lukem 	PLAYER	*npp;
    205  1.1      mrg 
    206  1.1      mrg 	memcpy(pp->p_maze, Maze, sizeof Maze);
    207  1.1      mrg 
    208  1.1      mrg 	drawmaze(pp);
    209  1.1      mrg 
    210  1.1      mrg 	(void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
    211  1.1      mrg 		pp->p_ident->i_name, pp->p_ident->i_team);
    212  1.1      mrg 	line = STAT_MON_ROW + 1 + (pp - Monitor);
    213  1.1      mrg 	for (npp = Player; npp < End_player; npp++) {
    214  1.1      mrg 		cgoto(npp, line, STAT_NAME_COL);
    215  1.1      mrg 		outstr(npp, Buf, STAT_NAME_LEN);
    216  1.1      mrg 	}
    217  1.1      mrg 	for (npp = Monitor; npp < End_monitor; npp++) {
    218  1.1      mrg 		cgoto(npp, line, STAT_NAME_COL);
    219  1.1      mrg 		outstr(npp, Buf, STAT_NAME_LEN);
    220  1.1      mrg 	}
    221  1.1      mrg 
    222  1.1      mrg 	sendcom(pp, REFRESH);
    223  1.1      mrg 	sendcom(pp, READY, 0);
    224  1.1      mrg 	(void) fflush(pp->p_output);
    225  1.1      mrg }
    226  1.1      mrg # endif
    227  1.1      mrg 
    228  1.3    lukem void
    229  1.1      mrg stplayer(newpp, enter_status)
    230  1.3    lukem 	PLAYER	*newpp;
    231  1.3    lukem 	int	enter_status;
    232  1.1      mrg {
    233  1.3    lukem 	int	x, y;
    234  1.3    lukem 	PLAYER	*pp;
    235  1.1      mrg 
    236  1.1      mrg 	Nplayer++;
    237  1.1      mrg 
    238  1.1      mrg 	for (y = 0; y < UBOUND; y++)
    239  1.1      mrg 		for (x = 0; x < WIDTH; x++)
    240  1.1      mrg 			newpp->p_maze[y][x] = Maze[y][x];
    241  1.1      mrg 	for (     ; y < DBOUND; y++) {
    242  1.1      mrg 		for (x = 0; x < LBOUND; x++)
    243  1.1      mrg 			newpp->p_maze[y][x] = Maze[y][x];
    244  1.1      mrg 		for (     ; x < RBOUND; x++)
    245  1.1      mrg 			newpp->p_maze[y][x] = SPACE;
    246  1.1      mrg 		for (     ; x < WIDTH;  x++)
    247  1.1      mrg 			newpp->p_maze[y][x] = Maze[y][x];
    248  1.1      mrg 	}
    249  1.1      mrg 	for (     ; y < HEIGHT; y++)
    250  1.1      mrg 		for (x = 0; x < WIDTH; x++)
    251  1.1      mrg 			newpp->p_maze[y][x] = Maze[y][x];
    252  1.1      mrg 
    253  1.1      mrg 	do {
    254  1.1      mrg 		x = rand_num(WIDTH - 1) + 1;
    255  1.1      mrg 		y = rand_num(HEIGHT - 1) + 1;
    256  1.1      mrg 	} while (Maze[y][x] != SPACE);
    257  1.1      mrg 	newpp->p_over = SPACE;
    258  1.1      mrg 	newpp->p_x = x;
    259  1.1      mrg 	newpp->p_y = y;
    260  1.1      mrg 	newpp->p_undershot = FALSE;
    261  1.1      mrg 
    262  1.1      mrg # ifdef FLY
    263  1.1      mrg 	if (enter_status == Q_FLY) {
    264  1.1      mrg 		newpp->p_flying = rand_num(20);
    265  1.1      mrg 		newpp->p_flyx = 2 * rand_num(6) - 5;
    266  1.1      mrg 		newpp->p_flyy = 2 * rand_num(6) - 5;
    267  1.1      mrg 		newpp->p_face = FLYER;
    268  1.1      mrg 	}
    269  1.1      mrg 	else
    270  1.1      mrg # endif
    271  1.1      mrg 	{
    272  1.1      mrg 		newpp->p_flying = -1;
    273  1.1      mrg 		newpp->p_face = rand_dir();
    274  1.1      mrg 	}
    275  1.1      mrg 	newpp->p_damage = 0;
    276  1.1      mrg 	newpp->p_damcap = MAXDAM;
    277  1.1      mrg 	newpp->p_nchar = 0;
    278  1.1      mrg 	newpp->p_ncount = 0;
    279  1.1      mrg 	newpp->p_nexec = 0;
    280  1.1      mrg 	newpp->p_ammo = ISHOTS;
    281  1.1      mrg # ifdef BOOTS
    282  1.1      mrg 	newpp->p_nboots = 0;
    283  1.1      mrg # endif
    284  1.1      mrg 	if (enter_status == Q_SCAN) {
    285  1.1      mrg 		newpp->p_scan = SCANLEN;
    286  1.1      mrg 		newpp->p_cloak = 0;
    287  1.1      mrg 	}
    288  1.1      mrg 	else {
    289  1.1      mrg 		newpp->p_scan = 0;
    290  1.1      mrg 		newpp->p_cloak = CLOAKLEN;
    291  1.1      mrg 	}
    292  1.1      mrg 	newpp->p_ncshot = 0;
    293  1.1      mrg 
    294  1.1      mrg 	do {
    295  1.1      mrg 		x = rand_num(WIDTH - 1) + 1;
    296  1.1      mrg 		y = rand_num(HEIGHT - 1) + 1;
    297  1.1      mrg 	} while (Maze[y][x] != SPACE);
    298  1.1      mrg 	Maze[y][x] = GMINE;
    299  1.1      mrg # ifdef MONITOR
    300  1.1      mrg 	for (pp = Monitor; pp < End_monitor; pp++)
    301  1.1      mrg 		check(pp, y, x);
    302  1.1      mrg # endif
    303  1.1      mrg 
    304  1.1      mrg 	do {
    305  1.1      mrg 		x = rand_num(WIDTH - 1) + 1;
    306  1.1      mrg 		y = rand_num(HEIGHT - 1) + 1;
    307  1.1      mrg 	} while (Maze[y][x] != SPACE);
    308  1.1      mrg 	Maze[y][x] = MINE;
    309  1.1      mrg # ifdef MONITOR
    310  1.1      mrg 	for (pp = Monitor; pp < End_monitor; pp++)
    311  1.1      mrg 		check(pp, y, x);
    312  1.1      mrg # endif
    313  1.1      mrg 
    314  1.1      mrg 	(void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
    315  1.1      mrg 		stat_char(newpp), newpp->p_ident->i_name,
    316  1.1      mrg 		newpp->p_ident->i_team);
    317  1.1      mrg 	y = STAT_PLAY_ROW + 1 + (newpp - Player);
    318  1.1      mrg 	for (pp = Player; pp < End_player; pp++) {
    319  1.1      mrg 		if (pp != newpp) {
    320  1.1      mrg 			char	smallbuf[10];
    321  1.1      mrg 
    322  1.1      mrg 			pp->p_ammo += NSHOTS;
    323  1.1      mrg 			newpp->p_ammo += NSHOTS;
    324  1.1      mrg 			cgoto(pp, y, STAT_NAME_COL);
    325  1.1      mrg 			outstr(pp, Buf, STAT_NAME_LEN);
    326  1.1      mrg 			(void) sprintf(smallbuf, "%3d", pp->p_ammo);
    327  1.1      mrg 			cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
    328  1.1      mrg 			outstr(pp, smallbuf, 3);
    329  1.1      mrg 		}
    330  1.1      mrg 	}
    331  1.1      mrg # ifdef MONITOR
    332  1.1      mrg 	for (pp = Monitor; pp < End_monitor; pp++) {
    333  1.1      mrg 		cgoto(pp, y, STAT_NAME_COL);
    334  1.1      mrg 		outstr(pp, Buf, STAT_NAME_LEN);
    335  1.1      mrg 	}
    336  1.1      mrg # endif
    337  1.1      mrg 
    338  1.1      mrg 	drawmaze(newpp);
    339  1.1      mrg 	drawplayer(newpp, TRUE);
    340  1.1      mrg 	look(newpp);
    341  1.1      mrg # ifdef	FLY
    342  1.1      mrg 	if (enter_status == Q_FLY)
    343  1.1      mrg 		/* Make sure that the position you enter in will be erased */
    344  1.1      mrg 		showexpl(newpp->p_y, newpp->p_x, FLYER);
    345  1.1      mrg # endif
    346  1.1      mrg 	sendcom(newpp, REFRESH);
    347  1.1      mrg 	sendcom(newpp, READY, 0);
    348  1.1      mrg 	(void) fflush(newpp->p_output);
    349  1.1      mrg }
    350  1.1      mrg 
    351  1.1      mrg /*
    352  1.1      mrg  * rand_dir:
    353  1.1      mrg  *	Return a random direction
    354  1.1      mrg  */
    355  1.3    lukem int
    356  1.1      mrg rand_dir()
    357  1.1      mrg {
    358  1.1      mrg 	switch (rand_num(4)) {
    359  1.1      mrg 	  case 0:
    360  1.1      mrg 		return LEFTS;
    361  1.1      mrg 	  case 1:
    362  1.1      mrg 		return RIGHT;
    363  1.1      mrg 	  case 2:
    364  1.1      mrg 		return BELOW;
    365  1.1      mrg 	  case 3:
    366  1.1      mrg 		return ABOVE;
    367  1.1      mrg 	}
    368  1.1      mrg 	/* NOTREACHED */
    369  1.3    lukem 	return(-1);
    370  1.1      mrg }
    371  1.1      mrg 
    372  1.1      mrg /*
    373  1.1      mrg  * get_ident:
    374  1.1      mrg  *	Get the score structure of a player
    375  1.1      mrg  */
    376  1.1      mrg IDENT *
    377  1.1      mrg get_ident(machine, uid, name, team)
    378  1.3    lukem 	u_long	machine;
    379  1.3    lukem 	u_long	uid;
    380  1.3    lukem 	char	*name;
    381  1.3    lukem 	char	team;
    382  1.1      mrg {
    383  1.3    lukem 	IDENT		*ip;
    384  1.1      mrg 	static IDENT	punt;
    385  1.1      mrg 
    386  1.1      mrg 	for (ip = Scores; ip != NULL; ip = ip->i_next)
    387  1.1      mrg 		if (ip->i_machine == machine
    388  1.1      mrg 		&&  ip->i_uid == uid
    389  1.1      mrg 		&&  ip->i_team == team
    390  1.1      mrg 		&&  strncmp(ip->i_name, name, NAMELEN) == 0)
    391  1.1      mrg 			break;
    392  1.1      mrg 
    393  1.1      mrg 	if (ip != NULL) {
    394  1.1      mrg 		if (ip->i_entries < SCOREDECAY)
    395  1.1      mrg 			ip->i_entries++;
    396  1.1      mrg 		else
    397  1.1      mrg 			ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
    398  1.1      mrg 				/ SCOREDECAY;
    399  1.1      mrg 		ip->i_score = ip->i_kills / (double) ip->i_entries;
    400  1.1      mrg 	}
    401  1.1      mrg 	else {
    402  1.1      mrg 		ip = (IDENT *) malloc(sizeof (IDENT));
    403  1.1      mrg 		if (ip == NULL) {
    404  1.1      mrg 			/* Fourth down, time to punt */
    405  1.1      mrg 			ip = &punt;
    406  1.1      mrg 		}
    407  1.1      mrg 		ip->i_machine = machine;
    408  1.1      mrg 		ip->i_team = team;
    409  1.1      mrg 		ip->i_uid = uid;
    410  1.1      mrg 		strncpy(ip->i_name, name, NAMELEN);
    411  1.1      mrg 		ip->i_kills = 0;
    412  1.1      mrg 		ip->i_entries = 1;
    413  1.1      mrg 		ip->i_score = 0;
    414  1.1      mrg 		ip->i_absorbed = 0;
    415  1.1      mrg 		ip->i_faced = 0;
    416  1.1      mrg 		ip->i_shot = 0;
    417  1.1      mrg 		ip->i_robbed = 0;
    418  1.1      mrg 		ip->i_slime = 0;
    419  1.1      mrg 		ip->i_missed = 0;
    420  1.1      mrg 		ip->i_ducked = 0;
    421  1.1      mrg 		ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
    422  1.1      mrg 		ip->i_stillb = ip->i_saved = 0;
    423  1.1      mrg 		ip->i_next = Scores;
    424  1.1      mrg 		Scores = ip;
    425  1.1      mrg 	}
    426  1.1      mrg 
    427  1.1      mrg 	return ip;
    428  1.1      mrg }
    429