Example #1
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);
}
Example #2
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
}
Example #3
0
/*
 * move_drone:
 *	Move the drone to the next square
 *	Returns FALSE if the drone need no longer be tracked.
 */
static int
move_drone(BULLET *bp)
{
    int	mask, count;
    int	n, dir = -1;
    PLAYER	*pp;

    /* See if we can give someone a blast: */
    if (is_player(Maze[bp->b_y][bp->b_x - 1])) {
        dir = WEST;
        goto drone_move;
    }
    if (is_player(Maze[bp->b_y - 1][bp->b_x])) {
        dir = NORTH;
        goto drone_move;
    }
    if (is_player(Maze[bp->b_y + 1][bp->b_x])) {
        dir = SOUTH;
        goto drone_move;
    }
    if (is_player(Maze[bp->b_y][bp->b_x + 1])) {
        dir = EAST;
        goto drone_move;
    }

    /* Find out what directions are clear and move that way: */
    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 wait: */
    if (count == 0)
        return TRUE;

    /* Only one way to go: */
    if (count == 1) {
        dir = mask;
        goto drone_move;
    }

    /* Avoid backtracking, and remove the direction 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--;

drone_move:
    /* Move the drone: */
    switch (dir) {
    case -1:
    /* no move */
    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;
    }

    /* Look at what the drone moved onto: */
    switch (Maze[bp->b_y][bp->b_x]) {
    case LEFTS:
    case RIGHT:
    case BELOW:
    case ABOVE:
        /*
         * Players have a 1% chance of absorbing a drone,
         * if they are facing it.
         */
        if (rand_num(100) < conf_pdroneabsorb && opposite(bp->b_face,
                Maze[bp->b_y][bp->b_x])) {

            /* Feel the power: */
            pp = play_at(bp->b_y, bp->b_x);
            pp->p_ammo += bp->b_charge;
            message(pp, "**** Absorbed drone ****");

            /* Release drone storage: */
            free(bp);

            /* Update ammo: */
            ammo_update(pp);

            /* No need for caller to keep tracking drone: */
            return FALSE;
        }
        /* Detonate the drone: */
        bp->b_expl = TRUE;
        break;
    }

    /* Keep tracking the drone. */
    return TRUE;
}
Example #4
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;
            }
        }
    }
}
Example #5
0
/*
 * move_normal_shot:
 *	Move a normal shot along its trajectory.
 *	Returns false if the bullet no longer needs tracking.
 */
static int
move_normal_shot(BULLET *bp)
{
    int	i, x, y;
    PLAYER	*pp;

    /*
     * Walk an unexploded bullet along conf_bulspd times, moving it
     * one unit along each step. We flag it as exploding if it
     * meets something.
     */

    for (i = 0; i < conf_bulspd; i++) {

        /* Stop if the bullet has already exploded: */
        if (bp->b_expl)
            break;

        /* Adjust the bullet's co-ordinates: */
        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;
        }


        /* Look at what the bullet is colliding with : */
        switch (Maze[y][x]) {
        /* Gun shots have a chance of collision: */
        case SHOT:
            if (rand_num(100) < conf_pshot_coll) {
                zapshot(Bullets, bp);
                zapshot(bp->b_next, bp);
            }
            break;
        /* Grenades only have a chance of collision: */
        case GRENADE:
            if (rand_num(100) < conf_pgren_coll) {
                zapshot(Bullets, bp);
                zapshot(bp->b_next, bp);
            }
            break;
        /* Reflecting walls richochet the bullet: */
        case WALL4:
            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;
            for (pp = Monitor; pp < End_monitor; pp++)
                check(pp, y, x);
            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;
            for (pp = Monitor; pp < End_monitor; pp++)
                check(pp, y, x);
            break;
        /* Dispersion doors randomly disperse bullets: */
        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;
        /* Bullets zing past fliers: */
        case FLYER:
            pp = play_at(y, x);
            message(pp, "Zing!");
            break;
        /* Bullets encountering a player: */
        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])) {
                /* Give them a 10% chance: */
                if (rand_num(100) < conf_pgren_catch) {
                    /* They caught it! */
                    if (bp->b_owner != NULL)
                        message(bp->b_owner,
                                "Your charge was absorbed!");

                    /*
                     * The target player stole from the bullet's
                     * owner. Charge stolen statistics:
                     */
                    if (bp->b_score != NULL)
                        bp->b_score->i_robbed += bp->b_charge;

                    /* They acquire more ammo: */
                    pp->p_ammo += bp->b_charge;

                    /* Check if it would have destroyed them: */
                    if (pp->p_damage + bp->b_size * conf_mindam
                            > pp->p_damcap)
                        /* Lucky escape statistics: */
                        pp->p_ident->i_saved++;

                    /* Tell them: */
                    message(pp, "Absorbed charge (good shield!)");

                    /* Absorbtion statistics: */
                    pp->p_ident->i_absorbed += bp->b_charge;

                    /* Deallocate storage: */
                    free(bp);

                    /* Update ammo display: */
                    ammo_update(pp);

                    /* No need for caller to keep tracking it: */
                    return FALSE;
                }

                /* Bullets faced head-on (statistics): */
                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. (5% chance)
             */
            if (rand_num(100) < conf_pmiss) {
                /* Ducked statistics: */
                pp->p_ident->i_ducked += bp->b_charge;

                /* Check if it would have killed them: */
                if (pp->p_damage + bp->b_size * conf_mindam
                        > pp->p_damcap)
                    /* Lucky escape statistics: */
                    pp->p_ident->i_saved++;

                /* Shooter missed statistics: */
                if (bp->b_score != NULL)
                    bp->b_score->i_missed += bp->b_charge;

                /* Tell target that they were missed: */
                message(pp, "Zing!");

                /* Tell the bullet owner they missed: */
                if (bp->b_owner != NULL)
                    message(bp->b_owner,
                            ((bp->b_score->i_missed & 0x7) == 0x7) ?
                            "My!  What a bad shot you are!" :
                            "Missed him");

                /* Don't fall through */
                break;
            } else {
                /* The player is to be blown up: */
                bp->b_expl = TRUE;
            }
            break;
        /* Bullet hits a wall, and always explodes: */
        case WALL1:
        case WALL2:
        case WALL3:
            bp->b_expl = TRUE;
            break;
        }

        /* Update the bullet's new position: */
        bp->b_x = x;
        bp->b_y = y;
    }

    /* Caller should keep tracking the bullet: */
    return TRUE;
}
Example #6
0
/*
 * move_player:
 *	Execute a move in the given direction
 */
