/* * 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; }
/** * Place some staircases near walls. * \param c the current chunk * \param feat the stair terrain type * \param num number of staircases to place * \param walls number of walls to surround the stairs (negotiable) */ void alloc_stairs(struct chunk *c, int feat, int num, int walls) { int y, x, i, j, done; /* Place "num" stairs */ for (i = 0; i < num; i++) { /* Place some stairs */ for (done = FALSE; !done; ) { /* Try several times, then decrease "walls" */ for (j = 0; !done && j <= 1000; j++) { find_empty(c, &y, &x); if (next_to_walls(c, y, x) < walls) continue; place_stairs(c, y, x, feat); done = TRUE; } /* Require fewer walls */ if (walls) walls--; } } }
/* * Places some staircases near walls */ static bool alloc_stairs(int feat, int num, int walls) { int y, x, i, j, flag; cave_type *c_ptr; if (feat == FEAT_LESS) { /* No up stairs in town or in ironman mode */ if (ironman_downward || !p_ptr->depth) return TRUE; } else if (feat == FEAT_MORE) { /* No downstairs on quest levels */ if ((p_ptr->depth > /*1*/0) && quest_number(p_ptr->depth)) return TRUE; /* No downstairs at the bottom */ if (p_ptr->depth >= MAX_DEPTH - 1) return TRUE; } /* Place "num" stairs */ for (i = 0; i < num; i++) { /* Place some stairs */ for (flag = FALSE; !flag; ) { /* Try several times, then decrease "walls" */ for (j = 0; !flag && j <= 10000; j++) { /* Pick a random grid */ y = rand_range(min_hgt + 1, max_hgt - 2); x = rand_range(min_wid + 1, max_wid - 2); /* Access the grid */ c_ptr = &cave[y][x]; /* Require "naked" floor grid */ if (!cave_naked_grid(c_ptr)) continue; /* Require floor */ if (c_ptr->feat != FEAT_FLOOR) continue; /* Require a certain number of adjacent walls */ if (next_to_walls(y, x) < walls) continue; /* Clear previous contents, add stairs */ c_ptr->feat = feat; /* All done */ flag = TRUE; } /* If cannot find a blank spot - exit */ if (!walls) { /* Placed at least one. */ if (i > 0) return TRUE; /* Couldn't place any stairs */ return FALSE; } /* Require fewer walls */ walls--; } } /* Done */ return TRUE; }
/** * Returns co-ordinates for the player. Player prefers to be near * walls, because large open spaces are dangerous. */ void new_player_spot(void) { int i = 0; int y, x; feature_type *f_ptr; /* * Check stored stair locations, then search at random. */ while (TRUE) { i++; /* Scan stored locations first. */ if (i < dun->stair_n) { /* Get location */ y = dun->stair[i].y; x = dun->stair[i].x; /* Require exactly three adjacent walls */ if (next_to_walls(y, x) != 3) continue; /* If character starts on stairs, ... */ if (!OPT(adult_no_stairs) || !p_ptr->depth) { /* Accept stairs going the right way or floors. */ if (p_ptr->create_stair) { /* Accept correct stairs */ if (cave_feat[y][x] == p_ptr->create_stair) break; /* Accept floors, build correct stairs. */ f_ptr = &f_info[cave_feat[y][x]]; if (cave_naked_bold(y, x) && tf_has(f_ptr->flags, TF_FLOOR)) { cave_set_feat(y, x, p_ptr->create_stair); break; } } } /* If character doesn't start on stairs, ... */ else { /* Accept only "naked" floor grids */ f_ptr = &f_info[cave_feat[y][x]]; if (cave_naked_bold(y, x) && tf_has(f_ptr->flags, TF_FLOOR)) break; } } /* Then, search at random */ else { /* Pick a random grid */ y = randint0(DUNGEON_HGT); x = randint0(DUNGEON_WID); /* Refuse to start on anti-teleport (vault) grids */ if (cave_has(cave_info[y][x], CAVE_ICKY)) continue; /* Must be a "naked" floor grid */ f_ptr = &f_info[cave_feat[y][x]]; if (!(cave_naked_bold(y, x) && tf_has(f_ptr->flags, TF_FLOOR))) continue; /* Player prefers to be near walls. */ if (i < 300 && (next_to_walls(y, x) < 2)) continue; else if (i < 600 && (next_to_walls(y, x) < 1)) continue; /* Success */ break; } } /* Place the player */ player_place(y, x); }
/** * Places some staircases near walls */ void alloc_stairs(int feat, int num, int walls) { int y, x, i, j; feature_type *f_ptr; bool no_down_shaft = (!stage_map[stage_map[p_ptr->stage][DOWN]][DOWN] || is_quest(stage_map[p_ptr->stage][DOWN]) || is_quest(p_ptr->stage)); bool no_up_shaft = (!stage_map[stage_map[p_ptr->stage][UP]][UP]); bool morgy = is_quest(p_ptr->stage) && stage_map[p_ptr->stage][DEPTH] == 100; /* Place "num" stairs */ for (i = 0; i < num; i++) { /* Try hard to place the stair */ for (j = 0; j < 3000; j++) { /* Cut some slack if necessary. */ if ((j > dun->stair_n) && (walls > 2)) walls = 2; if ((j > 1000) && (walls > 1)) walls = 1; if (j > 2000) walls = 0; /* Use the stored stair locations first. */ if (j < dun->stair_n) { y = dun->stair[j].y; x = dun->stair[j].x; } /* Then, search at random. */ else { /* Pick a random grid */ y = randint0(DUNGEON_HGT); x = randint0(DUNGEON_WID); } /* Require "naked" floor grid */ f_ptr = &f_info[cave_feat[y][x]]; if (!(cave_naked_bold(y, x) && tf_has(f_ptr->flags, TF_FLOOR))) continue; /* Require a certain number of adjacent walls */ if (next_to_walls(y, x) < walls) continue; /* If we've asked for a shaft and they're forbidden, fail */ if (no_down_shaft && (feat == FEAT_MORE_SHAFT)) return; if (no_up_shaft && (feat == FEAT_LESS_SHAFT)) return; /* Town or no way up -- must go down */ if ((!p_ptr->depth) || (!stage_map[p_ptr->stage][UP])) { /* Clear previous contents, add down stairs */ if (feat != FEAT_MORE_SHAFT) cave_set_feat(y, x, FEAT_MORE); } /* Bottom of dungeon, Morgoth or underworld -- must go up */ else if ((!stage_map[p_ptr->stage][DOWN]) || underworld || morgy) { /* Clear previous contents, add up stairs */ if (feat != FEAT_LESS_SHAFT) cave_set_feat(y, x, FEAT_LESS); } /* Requested type */ else { /* Clear previous contents, add stairs */ cave_set_feat(y, x, feat); } /* Finished with this staircase. */ break; } } }