/*
 * Count the number of "corridor" grids adjacent to the given grid.
 *
 * Note -- Assumes "in_bounds(y1, x1)"
 *
 * XXX XXX This routine currently only counts actual "empty floor"
 * grids which are not in rooms. We might want to also count stairs,
 * open doors, closed doors, etc.
 */
static int next_to_corr(int y1, int x1)
{
    int i, y, x, k = 0;

    cave_type *c_ptr;

    /* Scan adjacent grids */
    for (i = 0; i < 4; i++)
    {
        /* Extract the location */
        y = y1 + ddy_ddd[i];
        x = x1 + ddx_ddd[i];

        /* Access the grid */
        c_ptr = &cave[y][x];

        /* Skip non floors */
        if (cave_have_flag_grid(c_ptr, FF_WALL)) continue;

        /* Skip non "empty floor" grids */
        if (!is_floor_grid(c_ptr))
            continue;

        /* Skip grids inside rooms */
        if (c_ptr->info & (CAVE_ROOM)) continue;

        /* Count these grids */
        k++;
    }

    /* Return the number of corridors */
    return (k);
}
static bool _get_loc(int set, int* x, int *y)
{
    int dummy = 0;
    while (dummy < SAFE_MAX_ATTEMPTS)
    {
        bool       room;
        cave_type *c_ptr;

        dummy++;

        *x = randint0(cur_wid);
        *y = randint0(cur_hgt);

        c_ptr = &cave[*y][*x];

        if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;
        if (player_bold(*y, *x)) continue;

        room = (cave[*y][*x].info & CAVE_ROOM) ? TRUE : FALSE;
        if (set == ALLOC_SET_CORR && room) continue;
        if (set == ALLOC_SET_ROOM && !room) continue;

        return TRUE;
    }
    return FALSE;
}
Beispiel #3
0
/*
 * Create up to "num" objects near the given coordinates
 * Only really called by some of the "vault" routines.
 */
void vault_objects(int y, int x, int num)
{
    int dummy = 0;
    int i = 0, j = y, k = x;

    cave_type *c_ptr;


    /* Attempt to place 'num' objects */
    for (; num > 0; --num)
    {
        /* Try up to 11 spots looking for empty space */
        for (i = 0; i < 11; ++i)
        {
            /* Pick a random location */
            while (dummy < SAFE_MAX_ATTEMPTS)
            {
                j = rand_spread(y, 2);
                k = rand_spread(x, 3);
                dummy++;
                if (!in_bounds(j, k)) continue;
                break;
            }


            if (dummy >= SAFE_MAX_ATTEMPTS)
            {
                if (cheat_room)
                {
                    msg_print("Warning! Could not place vault object!");

                }
            }


            /* Require "clean" floor space */
            c_ptr = &cave[j][k];
            if (!is_floor_grid(c_ptr) || c_ptr->o_idx) continue;

            /* Place an item */
            if (randint0(100) < 75)
            {
                place_object(j, k, 0L);
            }

            /* Place gold */
            else
            {
                place_gold(j, k);
            }

            /* Placement accomplished */
            break;
        }
    }
}
/*
 *  Helper function for alloc_stairs().
 *
 *  Is this a good location for stairs?
 */
static bool alloc_stairs_aux(int y, int x, int walls)
{
    /* Access the grid */
    cave_type *c_ptr = &cave[y][x];

    /* Require "naked" floor grid */
    if (!is_floor_grid(c_ptr)) return FALSE;
    if (pattern_tile(y, x)) return FALSE;
    if (c_ptr->o_idx || c_ptr->m_idx) return FALSE;

    /* Require a certain number of adjacent walls */
    if (next_to_walls(y, x) < walls) return FALSE;

    return TRUE;
}
Beispiel #5
0
/*
 * Place an up/down staircase at given location
 */