static void
move_player(PLAYER *pp, int dir)
{
	PLAYER *newp;
	int x, y;
	bool moved;
	BULLET *bp;

	y = pp->p_y;
	x = pp->p_x;

	switch (dir) {
	  case LEFTS:
		x--;
		break;
	  case RIGHT:
		x++;
		break;
	  case ABOVE:
		y--;
		break;
	  case BELOW:
		y++;
		break;
	}

	moved = false;
	switch (Maze[y][x]) {
	  case SPACE:
#ifdef RANDOM
	  case DOOR:
#endif
		moved = true;
		break;
	  case WALL1:
	  case WALL2:
	  case WALL3:
#ifdef REFLECT
	  case WALL4:
	  case WALL5:
#endif
		break;
	  case MINE:
	  case GMINE:
		if (dir == pp->p_face)
			pickup(pp, y, x, 2, Maze[y][x]);
		else if (opposite(dir, pp->p_face))
			pickup(pp, y, x, 95, Maze[y][x]);
		else
			pickup(pp, y, x, 50, Maze[y][x]);
		Maze[y][x] = SPACE;
		moved = true;
		break;
	  case SHOT:
	  case GRENADE:
	  case SATCHEL:
	  case BOMB:
#ifdef OOZE
	  case SLIME:
#endif
#ifdef DRONE
	  case DSHOT:
#endif
		bp = is_bullet(y, x);
		if (bp != NULL)
			bp->b_expl = true;
		Maze[y][x] = SPACE;
		moved = true;
		break;
	  case LEFTS:
	  case RIGHT:
	  case ABOVE:
	  case BELOW:
		if (dir != pp->p_face)
			sendcom(pp, BELL);
		else {
			newp = play_at(y, x);
			checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE);
		}
		break;
#ifdef FLY
	  case FLYER:
		newp = play_at(y, x);
		message(newp, "Oooh, there's a short guy waving at you!");
		message(pp, "You couldn't quite reach him!");
		break;
#endif
#ifdef BOOTS
	  case BOOT:
	  case BOOT_PAIR:
		if (Maze[y][x] == BOOT)
			pp->p_nboots++;
		else
			pp->p_nboots += 2;
		for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
			if (newp->p_flying < 0)
				continue;
			if (newp->p_y == y && newp->p_x == x) {
				newp->p_flying = -1;
				if (newp->p_undershot)
					fixshots(y, x, newp->p_over);
			}
		}
		if (pp->p_nboots == 2)
			message(pp, "Wow!  A pair of boots!");
		else
			message(pp, "You can hobble around on one boot.");
		Maze[y][x] = SPACE;
		moved = true;
		break;
