/** * Add visible treasure to a mineral square. */ void square_upgrade_mineral(struct chunk *c, int y, int x) { if (c->squares[y][x].feat == FEAT_MAGMA) square_set_feat(c, y, x, FEAT_MAGMA_K); if (c->squares[y][x].feat == FEAT_QUARTZ) square_set_feat(c, y, x, FEAT_QUARTZ_K); }
/** * Place stairs (of the requested type 'feat' if allowed) at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates * \param feat stair terrain type * * All stairs from town go down. All stairs on an unfinished quest level go up. */ static void place_stairs(struct chunk *c, int y, int x, int feat) { if (!c->depth) square_set_feat(c, y, x, FEAT_MORE); else if (is_quest(c->depth) || c->depth >= z_info->max_depth - 1) square_set_feat(c, y, x, FEAT_LESS); else square_set_feat(c, y, x, feat); }
/** * Place a random door at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates * * The door generated could be closed, open, broken, or secret. */ void place_random_door(struct chunk *c, int y, int x) { int tmp = randint0(100); if (tmp < 30) square_set_feat(c, y, x, FEAT_OPEN); else if (tmp < 40) square_set_feat(c, y, x, FEAT_BROKEN); else place_closed_door(c, y, x); }
/** * Creates magical stairs after finishing a quest monster. */ static void build_quest_stairs(int y, int x) { int ny, nx; /* Stagger around */ while (!square_changeable(cave, y, x) && !square_iswall(cave, y, x) && !square_isdoor(cave, y, x)) { /* Pick a location */ scatter(cave, &ny, &nx, y, x, 1, FALSE); /* Stagger */ y = ny; x = nx; } /* Push any objects */ push_object(y, x); /* Explain the staircase */ msg("A magical staircase appears..."); /* Create stairs down */ square_set_feat(cave, y, x, FEAT_MORE); /* Update the visuals */ player->upkeep->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Fully update the flow */ player->upkeep->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); }
void square_add_stairs(struct chunk *c, int y, int x, int depth) { int down = randint0(100) < 50; if (depth == 0) down = 1; else if (is_quest(depth) || depth >= z_info->max_depth - 1) down = 0; square_set_feat(c, y, x, down ? FEAT_MORE : FEAT_LESS); }
void square_earthquake(struct chunk *c, int y, int x) { int t = randint0(100); int f; if (!square_ispassable(c, y, x)) { square_set_feat(c, y, x, FEAT_FLOOR); return; } if (t < 20) f = FEAT_GRANITE; else if (t < 70) f = FEAT_QUARTZ; else f = FEAT_MAGMA; square_set_feat(c, y, x, f); }
/** * Place the player at a random starting location. * \param c current chunk * \param p the player */ void new_player_spot(struct chunk *c, struct player *p) { int y, x; /* Try to find a good place to put the player */ cave_find_in_range(c, &y, 0, c->height, &x, 0, c->width, square_isstart); /* Create stairs the player came down if allowed and necessary */ if (OPT(birth_no_stairs)) ; else if (p->upkeep->create_down_stair) square_set_feat(c, y, x, FEAT_MORE); else if (p->upkeep->create_up_stair) square_set_feat(c, y, x, FEAT_LESS); player_place(c, p, y, x); }
void square_destroy(struct chunk *c, int y, int x) { int feat = FEAT_FLOOR; int r = randint0(200); if (r < 20) feat = FEAT_GRANITE; else if (r < 70) feat = FEAT_QUARTZ; else if (r < 100) feat = FEAT_MAGMA; square_set_feat(c, y, x, feat); }
/** * This will push objects off a square. * * The methodology is to load all objects on the square into a queue. Replace * the previous square with a type that does not allow for objects. Drop the * objects. Last, put the square back to its original type. */ void push_object(int y, int x) { /* Save the original terrain feature */ struct feature *feat_old = square_feat(cave, y, x); struct object *obj = square_object(cave, y, x); struct queue *queue = q_new(z_info->floor_size); bool glyph = square_iswarded(cave, y, x); /* Push all objects on the square, stripped of pile info, into the queue */ while (obj) { struct object *next = obj->next; q_push_ptr(queue, obj); /* Orphan the object */ obj->next = NULL; obj->prev = NULL; obj->iy = 0; obj->ix = 0; /* Next object */ obj = next; } /* Disassociate the objects from the square */ cave->squares[y][x].obj = NULL; /* Set feature to an open door */ square_force_floor(cave, y, x); square_add_door(cave, y, x, false); /* Drop objects back onto the floor */ while (q_len(queue) > 0) { /* Take object from the queue */ obj = q_pop_ptr(queue); /* Drop the object */ drop_near(cave, &obj, 0, y, x, false); } /* Reset cave feature and rune if needed */ square_set_feat(cave, y, x, feat_old->fidx); if (glyph) square_add_ward(cave, y, x); q_free(queue); }
/** * Place the player at a random starting location. * \param c current chunk * \param p the player */ void new_player_spot(struct chunk *c, struct player *p) { int y, x; /* Try to find a good place to put the player */ if (OPT(p, birth_levels_persist) && square_in_bounds_fully(c, p->py, p->px) && square_isstairs(c, p->py, p->px)) { y = p->py; x = p->px; } else if (!find_start(c, &y, &x)) { quit("Failed to place player!"); } /* Create stairs the player came down if allowed and necessary */ if (!OPT(p, birth_connect_stairs)) ; else if (p->upkeep->create_down_stair) square_set_feat(c, y, x, FEAT_MORE); else if (p->upkeep->create_up_stair) square_set_feat(c, y, x, FEAT_LESS); player_place(c, p, y, x); }
/** * Place rubble at (x, y). * \param c current chunk * \param y * \param x co-ordinates */ static void place_rubble(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_RUBBLE); }
void square_destroy_wall(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_FLOOR); }
/** * Place rubble at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates */ static void place_rubble(struct chunk *c, int y, int x) { square_set_feat(c, y, x, one_in_(2) ? FEAT_RUBBLE : FEAT_PASS_RUBBLE); }
void square_smash_door(struct chunk *c, int y, int x) { square_remove_trap(c, y, x, FALSE, -1); square_set_feat(c, y, x, FEAT_BROKEN); }
void square_destroy_door(struct chunk *c, int y, int x) { assert(square_isdoor(c, y, x)); square_remove_trap(c, y, x, FALSE, -1); square_set_feat(c, y, x, FEAT_FLOOR); }
void square_close_door(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_CLOSED); }
void square_open_door(struct chunk *c, int y, int x) { square_remove_trap(c, y, x, FALSE, -1); square_set_feat(c, y, x, FEAT_OPEN); }
/** * Place a secret door at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates */ void place_secret_door(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_SECRET); }
void square_destroy_rubble(struct chunk *c, int y, int x) { assert(square_isrubble(c, y, x)); square_set_feat(c, y, x, FEAT_FLOOR); }
/** * Place a closed door at (x, y). * \param c current chunk * \param y co-ordinates * \param x co-ordinates */ void place_closed_door(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_CLOSED); if (one_in_(4)) square_set_door_lock(c, y, x, randint1(7)); }
void square_force_floor(struct chunk *c, int y, int x) { square_set_feat(c, y, x, FEAT_FLOOR); }
void square_add_door(struct chunk *c, int y, int x, bool closed) { square_set_feat(c, y, x, closed ? FEAT_CLOSED : FEAT_OPEN); }