Exemplo n.º 1
0
/*
 * fire_slime:
 *	Fire a slime shot in the given direction
 */
static void
fire_slime(PLAYER *pp, int req_index)
{
	if (pp == NULL)
		return;

	/* Check configuration: */
	if (!conf_ooze)
		return;

	/* Drop the slime type back util we can afford it: */
	while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
		req_index--;

	/* Can we afford to slime at all? */
	if (req_index < 0) {
		message(pp, "Not enough charges.");
		return;
	}

	/* Is the gun too hot? */
	if (pp->p_ncshot > conf_maxncshot)
		return;

	/* Heat up the gun: */
	if (pp->p_ncshot++ == conf_maxncshot) {
		/* The gun has overheated: */
		outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, "   ");
	}

	/* Use up some ammo: */
	pp->p_ammo -= slime_req[req_index];
	ammo_update(pp);

	/* Start the slime moving: */
	add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
		slime_req[req_index] * conf_slimefactor, pp, FALSE, pp->p_face);
	pp->p_undershot = TRUE;

	/* Show the object to everyone: */
	showexpl(pp->p_y, pp->p_x, SLIME);
	sendcom(ALL_PLAYERS, REFRESH);
}
Exemplo n.º 2
0
/*
 * fire_slime:
 *	Fire a slime shot in the given direction
 */
static void
fire_slime(PLAYER *pp, int req_index)
{
	if (pp == NULL)
		return;
#ifdef DEBUG
	if (req_index < 0 || req_index >= MAXSLIME)
		message(pp, "What you do?");
#endif
	while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
		req_index--;
	if (req_index < 0) {
		message(pp, "Not enough charges.");
		return;
	}
	if (pp->p_ncshot > MAXNCSHOT)
		return;
	if (pp->p_ncshot++ == MAXNCSHOT) {
		cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
		outstr(pp, "   ", 3);
	}
	pp->p_ammo -= slime_req[req_index];
	(void) snprintf(Buf, sizeof(Buf), "%3d", pp->p_ammo);
	cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
	outstr(pp, Buf, 3);

	add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
		slime_req[req_index] * SLIME_FACTOR, pp, false, pp->p_face);
	pp->p_undershot = true;

	/*
	 * Show the object to everyone
	 */
	showexpl(pp->p_y, pp->p_x, SLIME);
	for (pp = Player; pp < End_player; pp++)
		sendcom(pp, REFRESH);
#ifdef MONITOR
	for (pp = Monitor; pp < End_monitor; pp++)
		sendcom(pp, REFRESH);
#endif
}
Exemplo n.º 3
0
/*
 * fire:
 *	Fire a shot of the given type in the given direction
 */
static void
fire(PLAYER *pp, int req_index)
{
	if (pp == NULL)
		return;

	/* Drop the shot type down until we can afford it: */
	while (req_index >= 0 && pp->p_ammo < shot_req[req_index])
		req_index--;

	/* Can we shoot at all? */
	if (req_index < 0) {
		message(pp, "Not enough charges.");
		return;
	}

	/* Check if the gun is too hot: */
	if (pp->p_ncshot > conf_maxncshot)
		return;

	/* Heat up the gun: */
	if (pp->p_ncshot++ == conf_maxncshot) {
		/* The gun has overheated: */
		outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, "   ");
	}

	/* Use up some ammo: */
	pp->p_ammo -= shot_req[req_index];
	ammo_update(pp);

	/* Start the bullet moving: */
	add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face,
		shot_req[req_index], pp, FALSE, pp->p_face);
	pp->p_undershot = TRUE;

	/* Show the bullet to everyone: */
	showexpl(pp->p_y, pp->p_x, shot_type[req_index]);
	sendcom(ALL_PLAYERS, REFRESH);
}
Exemplo n.º 4
0
/*
 * remove_wall - add a location where the wall was blown away.
 *		 if there is no space left over, put the a wall at
 *		 the location currently pointed at.
 */