void place_random_stairs(int y, int x)
{
    bool up_stairs = TRUE;
    bool down_stairs = TRUE;
    cave_type *c_ptr;

    /* Paranoia */
    c_ptr = &cave[y][x];
    if (!is_floor_grid(c_ptr) || c_ptr->o_idx) return;

    /* Town */
    if (!dun_level)
        up_stairs = FALSE;

    /* Ironman */
    if (ironman_downward)
        up_stairs = FALSE;

    /* Bottom */
    if (dun_level >= d_info[dungeon_type].maxdepth)
        down_stairs = FALSE;

    /* Quest-level */
    if (quest_number(dun_level) && (dun_level > 1))
        down_stairs = FALSE;

    /* We can't place both */
    if (down_stairs && up_stairs)
    {
        /* Choose a staircase randomly */
        if (randint0(100) < 50)
            up_stairs = FALSE;
        else
            down_stairs = FALSE;
    }

    /* Place the stairs */
    if (up_stairs)
        place_up_stairs(y, x);
    else if (down_stairs)
        place_down_stairs(y, x);
}
Beispiel #6
0
/*
 * Place a trap with a given displacement of point
 */
void vault_trap_aux(int y, int x, int yd, int xd)
{
    int count = 0, y1 = y, x1 = x;
    int dummy = 0;

    cave_type *c_ptr;

    /* Place traps */
    for (count = 0; count <= 5; count++)
    {
        /* Get a location */
        while (dummy < SAFE_MAX_ATTEMPTS)
        {
            y1 = rand_spread(y, yd);
            x1 = rand_spread(x, xd);
            dummy++;
            if (!in_bounds(y1, x1)) continue;
            break;
        }

        if (dummy >= SAFE_MAX_ATTEMPTS)
        {
            if (cheat_room)
            {
                msg_print("Warning! Could not place vault trap!");

            }
        }

        /* Require "naked" floor grids */
        c_ptr = &cave[y1][x1];
        if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;

        /* Place the trap */
        place_trap(y1, x1);

        /* Done */
        break;
    }
}
Beispiel #7
0
/*
 * This routine maps a path from (x1, y1) to (x2, y2) avoiding SOLID walls.
 * Permanent rock is ignored in this path finding- sometimes there is no
 * path around anyway -so there will be a crash if we try to find one.
 * This routine is much like the river creation routine in Zangband.
 * It works by dividing a line segment into two.  The segments are divided
 * until they are less than "cutoff" - when the corresponding routine from
 * "short_seg_hack" is called.
 * Note it is VERY important that the "stop if hit another passage" logic
 * stays as is.  Without this the dungeon turns into Swiss Cheese...
 */
