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

📄 shots.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		  case 1:			MINUS_DELTA(x, 1);			break;		  case 2:			PLUS_DELTA(y, HEIGHT - 2);			break;		  case 3:			MINUS_DELTA(y, 1);			break;		}		goto again;	  case WALL1:	  case WALL2:	  case WALL3:# ifdef	REFLECT	  case WALL4:	  case WALL5:# endif# ifdef	RANDOM	  case DOOR:# endif		if (pp->p_flying == 0)			pp->p_flying++;		break;	  case SPACE:		break;	}	pp->p_y = y;	pp->p_x = x;	if (pp->p_flying-- == 0) {# ifdef BOOTS		if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) {# endif			checkdam(pp, (PLAYER *) NULL, (IDENT *) NULL,				rand_num(pp->p_damage / 5), FALL);			pp->p_face = rand_dir();			showstat(pp);# ifdef BOOTS		}		else {			if (Maze[y][x] == BOOT)				pp->p_face = BOOT_PAIR;			Maze[y][x] = SPACE;		}# endif	}	pp->p_over = Maze[y][x];	Maze[y][x] = pp->p_face;	showexpl(y, x, pp->p_face);}/* * chkshot *	Handle explosions */chkshot(bp, next)register BULLET	*bp;BULLET		*next;{	register int	y, x;	register int	dy, dx, absdy;	register int	delta, damage;	register char	expl;	register PLAYER	*pp;	switch (bp->b_type) {	  case SHOT:	  case MINE:	  case GRENADE:	  case GMINE:	  case SATCHEL:	  case BOMB:		delta = bp->b_size - 1;		break;# ifdef	OOZE	  case SLIME:# ifdef VOLCANO	  case LAVA:# endif		chkslime(bp, next);		return;# endif# ifdef DRONE	  case DSHOT:		bp->b_type = SLIME;		chkslime(bp, next);		return;# endif	}	for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) {		if (y < 0 || y >= HEIGHT)			continue;		dy = y - bp->b_y;		absdy = (dy < 0) ? -dy : dy;		for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) {			if (x < 0 || x >= WIDTH)				continue;			dx = x - bp->b_x;			if (dx == 0)				expl = (dy == 0) ? '*' : '|';			else if (dy == 0)				expl = '-';			else if (dx == dy)				expl = '\\';			else if (dx == -dy)				expl = '/';			else				expl = '*';			showexpl(y, x, expl);			switch (Maze[y][x]) {			  case LEFTS:			  case RIGHT:			  case ABOVE:			  case BELOW:# ifdef FLY			  case FLYER:# endif				if (dx < 0)					dx = -dx;				if (absdy > dx)					damage = bp->b_size - absdy;				else					damage = bp->b_size - dx;				pp = play_at(y, x);				checkdam(pp, bp->b_owner, bp->b_score,					damage * MINDAM, bp->b_type);				break;			  case GMINE:			  case MINE:				add_shot((Maze[y][x] == GMINE) ?					GRENADE : SHOT,					y, x, LEFTS,					(Maze[y][x] == GMINE) ?					GRENREQ : BULREQ,					(PLAYER *) NULL, TRUE, SPACE);				Maze[y][x] = SPACE;				break;			}		}	}}# ifdef	OOZE/* * chkslime: *	handle slime shot exploding */chkslime(bp, next)register BULLET	*bp;BULLET		*next;{	register BULLET	*nbp;	switch (Maze[bp->b_y][bp->b_x]) {	  case WALL1:	  case WALL2:	  case WALL3:# ifdef	REFLECT	  case WALL4:	  case WALL5:# endif# ifdef	RANDOM	  case DOOR:# endif		switch (bp->b_face) {		  case LEFTS:			bp->b_x++;			break;		  case RIGHT:			bp->b_x--;			break;		  case ABOVE:			bp->b_y++;			break;		  case BELOW:			bp->b_y--;			break;		}		break;	}	nbp = (BULLET *) malloc(sizeof (BULLET));	*nbp = *bp;# ifdef VOLCANO	move_slime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED, next);# else	move_slime(nbp, SLIMESPEED, next);# endif}/* * move_slime: *	move the given slime shot speed times and add it back if *	it hasn't fizzled yet */move_slime(bp, speed, next)register BULLET	*bp;register int	speed;BULLET		*next;{	register int	i, j, dirmask, count;	register PLAYER	*pp;	register BULLET	*nbp;	if (speed == 0) {		if (bp->b_charge <= 0)			free((char *) bp);		else			save_bullet(bp);		return;	}# ifdef VOLCANO	showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');# else	showexpl(bp->b_y, bp->b_x, '*');# endif	switch (Maze[bp->b_y][bp->b_x]) {	  case LEFTS:	  case RIGHT:	  case ABOVE:	  case BELOW:# ifdef FLY	  case FLYER:# endif		pp = play_at(bp->b_y, bp->b_x);		message(pp, "You've been slimed.");		checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type);		break;	  case SHOT:	  case GRENADE:	  case SATCHEL:	  case BOMB:# ifdef DRONE	  case DSHOT:# endif		explshot(next, bp->b_y, bp->b_x);		explshot(Bullets, bp->b_y, bp->b_x);		break;	}	if (--bp->b_charge <= 0) {		free((char *) bp);		return;	}	dirmask = 0;	count = 0;	switch (bp->b_face) {	  case LEFTS:		if (!iswall(bp->b_y, bp->b_x - 1))			dirmask |= WEST, count++;		if (!iswall(bp->b_y - 1, bp->b_x))			dirmask |= NORTH, count++;		if (!iswall(bp->b_y + 1, bp->b_x))			dirmask |= SOUTH, count++;		if (dirmask == 0)			if (!iswall(bp->b_y, bp->b_x + 1))				dirmask |= EAST, count++;		break;	  case RIGHT:		if (!iswall(bp->b_y, bp->b_x + 1))			dirmask |= EAST, count++;		if (!iswall(bp->b_y - 1, bp->b_x))			dirmask |= NORTH, count++;		if (!iswall(bp->b_y + 1, bp->b_x))			dirmask |= SOUTH, count++;		if (dirmask == 0)			if (!iswall(bp->b_y, bp->b_x - 1))				dirmask |= WEST, count++;		break;	  case ABOVE:		if (!iswall(bp->b_y - 1, bp->b_x))			dirmask |= NORTH, count++;		if (!iswall(bp->b_y, bp->b_x - 1))			dirmask |= WEST, count++;		if (!iswall(bp->b_y, bp->b_x + 1))			dirmask |= EAST, count++;		if (dirmask == 0)			if (!iswall(bp->b_y + 1, bp->b_x))				dirmask |= SOUTH, count++;		break;	  case BELOW:		if (!iswall(bp->b_y + 1, bp->b_x))			dirmask |= SOUTH, count++;		if (!iswall(bp->b_y, bp->b_x - 1))			dirmask |= WEST, count++;		if (!iswall(bp->b_y, bp->b_x + 1))			dirmask |= EAST, count++;		if (dirmask == 0)			if (!iswall(bp->b_y - 1, bp->b_x))				dirmask |= NORTH, count++;		break;	}	if (count == 0) {		/*		 * No place to go.  Just sit here for a while and wait		 * for adjacent squares to clear out.		 */		save_bullet(bp);		return;	}	if (bp->b_charge < count) {		/* Only bp->b_charge paths may be taken */		while (count > bp->b_charge) {			if (dirmask & WEST)				dirmask &= ~WEST;			else if (dirmask & EAST)				dirmask &= ~EAST;			else if (dirmask & NORTH)				dirmask &= ~NORTH;			else if (dirmask & SOUTH)				dirmask &= ~SOUTH;			count--;		}	}	i = bp->b_charge / count;	j = bp->b_charge % count;	if (dirmask & WEST) {		count--;		nbp = create_shot(bp->b_type, bp->b_y, bp->b_x - 1, LEFTS,			i, bp->b_size, bp->b_owner, bp->b_score, TRUE, SPACE);		move_slime(nbp, speed - 1, next);	}	if (dirmask & EAST) {		count--;		nbp = create_shot(bp->b_type, bp->b_y, bp->b_x + 1, RIGHT,			(count < j) ? i + 1 : i, bp->b_size, bp->b_owner,			bp->b_score, TRUE, SPACE);		move_slime(nbp, speed - 1, next);	}	if (dirmask & NORTH) {		count--;		nbp = create_shot(bp->b_type, bp->b_y - 1, bp->b_x, ABOVE,			(count < j) ? i + 1 : i, bp->b_size, bp->b_owner,			bp->b_score, TRUE, SPACE);		move_slime(nbp, speed - 1, next);	}	if (dirmask & SOUTH) {		count--;		nbp = create_shot(bp->b_type, bp->b_y + 1, bp->b_x, BELOW,			(count < j) ? i + 1 : i, bp->b_size, bp->b_owner,			bp->b_score, TRUE, SPACE);		move_slime(nbp, speed - 1, next);	}	free((char *) bp);}/* * iswall: *	returns whether the given location is a wall */iswall(y, x)register int	y, x;{	if (y < 0 || x < 0 || y >= HEIGHT || x >= WIDTH)		return TRUE;	switch (Maze[y][x]) {	  case WALL1:	  case WALL2:	  case WALL3:# ifdef	REFLECT	  case WALL4:	  case WALL5:# endif# ifdef	RANDOM	  case DOOR:# endif# ifdef OOZE	  case SLIME:# ifdef VOLCANO	  case LAVA:# endif# endif		return TRUE;	}	return FALSE;}# endif/* * zapshot: *	Take a shot out of the air. */zapshot(blist, obp)register BULLET	*blist, *obp;{	register BULLET	*bp;	register FLAG	explode;	explode = FALSE;	for (bp = blist; bp != NULL; bp = bp->b_next) {		if (bp->b_x != obp->b_x || bp->b_y != obp->b_y)			continue;		if (bp->b_face == obp->b_face)			continue;		explode = TRUE;		break;	}	if (!explode)		return;	explshot(blist, obp->b_y, obp->b_x);}/* * explshot - *	Make all shots at this location blow up */explshot(blist, y, x)register BULLET	*blist;register int	y, x;{	register BULLET	*bp;	for (bp = blist; bp != NULL; bp = bp->b_next)		if (bp->b_x == x && bp->b_y == y) {			bp->b_expl = TRUE;			if (bp->b_owner != NULL)				message(bp->b_owner, "Shot intercepted");		}}/* * play_at: *	Return a pointer to the player at the given location */PLAYER *play_at(y, x)register int	y, x;{	register PLAYER	*pp;	for (pp = Player; pp < End_player; pp++)		if (pp->p_x == x && pp->p_y == y)			return pp;	fprintf(stderr, "driver: couldn't find player at (%d,%d)\n", x, y);	abort();	/* NOTREACHED */}/* * opposite: *	Return TRUE if the bullet direction faces the opposite direction *	of the player in the maze */opposite(face, dir)int	face;char	dir;{	switch (face) {	  case LEFTS:		return (dir == RIGHT);	  case RIGHT:		return (dir == LEFTS);	  case ABOVE:		return (dir == BELOW);	  case BELOW:		return (dir == ABOVE);	  default:		return FALSE;	}}/* * is_bullet: *	Is there a bullet at the given coordinates?  If so, return *	a pointer to the bullet, otherwise return NULL */BULLET *is_bullet(y, x)register int	y, x;{	register BULLET	*bp;	for (bp = Bullets; bp != NULL; bp = bp->b_next)		if (bp->b_y == y && bp->b_x == x)			return bp;	return NULL;}/* * fixshots: *	change the underlying character of the shots at a location *	to the given character. */fixshots(y, x, over)register int	y, x;char		over;{	register BULLET	*bp;	for (bp = Bullets; bp != NULL; bp = bp->b_next)		if (bp->b_y == y && bp->b_x == x)			bp->b_over = over;}/* * find_under: *	find the underlying character for a bullet when it lands *	on another bullet. */find_under(blist, bp)register BULLET	*blist, *bp;{	register BULLET	*nbp;	for (nbp = blist; nbp != NULL; nbp = nbp->b_next)		if (bp->b_y == nbp->b_y && bp->b_x == nbp->b_x) {			bp->b_over = nbp->b_over;			break;		}}/* * mark_player: *	mark a player as under a shot */mark_player(bp)register BULLET	*bp;{	register PLAYER	*pp;	for (pp = Player; pp < End_player; pp++)		if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {			pp->p_undershot = TRUE;			break;		}}# ifdef BOOTS/* * mark_boot: *	mark a boot as under a shot */mark_boot(bp)register BULLET	*bp;{	register PLAYER	*pp;	for (pp = Boot; pp < &Boot[NBOOTS]; pp++)		if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {			pp->p_undershot = TRUE;			break;		}}# endif

⌨️ 快捷键说明

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