static void
remove_wall(int y, int x)
{
	REGEN *r;
#if defined(MONITOR) || defined(FLY)
	PLAYER *pp;
#endif
#ifdef FLY
	char save_char = 0;
#endif

	r = rem_index;
	while (r->r_y != 0) {
#ifdef FLY
		switch (Maze[r->r_y][r->r_x]) {
		  case SPACE:
		  case LEFTS:
		  case RIGHT:
		  case ABOVE:
		  case BELOW:
		  case FLYER:
			save_char = Maze[r->r_y][r->r_x];
			goto found;
		}
#else
		if (Maze[r->r_y][r->r_x] == SPACE)
			break;
#endif
		if (++r >= &removed[MAXREMOVE])
			r = removed;
	}

found:
	if (r->r_y != 0) {
		/* Slot being used, put back this wall */
#ifdef FLY
		if (save_char == SPACE)
			Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
		else {
			pp = play_at(r->r_y, r->r_x);
			if (pp->p_flying >= 0)
				pp->p_flying += rand_num(10);
			else {
				pp->p_flying = rand_num(20);
				pp->p_flyx = 2 * rand_num(6) - 5;
				pp->p_flyy = 2 * rand_num(6) - 5;
			}
			pp->p_over = Orig_maze[r->r_y][r->r_x];
			pp->p_face = FLYER;
			Maze[r->r_y][r->r_x] = FLYER;
			showexpl(r->r_y, r->r_x, FLYER);
		}
#else
		Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
#endif
#ifdef RANDOM
		if (rand_num(100) == 0)
			Maze[r->r_y][r->r_x] = DOOR;
#endif
#ifdef REFLECT
		if (rand_num(100) == 0)		/* one percent of the time */
			Maze[r->r_y][r->r_x] = WALL4;
#endif
#ifdef MONITOR
		for (pp = Monitor; pp < End_monitor; pp++)
			check(pp, r->r_y, r->r_x);
#endif
	}

	r->r_y = y;
	r->r_x = x;
	if (++r >= &removed[MAXREMOVE])
		rem_index = removed;
	else
		rem_index = r;

	Maze[y][x] = SPACE;
#ifdef MONITOR
	for (pp = Monitor; pp < End_monitor; pp++)
		check(pp, y, x);
#endif
}
Exemplo n.º 5
0
/*
 * move_slime:
 *	move the given slime shot speed times and add it back if
 *	it hasn't fizzled yet
 */
static void
move_slime(BULLET *bp, int speed, BULLET *next)
{
    int	i, j, dirmask, count;
    PLAYER	*pp;
    BULLET	*nbp;

    if (speed == 0) {
        if (bp->b_charge <= 0)
            free(bp);
        else
            save_bullet(bp);
        return;
    }

    /* Draw it: */
    showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');

    switch (Maze[bp->b_y][bp->b_x]) {
    /* Someone got hit by slime or lava: */
    case LEFTS:
    case RIGHT:
    case ABOVE:
    case BELOW:
    case FLYER:
        pp = play_at(bp->b_y, bp->b_x);
        message(pp, "You've been slimed.");
        checkdam(pp, bp->b_owner, bp->b_score, conf_mindam, bp->b_type);
        break;
    /* Bullets detonate in slime and lava: */
    case SHOT:
    case GRENADE:
    case SATCHEL:
    case BOMB:
    case DSHOT:
        explshot(next, bp->b_y, bp->b_x);
        explshot(Bullets, bp->b_y, bp->b_x);
        break;
    }


    /* Drain the slime/lava of some energy: */
    if (--bp->b_charge <= 0) {
        /* It fizzled: */
        free(bp);
        return;
    }

    /* Figure out which way the slime should flow: */
    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--;
        }
    }

    /* Spawn little slimes off in every possible direction: */
    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(bp);
}
Exemplo n.º 6
0
/*
 * chkshot
 *	Handle explosions
 */
static void
chkshot(BULLET *bp, BULLET *next)
{
    int	y, x;
    int	dy, dx, absdy;
    int	delta, damage;
    char	expl;
    PLAYER	*pp;

    delta = 0;
    switch (bp->b_type) {
    case SHOT:
    case MINE:
    case GRENADE:
    case GMINE:
    case SATCHEL:
    case BOMB:
        delta = bp->b_size - 1;
        break;
    case SLIME:
    case LAVA:
        chkslime(bp, next);
        return;
    case DSHOT:
        bp->b_type = SLIME;
        chkslime(bp, next);
        return;
    }

    /* Draw the explosion square: */
    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++) {
            /* Draw a part of the explosion cloud: */
            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);

            /* Check what poor bastard was in the explosion: */
            switch (Maze[y][x]) {
            case LEFTS:
            case RIGHT:
            case ABOVE:
            case BELOW:
            case FLYER:
                if (dx < 0)
                    dx = -dx;
                if (absdy > dx)
                    damage = bp->b_size - absdy;
                else
                    damage = bp->b_size - dx;

                /* Everybody hurts, sometimes. */
                pp = play_at(y, x);
                checkdam(pp, bp->b_owner, bp->b_score,
                         damage * conf_mindam, bp->b_type);
                break;
            case GMINE:
            case MINE:
                /* Mines detonate in a chain reaction: */
                add_shot((Maze[y][x] == GMINE) ?
                         GRENADE : SHOT,
                         y, x, LEFTS,
                         (Maze[y][x] == GMINE) ?
                         GRENREQ : BULREQ,
                         NULL, TRUE, SPACE);
                Maze[y][x] = SPACE;
                break;
            }
        }
    }
}
Exemplo n.º 7
0
/*
 * move_flyer:
 *	Update the position of a player in flight
 */
