⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shots.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Hunt *  Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold *  San Francisco, California */# include	"hunt.h"# include	<signal.h># define	PLUS_DELTA(x, max)	if (x < max) x++; else x--# define	MINUS_DELTA(x, min)	if (x > min) x--; else x++/* * moveshots: *	Move the shots already in the air, taking explosions into account */moveshots(){	register BULLET	*bp, *next;	register PLAYER	*pp;	register int	x, y;	register BULLET	*blist;	rollexpl();	if (Bullets == NULL)		goto ret;	/*	 * First we move through the bullet list BULSPD times, looking	 * for things we may have run into.  If we do run into	 * something, we set up the explosion and disappear, checking	 * for damage to any player who got in the way.	 */	blist = Bullets;	Bullets = NULL;	for (bp = blist; bp != NULL; bp = next) {		next = bp->b_next;		x = bp->b_x;		y = bp->b_y;		Maze[y][x] = bp->b_over;		for (pp = Player; pp < End_player; pp++)			check(pp, y, x);# ifdef MONITOR		for (pp = Monitor; pp < End_monitor; pp++)			check(pp, y, x);# endif		switch (bp->b_type) {		  case SHOT:		  case GRENADE:		  case SATCHEL:		  case BOMB:			if (move_normal_shot(bp)) {				bp->b_next = Bullets;				Bullets = bp;			}			break;# ifdef OOZE		  case SLIME:			if (bp->b_expl || move_normal_shot(bp)) {				bp->b_next = Bullets;				Bullets = bp;			}			break;# endif# ifdef DRONE		  case DSHOT:			if (move_drone(bp)) {				bp->b_next = Bullets;				Bullets = bp;			}			break;# endif		  default:			bp->b_next = Bullets;			Bullets = bp;			break;		}	}	blist = Bullets;	Bullets = NULL;	for (bp = blist; bp != NULL; bp = next) {		next = bp->b_next;		if (!bp->b_expl) {			save_bullet(bp);# ifdef MONITOR			for (pp = Monitor; pp < End_monitor; pp++)				check(pp, bp->b_y, bp->b_x);# endif# ifdef DRONE			if (bp->b_type == DSHOT)				for (pp = Player; pp < End_player; pp++)					if (pp->p_scan >= 0)						check(pp, bp->b_y, bp->b_x);# endif			continue;		}		chkshot(bp, next);		free((char *) bp);	}	for (pp = Player; pp < End_player; pp++)		Maze[pp->p_y][pp->p_x] = pp->p_face;ret:# ifdef BOOTS	for (pp = Boot; pp < &Boot[NBOOTS]; pp++)		if (pp->p_flying >= 0)			move_flyer(pp);# endif	for (pp = Player; pp < End_player; pp++) {# ifdef FLY		if (pp->p_flying >= 0)			move_flyer(pp);# endif		sendcom(pp, REFRESH);	/* Flush out the explosions */		look(pp);		sendcom(pp, REFRESH);	}# ifdef MONITOR	for (pp = Monitor; pp < End_monitor; pp++)		sendcom(pp, REFRESH);# endif	return;}/* * move_normal_shot: *	Move a normal shot along its trajectory */move_normal_shot(bp)register BULLET	*bp;{	register int	i, x, y;	register PLAYER	*pp;	for (i = 0; i < BULSPD; i++) {		if (bp->b_expl)			break;		x = bp->b_x;		y = bp->b_y;		switch (bp->b_face) {		  case LEFTS:			x--;			break;		  case RIGHT:			x++;			break;		  case ABOVE:			y--;			break;		  case BELOW:			y++;			break;		}		switch (Maze[y][x]) {		  case SHOT:			if (rand_num(100) < 5) {				zapshot(Bullets, bp);				zapshot(bp->b_next, bp);			}			break;		  case GRENADE:			if (rand_num(100) < 10) {				zapshot(Bullets, bp);				zapshot(bp->b_next, bp);			}			break;# ifdef	REFLECT		  case WALL4:	/* reflecting walls */			switch (bp->b_face) {			  case LEFTS:				bp->b_face = BELOW;				break;			  case RIGHT:				bp->b_face = ABOVE;				break;			  case ABOVE:				bp->b_face = RIGHT;				break;			  case BELOW:				bp->b_face = LEFTS;				break;			}			Maze[y][x] = WALL5;# ifdef MONITOR			for (pp = Monitor; pp < End_monitor; pp++)				check(pp, y, x);# endif			break;		  case WALL5:			switch (bp->b_face) {			  case LEFTS:				bp->b_face = ABOVE;				break;			  case RIGHT:				bp->b_face = BELOW;				break;			  case ABOVE:				bp->b_face = LEFTS;				break;			  case BELOW:				bp->b_face = RIGHT;				break;			}			Maze[y][x] = WALL4;# ifdef MONITOR			for (pp = Monitor; pp < End_monitor; pp++)				check(pp, y, x);# endif			break;# endif# ifdef RANDOM		  case DOOR:			switch (rand_num(4)) {			  case 0:				bp->b_face = ABOVE;				break;			  case 1:				bp->b_face = BELOW;				break;			  case 2:				bp->b_face = LEFTS;				break;			  case 3:				bp->b_face = RIGHT;				break;			}			break;# endif# ifdef FLY		  case FLYER:			pp = play_at(y, x);			message(pp, "Zing!");			break;# endif		  case LEFTS:		  case RIGHT:		  case BELOW:		  case ABOVE:			/*			 * give the person a chance to catch a			 * grenade if s/he is facing it			 */			pp = play_at(y, x);			pp->p_ident->i_shot += bp->b_charge;			if (opposite(bp->b_face, Maze[y][x])) {			    if (rand_num(100) < 10) {				if (bp->b_owner != NULL)					message(bp->b_owner,					    "Your charge was absorbed!");				if (bp->b_score != NULL)					bp->b_score->i_robbed += bp->b_charge;				pp->p_ammo += bp->b_charge;				if (pp->p_damage + bp->b_size * MINDAM				    > pp->p_damcap)					pp->p_ident->i_saved++;				message(pp, "Absorbed charge (good shield!)");				pp->p_ident->i_absorbed += bp->b_charge;				free((char *) bp);				(void) sprintf(Buf, "%3d", pp->p_ammo);				cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);				outstr(pp, Buf, 3);				return FALSE;			    }			    pp->p_ident->i_faced += bp->b_charge;			}			/*			 * Small chance that the bullet just misses the			 * person.  If so, the bullet just goes on its			 * merry way without exploding.			 */			if (rand_num(100) < 5) {				pp->p_ident->i_ducked += bp->b_charge;				if (pp->p_damage + bp->b_size * MINDAM				    > pp->p_damcap)					pp->p_ident->i_saved++;				if (bp->b_score != NULL)					bp->b_score->i_missed += bp->b_charge;				message(pp, "Zing!");				if (bp->b_owner == NULL)					break;				message(bp->b_owner,					((bp->b_score->i_missed & 0x7) == 0x7) ?					"My!  What a bad shot you are!" :					"Missed him");				break;			}			/*			 * The shot hit that sucker!  Blow it up.			 */			/* FALLTHROUGH */# ifndef RANDOM		  case DOOR:# endif		  case WALL1:		  case WALL2:		  case WALL3:			bp->b_expl = TRUE;			break;		}		bp->b_x = x;		bp->b_y = y;	}	return TRUE;}# ifdef	DRONE/* * move_drone: *	Move the drone to the next square */move_drone(bp)register BULLET	*bp;{	register int	mask, count;	register int	n, dir;	register PLAYER	*pp;	/*	 * See if we can give someone a blast	 */	if (isplayer(Maze[bp->b_y][bp->b_x - 1])) {		dir = WEST;		goto drone_move;	}	if (isplayer(Maze[bp->b_y - 1][bp->b_x])) {		dir = NORTH;		goto drone_move;	}	if (isplayer(Maze[bp->b_y + 1][bp->b_x])) {		dir = SOUTH;		goto drone_move;	}	if (isplayer(Maze[bp->b_y][bp->b_x + 1])) {		dir = EAST;		goto drone_move;	}	/*	 * Find out what directions are clear	 */	mask = count = 0;	if (!iswall(bp->b_y, bp->b_x - 1))		mask |= WEST, count++;	if (!iswall(bp->b_y - 1, bp->b_x))		mask |= NORTH, count++;	if (!iswall(bp->b_y + 1, bp->b_x))		mask |= SOUTH, count++;	if (!iswall(bp->b_y, bp->b_x + 1))		mask |= EAST, count++;	/*	 * All blocked up, just you wait	 */	if (count == 0)		return TRUE;	/*	 * Only one way to go.	 */	if (count == 1) {		dir = mask;		goto drone_move;	}	/*	 * Get rid of the direction that we came from	 */	switch (bp->b_face) {	  case LEFTS:		if (mask & EAST)			mask &= ~EAST, count--;		break;	  case RIGHT:		if (mask & WEST)			mask &= ~WEST, count--;		break;	  case ABOVE:		if (mask & SOUTH)			mask &= ~SOUTH, count--;		break;	  case BELOW:		if (mask & NORTH)			mask &= ~NORTH, count--;		break;	}	/*	 * Pick one of the remaining directions	 */	n = rand_num(count);	if (n >= 0 && mask & NORTH)		dir = NORTH, n--;	if (n >= 0 && mask & SOUTH)		dir = SOUTH, n--;	if (n >= 0 && mask & EAST)		dir = EAST, n--;	if (n >= 0 && mask & WEST)		dir = WEST, n--;	/*	 * Now that we know the direction of movement,	 * just update the position of the drone	 */drone_move:	switch (dir) {	  case WEST:		bp->b_x--;		bp->b_face = LEFTS;		break;	  case EAST:		bp->b_x++;		bp->b_face = RIGHT;		break;	  case NORTH:		bp->b_y--;		bp->b_face = ABOVE;		break;	  case SOUTH:		bp->b_y++;		bp->b_face = BELOW;		break;	}	switch (Maze[bp->b_y][bp->b_x]) {	  case LEFTS:	  case RIGHT:	  case BELOW:	  case ABOVE:		/*		 * give the person a chance to catch a		 * drone if s/he is facing it		 */		if (rand_num(100) < 1 &&		opposite(bp->b_face, Maze[bp->b_y][bp->b_x])) {			pp = play_at(bp->b_y, bp->b_x);			pp->p_ammo += bp->b_charge;			message(pp, "**** Absorbed drone ****");			free((char *) bp);			(void) sprintf(Buf, "%3d", pp->p_ammo);			cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);			outstr(pp, Buf, 3);			return FALSE;		}		bp->b_expl = TRUE;		break;	}	return TRUE;}# endif/* * save_bullet: *	Put this bullet back onto the bullet list */save_bullet(bp)register BULLET	*bp;{	bp->b_over = Maze[bp->b_y][bp->b_x];	switch (bp->b_over) {	  case SHOT:	  case GRENADE:	  case SATCHEL:	  case BOMB:# ifdef OOZE	  case SLIME:# ifdef VOLCANO	  case LAVA:# endif# endif# ifdef DRONE	  case DSHOT:# endif		find_under(Bullets, bp);		break;	}	switch (bp->b_over) {	  case LEFTS:	  case RIGHT:	  case ABOVE:	  case BELOW:# ifdef FLY	  case FLYER:# endif		mark_player(bp);		break;# ifdef BOOTS	  case BOOT:	  case BOOT_PAIR:		mark_boot(bp);# endif			  default:		Maze[bp->b_y][bp->b_x] = bp->b_type;		break;	}	bp->b_next = Bullets;	Bullets = bp;}/* * move_flyer: *	Update the position of a player in flight */move_flyer(pp)register PLAYER	*pp;{	register int	x, y;	if (pp->p_undershot) {		fixshots(pp->p_y, pp->p_x, pp->p_over);		pp->p_undershot = FALSE;	}	Maze[pp->p_y][pp->p_x] = pp->p_over;	x = pp->p_x + pp->p_flyx;	y = pp->p_y + pp->p_flyy;	if (x < 1) {		x = 1 - x;		pp->p_flyx = -pp->p_flyx;	}	else if (x > WIDTH - 2) {		x = (WIDTH - 2) - (x - (WIDTH - 2));		pp->p_flyx = -pp->p_flyx;	}	if (y < 1) {		y = 1 - y;		pp->p_flyy = -pp->p_flyy;	}	else if (y > HEIGHT - 2) {		y = (HEIGHT - 2) - (y - (HEIGHT - 2));		pp->p_flyy = -pp->p_flyy;	}again:	switch (Maze[y][x]) {	  default:		switch (rand_num(4)) {		  case 0:			PLUS_DELTA(x, WIDTH - 2);			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -