int exits_north(struct generator *generator, struct box box, struct exit *exits, int exits_count) { assert(1 == box.size.height); int count = 0; struct point end = box_end_point(box); for (int i = 0; i < box.size.width; ++i) { struct point point = point_make(box.origin.x + i, end.y, box.origin.z); struct tile *outside_tile = generator_tile_at(generator, point); struct tile *inside_tile = generator_tile_at(generator, point_south(point)); if ( tile_is_escavated(outside_tile) && tile_is_escavated(inside_tile) && tile_has_south_exit(outside_tile)) { int index = count; ++count; if (exits && index < exits_count) { exits[index].direction = direction_north; exits[index].point = inside_tile->point; exits[index].type = outside_tile->walls.south; } } } return count; }
int exits_east(struct generator *generator, struct box box, struct exit *exits, int exits_count) { assert(1 == box.size.height); int count = 0; struct point end = box_end_point(box); for (int j = 0; j < box.size.length; ++j) { struct point point = point_make(end.x, box.origin.y + j, box.origin.z); struct tile *outside_tile = generator_tile_at(generator, point); struct tile *inside_tile = generator_tile_at(generator, point_west(point)); if ( tile_is_escavated(outside_tile) && tile_is_escavated(inside_tile) && tile_has_west_exit(outside_tile)) { int index = count; ++count; if (exits && index < exits_count) { exits[index].direction = direction_east; exits[index].point = inside_tile->point; exits[index].type = outside_tile->walls.west; } } } return count; }
static bool chimney_up_one_level(struct digger *digger) { struct area *passage = digger_dig_passage(digger, 1, wall_type_none); if (!passage) return false; passage->features |= area_features_chimney_up; digger_move_backward(digger, 1); struct tile *tile = generator_tile_at(digger->generator, digger->point); tile->features |= tile_features_chimney_up; struct digger *upper_digger = generator_copy_digger(digger->generator, digger); digger_move_forward(digger, 1); digger_ascend(upper_digger, 1); if (upper_digger->point.z < generator_min_level(digger->generator)) { generator_delete_digger(upper_digger->generator, upper_digger); return true; } // TODO: random direction? // TODO: random passage/room/chamber? // TODO: add chimney to existing area? passage = digger_dig_passage(upper_digger, 1, wall_type_solid); if (!passage) return false; passage->features |= area_features_chimney_down; digger_move_backward(upper_digger, 1); tile = generator_tile_at(upper_digger->generator, upper_digger->point); tile->features |= tile_features_chimney_down; digger_move_forward(upper_digger, 1); return true; }
static void check_for_chute_down_one_level(struct digger *digger, struct area *area) { if (digger->point.z == generator_max_level(digger->generator)) return; int score = roll("1d6", digger->generator->rnd); if (score == 1) { area->features |= area_features_chute_entrance; struct digger *chute_digger = generator_copy_digger(digger->generator, digger); digger_move_backward(chute_digger, 1); struct tile *tile = generator_tile_at(chute_digger->generator, chute_digger->point); tile->features |= tile_features_chute_entrance; digger_descend(chute_digger, 1); // TODO: random direction? // TODO: random passage/room/chamber? // TODO: add chute to existing area struct area *passage = digger_dig_passage(chute_digger, 1, wall_type_solid); if (passage) { passage->features |= area_features_chute_exit; digger_move_backward(chute_digger, 1); tile = generator_tile_at(chute_digger->generator, chute_digger->point); tile->features |= tile_features_chute_exit; digger_move_forward(chute_digger, 1); } else { generator_delete_digger(chute_digger->generator, chute_digger); } } }
static bool chimney_down_two_levels(struct digger *digger) { if (digger->point.z == generator_max_level(digger->generator)) return false; struct area *passage = digger_dig_passage(digger, 1, wall_type_none); if (!passage) return false; passage->features |= area_features_chimney_down; digger_move_backward(digger, 1); struct tile *tile = generator_tile_at(digger->generator, digger->point); tile->features |= tile_features_chimney_down; struct digger *digger_down_1 = generator_copy_digger(digger->generator, digger); digger_move_forward(digger, 1); digger_descend(digger_down_1, 1); // TODO: random direction? // TODO: random passage/room/chamber? // TODO: add chimney to existing area? passage = digger_dig_passage(digger_down_1, 1, wall_type_solid); if (!passage) return false; passage->features |= area_features_chimney_up; digger_move_backward(digger_down_1, 1); tile = generator_tile_at(digger_down_1->generator, digger_down_1->point); tile->features |= tile_features_chimney_up; if (digger_down_1->point.z == generator_max_level(digger_down_1->generator)) { digger_move_forward(digger_down_1, 1); return true; } passage->features |= area_features_chimney_down; tile->features |= tile_features_chimney_down; struct digger *digger_down_2 = generator_copy_digger(digger_down_1->generator, digger_down_1); digger_move_forward(digger_down_1, 1); digger_descend(digger_down_2, 1); // TODO: random direction? // TODO: random passage/room/chamber? // TODO: add chimney to existing area? passage = digger_dig_passage(digger_down_2, 1, wall_type_solid); if (!passage) return false; passage->features |= area_features_chimney_up; digger_move_backward(digger_down_2, 1); tile = generator_tile_at(digger_down_2->generator, digger_down_2->point); tile->features |= tile_features_chimney_up; digger_move_forward(digger_down_2, 1); return true; }
static void check_wall_for_secret_door(struct generator *generator, struct point point, enum direction direction) { struct tile *inside_tile = generator_tile_at(generator, point); struct tile *outside_tile = generator_tile_at(generator, point_move(point, 1, direction)); switch (direction) { case direction_north: if (wall_type_solid != outside_tile->walls.south) return; break; case direction_south: if (wall_type_solid != inside_tile->walls.south) return; break; case direction_east: if (wall_type_solid != outside_tile->walls.west) return; break; case direction_west: if (wall_type_solid != inside_tile->walls.west) return; break; default: fail("Unrecognized direction %i", direction); break; } int score = roll("1d4", generator->rnd); if (score == 1) { if (tile_type_empty == outside_tile->type) { generator_set_wall(generator, inside_tile->point, direction, wall_type_secret_door); } else { struct digger *door_digger = generator_add_digger(generator, point_move(point, 1, direction), direction); if (!space_beyond_door(door_digger, wall_type_secret_door, false)) { generator_delete_digger(generator, door_digger); } } } }