bool build_tunnel2(int x1, int y1, int x2, int y2, int type, int cutoff)
{
    int x3, y3, dx, dy;
    int changex, changey;
    int length;
    int i;
    bool retval, firstsuccede;
    cave_type *c_ptr;

    length = distance(x1, y1, x2, y2);

    if (length > cutoff)
    {
        /*
        * Divide path in half and call routine twice.
         */
        dx = (x2 - x1) / 2;
        dy = (y2 - y1) / 2;

        /* perturbation perpendicular to path */
        changex = (randint0(abs(dy) + 2) * 2 - abs(dy) - 1) / 2;

        /* perturbation perpendicular to path */
        changey = (randint0(abs(dx) + 2) * 2 - abs(dx) - 1) / 2;

        /* Work out "mid" ponit */
        x3 = x1 + dx + changex;
        y3 = y1 + dy + changey;

        /* See if in bounds - if not - do not perturb point */
        if (!in_bounds(y3, x3))
        {
            x3 = (x1 + x2) / 2;
            y3 = (y1 + y2) / 2;
        }
        /* cache c_ptr */
        c_ptr = &cave[y3][x3];
        if (is_solid_grid(c_ptr))
        {
            /* move midpoint a bit to avoid problem. */

            i = 50;

            dy = 0;
            dx = 0;
            while ((i > 0) && is_solid_bold(y3 + dy, x3 + dx))
            {
                dy = randint0(3) - 1;
                dx = randint0(3) - 1;
                if (!in_bounds(y3 + dy, x3 + dx))
                {
                    dx = 0;
                    dy = 0;
                }
                i--;
            }

            if (i == 0)
            {
                /* Failed for some reason: hack - ignore the solidness */
                place_outer_bold(y3, x3);
                dx = 0;
                dy = 0;
            }
            y3 += dy;
            x3 += dx;
            c_ptr = &cave[y3][x3];
        }

        if (is_floor_grid(c_ptr))
        {
            if (build_tunnel2(x1, y1, x3, y3, type, cutoff))
            {
                if ((cave[y3][x3].info & CAVE_ROOM) || (randint1(100) > 95))
                {
                    /* do second half only if works + if have hit a room */
                    retval = build_tunnel2(x3, y3, x2, y2, type, cutoff);
                }
                else
                {
                    /* have hit another tunnel - make a set of doors here */
                    retval = FALSE;

                    /* Save the door location */
                    if (dun->door_n < DOOR_MAX)
                    {
                        dun->door[dun->door_n].y = y3;
                        dun->door[dun->door_n].x = x3;
                        dun->door_n++;
                    }
                    else return FALSE;
                }
                firstsuccede = TRUE;
            }
            else
            {
                /* false- didn't work all the way */
                retval = FALSE;
                firstsuccede = FALSE;
            }
        }
        else
        {
            /* tunnel through walls */
            if (build_tunnel2(x1, y1, x3, y3, type, cutoff))
            {
                retval = build_tunnel2(x3, y3, x2, y2, type, cutoff);
                firstsuccede = TRUE;
            }
            else
            {
                /* false- didn't work all the way */
                retval = FALSE;
                firstsuccede = FALSE;
            }
        }
        if (firstsuccede)
        {
            /* only do this if the first half has worked */
            set_tunnel(&x3, &y3, TRUE);
        }
        /* return value calculated above */
        return retval;
    }
    else
    {
        /* Do a short segment */
        retval = TRUE;
        short_seg_hack(x1, y1, x2, y2, type, 0, &retval);

        /* Hack - ignore return value so avoid infinite loops */
        return TRUE;
    }
}
Beispiel #8
0
/*
 * Allocates some objects (using "place" and "type")
 */
static void alloc_object(int set, int typ, int num)
{
	int y = 0, x = 0, k;
	int dummy = 0;
	cave_type *c_ptr;

	/* A small level has few objects. */
	num = num * cur_hgt * cur_wid / (MAX_HGT*MAX_WID) +1;

	/* Place some objects */
	for (k = 0; k < num; k++)
	{
		/* Pick a "legal" spot */
		while (dummy < SAFE_MAX_ATTEMPTS)
		{
			bool room;

			dummy++;

			/* Location */
			y = randint0(cur_hgt);
			x = randint0(cur_wid);

			c_ptr = &cave[y][x];

			/* Require "naked" floor grid */
			if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue;

			/* Avoid player location */
			if (player_bold(y, x)) continue;

			/* Check for "room" */
			room = (cave[y][x].info & CAVE_ROOM) ? TRUE : FALSE;

			/* Require corridor? */
			if ((set == ALLOC_SET_CORR) && room) continue;

			/* Require room? */
			if ((set == ALLOC_SET_ROOM) && !room) continue;

			/* Accept it */
			break;
		}

		if (dummy >= SAFE_MAX_ATTEMPTS)
		{
			if (cheat_room)
			{
#ifdef JP
msg_print("警告!アイテムを配置できません!");
#else
				msg_print("Warning! Could not place object!");
#endif

			}
			return;
		}


		/* Place something */
		switch (typ)
		{
			case ALLOC_TYP_RUBBLE:
			{
				place_rubble(y, x);
				cave[y][x].info &= ~(CAVE_FLOOR);
				break;
			}

			case ALLOC_TYP_TRAP:
			{
				place_trap(y, x);
				cave[y][x].info &= ~(CAVE_FLOOR);
				break;
			}

			case ALLOC_TYP_GOLD:
			{
				place_gold(y, x);
				break;
			}

			case ALLOC_TYP_OBJECT:
			{
				place_object(y, x, 0L);
				break;
			}
		}
	}
}