Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
        }
    }
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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);
            }
        }
    }
}