static void
move_flyer(PLAYER *pp)
{
    int	x, y;

    if (pp->p_undershot) {
        fixshots(pp->p_y, pp->p_x, pp->p_over);
        pp->p_undershot = FALSE;
    }

    /* Restore what the flier was flying over */
    Maze[pp->p_y][pp->p_x] = pp->p_over;

    /* Fly: */
    x = pp->p_x + pp->p_flyx;
    y = pp->p_y + pp->p_flyy;

    /* Bouncing off the edges of the maze: */
    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;
    }

    /* Make sure we don't land on something we can't: */
again:
    switch (Maze[y][x]) {
    default:
        /*
         * Flier is over something other than space, a wall
         * or a door. Randomly move (drift) the flier a little bit
         * and then try again:
         */
        switch (rand_num(4)) {
        case 0:
            PLUS_DELTA(x, WIDTH - 2);
            break;
        case 1:
            MINUS_DELTA(x, 1);
            break;
        case 2:
            PLUS_DELTA(y, HEIGHT - 2);
            break;
        case 3:
            MINUS_DELTA(y, 1);
            break;
        }
        goto again;
    /* Give a little boost when about to land on a wall or door: */
    case WALL1:
    case WALL2:
    case WALL3:
    case WALL4:
    case WALL5:
    case DOOR:
        if (pp->p_flying == 0)
            pp->p_flying++;
        break;
    /* Spaces are okay: */
    case SPACE:
        break;
    }

    /* Update flier's coordinates: */
    pp->p_y = y;
    pp->p_x = x;

    /* Consume 'flying' time: */
    if (pp->p_flying-- == 0) {
        /* Land: */
        if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) {
            /* Land a player - they stustain a fall: */
            checkdam(pp, NULL, NULL,
                     rand_num(pp->p_damage / conf_fall_frac), FALL);
            pp->p_face = rand_dir();
            showstat(pp);
        } else {
            /* Land boots: */
            if (Maze[y][x] == BOOT)
                pp->p_face = BOOT_PAIR;
            Maze[y][x] = SPACE;
        }
    }

    /* Save under the flier: */
    pp->p_over = Maze[y][x];
    /* Draw in the flier: */
    Maze[y][x] = pp->p_face;
    showexpl(y, x, pp->p_face);
}
Exemplo n.º 8
0
/*
 * zap:
 *	Kill off a player and take them out of the game.
 *	The 'was_player' flag indicates that the player was not
 *	a monitor and needs extra cleaning up.
 */
static void
zap(PLAYER *pp, FLAG was_player)
{
	int	len;
	BULLET	*bp;
	PLAYER	*np;
	int	x, y;
	int	savefd;

	if (was_player) {
		/* If they died from a shot, clean up shrapnel */
		if (pp->p_undershot)
			fixshots(pp->p_y, pp->p_x, pp->p_over);
		/* Let the player see their last position: */
		drawplayer(pp, FALSE);
		/* Remove from game: */
		Nplayer--;
	}

	/* Display the cause of death in the centre of the screen: */
	len = strlen(pp->p_death);
	x = (WIDTH - len) / 2;
	outyx(pp, HEIGHT / 2, x, "%s", pp->p_death);

	/* Put some horizontal lines around and below the death message: */
	memset(pp->p_death + 1, '-', len - 2);
	pp->p_death[0] = '+';
	pp->p_death[len - 1] = '+';
	outyx(pp, HEIGHT / 2 - 1, x, "%s", pp->p_death);
	outyx(pp, HEIGHT / 2 + 1, x, "%s", pp->p_death);

	/* Move to bottom left */
	cgoto(pp, HEIGHT, 0);

	savefd = pp->p_fd;

	if (was_player) {
		int	expl_charge;
		int	expl_type;
		int	ammo_exploding;

		/* Check all the bullets: */
		for (bp = Bullets; bp != NULL; bp = bp->b_next) {
			if (bp->b_owner == pp)
				/* Zapped players can't own bullets: */
				bp->b_owner = NULL;
			if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
				/* Bullets over the player are now over air: */
				bp->b_over = SPACE;
		}

		/* Explode a random fraction of the player's ammo: */
		ammo_exploding = rand_num(pp->p_ammo);

		/* Determine the type and amount of detonation: */
		expl_charge = rand_num(ammo_exploding + 1);
		if (pp->p_ammo == 0)
			/* Ignore the no-ammo case: */
			expl_charge = expl_type = 0;
		else if (ammo_exploding >= pp->p_ammo - 1) {
			/* Maximal explosions always appear as slime: */
			expl_charge = pp->p_ammo;
			expl_type = SLIME;
		} else {
			/*
			 * Figure out the best effective explosion
			 * type to use, given the amount of charge
			 */
			int btype, stype;
			for (btype = MAXBOMB - 1; btype > 0; btype--)
				if (expl_charge >= shot_req[btype])
					break;
			for (stype = MAXSLIME - 1; stype > 0; stype--)
				if (expl_charge >= slime_req[stype])
					break;
			/* Pick the larger of the bomb or slime: */
			if (btype >= 0 && stype >= 0) {
				if (shot_req[btype] > slime_req[btype])
					btype = -1;
			}
			if (btype >= 0)  {
				expl_type = shot_type[btype];
				expl_charge = shot_req[btype];
			} else
				expl_type = SLIME;
		}

		if (expl_charge > 0) {
			char buf[BUFSIZ];

			/* Detonate: */
			(void) add_shot(expl_type, pp->p_y, pp->p_x,
			    pp->p_face, expl_charge, NULL,
			    TRUE, SPACE);

			/* Explain what the explosion is about. */
			snprintf(buf, sizeof buf, "%s detonated.",
				pp->p_ident->i_name);
			message(ALL_PLAYERS, buf);

			while (pp->p_nboots-- > 0) {
				/* Throw one of the boots away: */
				for (np = Boot; np < &Boot[NBOOTS]; np++)
					if (np->p_flying < 0)
						break;
#ifdef DIAGNOSTIC
				if (np >= &Boot[NBOOTS])
					err(1, "Too many boots");
#endif
				/* Start the boots from where the player is */
				np->p_undershot = FALSE;
				np->p_x = pp->p_x;
				np->p_y = pp->p_y;
				/* Throw for up to 20 steps */
				np->p_flying = rand_num(20);
				np->p_flyx = 2 * rand_num(6) - 5;
				np->p_flyy = 2 * rand_num(6) - 5;
				np->p_over = SPACE;
				np->p_face = BOOT;
				showexpl(np->p_y, np->p_x, BOOT);
			}
		}
		/* No explosion. Leave the player's boots behind. */
		else if (pp->p_nboots > 0) {
			if (pp->p_nboots == 2)
				Maze[pp->p_y][pp->p_x] = BOOT_PAIR;
			else
				Maze[pp->p_y][pp->p_x] = BOOT;
			if (pp->p_undershot)
				fixshots(pp->p_y, pp->p_x,
					Maze[pp->p_y][pp->p_x]);
		}

		/* Any unexploded ammo builds up in the volcano: */
		volcano += pp->p_ammo - expl_charge;

		/* Volcano eruption: */
		if (conf_volcano && rand_num(100) < volcano /
		    conf_volcano_max) {
			/* Erupt near the middle of the map */
			do {
				x = rand_num(WIDTH / 2) + WIDTH / 4;
				y = rand_num(HEIGHT / 2) + HEIGHT / 4;
			} while (Maze[y][x] != SPACE);

			/* Convert volcano charge into lava: */
			(void) add_shot(LAVA, y, x, LEFTS, volcano,
				NULL, TRUE, SPACE);
			volcano = 0;

			/* Tell eveyone what's happening */
			message(ALL_PLAYERS, "Volcano eruption.");
		}

		/* Drone: */
		if (conf_drone && rand_num(100) < 2) {
			/* Find a starting place near the middle of the map: */
			do {
				x = rand_num(WIDTH / 2) + WIDTH / 4;
				y = rand_num(HEIGHT / 2) + HEIGHT / 4;
			} while (Maze[y][x] != SPACE);

			/* Start the drone going: */
			add_shot(DSHOT, y, x, rand_dir(),
				shot_req[conf_mindshot +
				rand_num(MAXBOMB - conf_mindshot)],
				NULL, FALSE, SPACE);
		}

		/* Tell the zapped player's client to shut down. */
		sendcom(pp, ENDWIN, ' ');
		(void) fclose(pp->p_output);

		/* Close up the gap in the Player array: */
		End_player--;
		if (pp != End_player) {
			/* Move the last player into the gap: */
			memcpy(pp, End_player, sizeof *pp);
			outyx(ALL_PLAYERS,
				STAT_PLAY_ROW + 1 + (pp - Player),
				STAT_NAME_COL,
				"%5.2f%c%-10.10s %c",
				pp->p_ident->i_score, stat_char(pp),
				pp->p_ident->i_name, pp->p_ident->i_team);
		}

		/* Erase the last player from the display: */
		cgoto(ALL_PLAYERS, STAT_PLAY_ROW + 1 + Nplayer, STAT_NAME_COL);
		ce(ALL_PLAYERS);
	}
	else {
		/* Zap a monitor */

		/* Close the session: */
		sendcom(pp, ENDWIN, LAST_PLAYER);
		(void) fclose(pp->p_output);

		/* shuffle the monitor table */
		End_monitor--;
		if (pp != End_monitor) {
			memcpy(pp, End_monitor, sizeof *pp);
			outyx(ALL_PLAYERS,
				STAT_MON_ROW + 1 + (pp - Player), STAT_NAME_COL,
				"%5.5s %-10.10s %c", " ",
				pp->p_ident->i_name, pp->p_ident->i_team);
		}

		/* Erase the last monitor in the list */
		cgoto(ALL_PLAYERS,
			STAT_MON_ROW + 1 + (End_monitor - Monitor),
			STAT_NAME_COL);
		ce(ALL_PLAYERS);
	}

	/* Update the file descriptor sets used by select: */
	FD_CLR(savefd, &Fds_mask);
	if (Num_fds == savefd + 1) {
		Num_fds = Socket;
		if (Server_socket > Socket)
			Num_fds = Server_socket;
		for (np = Player; np < End_player; np++)
			if (np->p_fd > Num_fds)
				Num_fds = np->p_fd;
		for (np = Monitor; np < End_monitor; np++)
			if (np->p_fd > Num_fds)
				Num_fds = np->p_fd;
		Num_fds++;
	}
}
Exemplo n.º 9
0
/**
 * Initializes a player status.
 * @param[out] newpp The new player to initialize.
 * @param[in] enter_status The enter mode of a player.
 * [PSR]
 */
void stplayer(PLAYER *newpp, int enter_status) {
	int x, y;
	PLAYER *pp;

	nplayer++;

	for (y = 0; y < UBOUND; y++) {
		for (x = 0; x < WIDTH; x++) {
			newpp->p_maze[y][x] = maze[y][x];
		}
	}
	for (; y < DBOUND; y++) {
		for (x = 0; x < LBOUND; x++) {
			newpp->p_maze[y][x] = maze[y][x];
		}
		for (; x < RBOUND; x++) {
			newpp->p_maze[y][x] = SPACE;
		}
		for (; x < WIDTH; x++) {
			newpp->p_maze[y][x] = maze[y][x];
		}
	}
	for (; y < HEIGHT; y++) {
		for (x = 0; x < WIDTH; x++) {
			newpp->p_maze[y][x] = maze[y][x];
		}
	}

	do {
		x = rand_num(WIDTH - 1) + 1;
		y = rand_num(HEIGHT - 1) + 1;
	} while (maze[y][x] != SPACE);
	newpp->p_over = SPACE;
	newpp->p_x = x;
	newpp->p_y = y;
	newpp->p_undershot = false;

# ifdef FLY
	if (enter_status == Q_FLY) {
		newpp->p_flying = rand_num(20);
		newpp->p_flyx = 2 * rand_num(6) - 5;
		newpp->p_flyy = 2 * rand_num(6) - 5;
		newpp->p_face = FLYER;
	}
	else
# endif
	{
# ifdef FLY
		newpp->p_flying = -1;
# endif
		newpp->p_face = rand_dir();
	}
	newpp->p_damage = 0;
	newpp->p_damcap = MAXDAM;
	newpp->p_nchar = 0;
	newpp->p_ncount = 0;
	newpp->p_nexec = 0;
	newpp->p_ammo = ISHOTS;
# ifdef BOOTS
	newpp->p_nboots = 0;
# endif
	if (enter_status == Q_SCAN) {
		newpp->p_scan = SCANLEN;
		newpp->p_cloak = 0;
	} else {
		newpp->p_scan = 0;
		newpp->p_cloak = CLOAKLEN;
	}
	newpp->p_ncshot = 0;

	do {
		x = rand_num(WIDTH - 1) + 1;
		y = rand_num(HEIGHT - 1) + 1;
	} while (maze[y][x] != SPACE);
	maze[y][x] = GMINE;
# ifdef MONITOR
	for (pp = monitor; pp < end_monitor; pp++) {
		check(pp, y, x);
	}
# endif

	do {
		x = rand_num(WIDTH - 1) + 1;
		y = rand_num(HEIGHT - 1) + 1;
	} while (maze[y][x] != SPACE);
	maze[y][x] = MINE;
# ifdef MONITOR
	for (pp = monitor; pp < end_monitor; pp++) {
		check(pp, y, x);
	}
# endif

	(void) sprintf(gen_buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
			stat_char(newpp), newpp->p_ident->i_name, newpp->p_ident->i_team);
	y = STAT_PLAY_ROW + 1 + (newpp - player);
	for (pp = player; pp < end_player; pp++) {
		if (pp != newpp) {
			char smallbuf[10];

			pp->p_ammo += NSHOTS;
			newpp->p_ammo += NSHOTS;
			cgoto(pp, y, STAT_NAME_COL);
			outstr(pp, gen_buf, STAT_NAME_LEN);
			(void) sprintf(smallbuf, "%3d", pp->p_ammo);
			cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
			outstr(pp, smallbuf, 3);
		}
	}
# ifdef MONITOR
	for (pp = monitor; pp < end_monitor; pp++) {
		cgoto(pp, y, STAT_NAME_COL);
		outstr(pp, gen_buf, STAT_NAME_LEN);
	}
# endif

	drawmaze(newpp);
	drawplayer(newpp, true);
	look(newpp);
# ifdef	FLY
	if (enter_status == Q_FLY) {
		/* Make sure that the position you enter in will be erased */
		showexpl(newpp->p_y, newpp->p_x, FLYER);
	}
# endif
	sendcom(newpp, REFRESH);
	sendcom(newpp, READY, 0);
	(void) fflush(newpp->p_output);
}
Exemplo n.º 10
0
/*
 * remove_wall - add a location where the wall was blown away.
 *		 if there is no space left over, put the a wall at
 *		 the location currently pointed at.
 */