#endif
	}
	if (moved) {
		if (pp->p_ncshot > 0)
			if (--pp->p_ncshot == MAXNCSHOT) {
				cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
				outstr(pp, " ok", 3);
			}
		if (pp->p_undershot) {
			fixshots(pp->p_y, pp->p_x, pp->p_over);
			pp->p_undershot = false;
		}
		drawplayer(pp, false);
		pp->p_over = Maze[y][x];
		pp->p_y = y;
		pp->p_x = x;
		drawplayer(pp, true);
	}
}
Example #7
0
void sound_player::play_at(size_t iIndex, int iX, int iY)
{
    if(sound_effects_enabled)
        play_at(iIndex, sound_effect_volume, iX, iY);
}
Example #8
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);
}
Example #9
0
/*
 * move_player:
 *	Try to move player 'pp' in direction 'dir'.
 */
static void
move_player(PLAYER *pp, int dir)
{
	PLAYER	*newp;
	int	x, y;
	FLAG	moved;
	BULLET	*bp;

	y = pp->p_y;
	x = pp->p_x;

	switch (dir) {
	  case LEFTS:
		x--;
		break;
	  case RIGHT:
		x++;
		break;
	  case ABOVE:
		y--;
		break;
	  case BELOW:
		y++;
		break;
	}

	moved = FALSE;

	/* What would the player move over: */
	switch (Maze[y][x]) {
	  /* Players can move through spaces and doors, no problem: */
	  case SPACE:
	  case DOOR:
		moved = TRUE;
		break;
	  /* Can't move through walls: */
	  case WALL1:
	  case WALL2:
	  case WALL3:
	  case WALL4:
	  case WALL5:
		break;
	  /* Moving over a mine - try to pick it up: */
	  case MINE:
	  case GMINE:
		if (dir == pp->p_face)
			/* facing it: 2% chance of trip */
			pickup(pp, y, x, conf_ptrip_face, Maze[y][x]);
		else if (opposite(dir, pp->p_face))
			/* facing away: 95% chance of trip */
			pickup(pp, y, x, conf_ptrip_back, Maze[y][x]);
		else
			/* facing sideways: 50% chance of trip */
			pickup(pp, y, x, conf_ptrip_side, Maze[y][x]);
		/* Remove the mine: */
		Maze[y][x] = SPACE;
		moved = TRUE;
		break;
	  /* Moving into a bullet: */
	  case SHOT:
	  case GRENADE:
	  case SATCHEL:
	  case BOMB:
	  case SLIME:
	  case DSHOT:
		/* Find which bullet: */
		bp = is_bullet(y, x);
		if (bp != NULL)
			/* Detonate it: */
			bp->b_expl = TRUE;
		/* Remove it: */
		Maze[y][x] = SPACE;
		moved = TRUE;
		break;
	  /* Moving into another player: */
	  case LEFTS:
	  case RIGHT:
	  case ABOVE:
	  case BELOW:
		if (dir != pp->p_face)
			/* Can't walk backwards/sideways into another player: */
			sendcom(pp, BELL);
		else {
			/* Stab the other player */
			newp = play_at(y, x);
			checkdam(newp, pp, pp->p_ident, conf_stabdam, KNIFE);
		}
		break;
	  /* Moving into a player flying overhead: */
	  case FLYER:
		newp = play_at(y, x);
		message(newp, "Oooh, there's a short guy waving at you!");
		message(pp, "You couldn't quite reach him!");
		break;
	  /* Picking up a boot, or two: */
	  case BOOT_PAIR:
		pp->p_nboots++;
	  case BOOT:
		pp->p_nboots++;
		for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
			if (newp->p_flying < 0)
				continue;
			if (newp->p_y == y && newp->p_x == x) {
				newp->p_flying = -1;
				if (newp->p_undershot)
					fixshots(y, x, newp->p_over);
			}
		}
		if (pp->p_nboots == 2)
			message(pp, "Wow!  A pair of boots!");
		else
			message(pp, "You can hobble around on one boot.");
		Maze[y][x] = SPACE;
		moved = TRUE;
		break;
	}

	/* Can the player be moved? */
	if (moved) {
		/* Check the gun status: */
		if (pp->p_ncshot > 0)
			if (--pp->p_ncshot == conf_maxncshot)
				outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " ok");
		/* Check for bullets flying past: */
		if (pp->p_undershot) {
			fixshots(pp->p_y, pp->p_x, pp->p_over);
			pp->p_undershot = FALSE;
		}
		/* Erase the player: */
		drawplayer(pp, FALSE);
		/* Save under: */
		pp->p_over = Maze[y][x];
		/* Move the player: */
		pp->p_y = y;
		pp->p_x = x;
		/* Draw the player in their new position */
		drawplayer(pp, TRUE);
	}
}