static void
remove_wall(int y, int x)
{
	REGEN	*r;
	PLAYER	*pp;
	char	save_char = 0;

	if (removed == NULL)
		clearwalls();

	r = rem_index;
	while (r->r_y != 0) {
		switch (Maze[r->r_y][r->r_x]) {
		  case SPACE:
		  case LEFTS:
		  case RIGHT:
		  case ABOVE:
		  case BELOW:
		  case FLYER:
			save_char = Maze[r->r_y][r->r_x];
			goto found;
		}
		if (++r >= removed + conf_maxremove)
			r = removed;
	}

found:
	if (r->r_y != 0) {
		/* Slot being used, put back this wall */
		if (save_char == SPACE)
			Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
		else {
			/* We throw the player off the wall: */
			pp = play_at(r->r_y, r->r_x);
			if (pp->p_flying >= 0)
				pp->p_flying += rand_num(conf_flytime / 2);
			else {
				pp->p_flying = rand_num(conf_flytime);
				pp->p_flyx = 2 * rand_num(conf_flystep + 1) -
				    conf_flystep;
				pp->p_flyy = 2 * rand_num(conf_flystep + 1) -
				    conf_flystep;
			}
			pp->p_over = Orig_maze[r->r_y][r->r_x];
			pp->p_face = FLYER;
			Maze[r->r_y][r->r_x] = FLYER;
			showexpl(r->r_y, r->r_x, FLYER);
		}
		Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
		if (conf_random && rand_num(100) < conf_prandom)
			Maze[r->r_y][r->r_x] = DOOR;
		if (conf_reflect && rand_num(100) == conf_preflect)
			Maze[r->r_y][r->r_x] = WALL4;
		for (pp = Monitor; pp < End_monitor; pp++)
			check(pp, r->r_y, r->r_x);
	}

	r->r_y = y;
	r->r_x = x;
	if (++r >= removed + conf_maxremove)
		rem_index = removed;
	else
		rem_index = r;

	Maze[y][x] = SPACE;
	for (pp = Monitor; pp < End_monitor; pp++)
		check(pp, y, x);
}