Esempio n. 1
0
item_ptr Item::Generate() {
    Die die = {1, ITEM_RANGED + 1, -1};
    uint cat = DieRoll::Roll(die);

    item_ptr item;

    switch(cat) {
        case ITEM_ARMOUR:
            die.Set(1, sizeof(armourTemplates)/sizeof(armourTemplates[0]), -1);
            item = std::make_shared<Armour>(armourTemplates[DieRoll::Roll(die)]);
            break;

        case ITEM_WEAPON:
            die.Set(1, sizeof(weaponTemplates)/sizeof(weaponTemplates[0]), -1);
            item = std::make_shared<Weapon>(weaponTemplates[DieRoll::Roll(die)]);
            break;

        case ITEM_RANGED:
            die.Set(1, sizeof(rangedTemplates)/sizeof(rangedTemplates[0]), -1);
            item = std::make_shared<Ranged>(rangedTemplates[DieRoll::Roll(die)]);
            break;

        default:
            item = std::make_shared<Item>("Nothing", 255, 255, 0);
    }

    return item;
}
Esempio n. 2
0
void Level::Generate() {

    // allocate memory for levels
    Tile** new_map = new Tile* [_h];
    Tile** flooded_map = new Tile* [_h];
    for(uint i = 0; i < _h; i++) {
        new_map[i] = new Tile [_w];
        flooded_map[i] = new Tile [_w];
    }

    while(1) {
        // randomly fill starting level
        for(uint y = 1; y < _h -1; y++) {
            for(uint x = 1; x < _w; x++) {
                _map[y][x] = tiles[randpick()];
            }
        }

        // fill temp level with walls
        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                new_map[y][x] = tiles[MAP_WALL];
            }
        }

        // ensure the level has outer walls
        for(uint y = 0; y < _h; y++) {
            _map[y][0] = _map[y][_w-1] = tiles[MAP_WALL];
        }
        for(uint x = 0; x < _w; x++) {
            _map[0][x] = _map[_h-1][x] = tiles[MAP_WALL];
        }

        // run cellular autonoma algorithm
        for(uint y = 1; y < _h - 1; y++) {
            for(uint x = 1; x < _w - 1; x++) {
                int adjcount_r1 = 0,
                    adjcount_r2 = 0;

                for(int i = -1; i <= 1; i++) {
                    for(int j = -1; j <= 1; j++) {
                        if(_map[y+i][x+j].type != MAP_FLOOR) adjcount_r1++;
                    }
                }

                for(uint i = y - 2; i <= y + 2; i++) {
                    for(uint j = x - 2; j <= x + 2; j++) {
                        if(abs(i-y) == 2 && abs(j-x) == 2) continue;
                        if(i >= _h || j >= _w) continue;
                        if(_map[i][j].type != MAP_FLOOR) adjcount_r2++;
                    }
                }

                // select new tile for this position
                if(adjcount_r1 >= _r1_cutoff || adjcount_r2 <= _r2_cutoff) {
                    new_map[y][x] = tiles[MAP_WALL];
                }
                else {
                    new_map[y][x] = tiles[MAP_FLOOR];
                }
            }
        }

        // flood map from random floor cell
        int rnd_x, rnd_y;
        while(1) {
            rnd_x = rand() % _w;
            rnd_y = rand() % _h;

            if(new_map[rnd_y][rnd_x].type == MAP_FLOOR) break;
        }

        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                flooded_map[y][x] = tiles[MAP_WALL];
            }
        }

        floodmap(new_map, flooded_map, rnd_x, rnd_y);

        // ensure that at least 1/2 of the map is floor
        uint floorcount = 0;
        for(uint y = 0; y < _h; y++) {
            for(uint x = 0; x < _w; x++) {
                if(flooded_map[y][x].type == MAP_FLOOR) floorcount++;
            }
        }

        if(floorcount > (_w*_h)/2) break;
    }

    // place stairs
    int rnd_x, rnd_y;
    while(1) {
        rnd_x = rand() % _w;
        rnd_y = rand() % _h;

        if(flooded_map[rnd_y][rnd_x].type == MAP_FLOOR) {
            flooded_map[rnd_y][rnd_x] = tiles[MAP_STAIR_DOWN];
            _stairDown.x = rnd_x;
            _stairDown.y = rnd_y;
            break;
        }
    }
    while(1) {
        rnd_x = rand() % _w;
        rnd_y = rand() % _h;

        if(flooded_map[rnd_y][rnd_x].type == MAP_FLOOR) {
            flooded_map[rnd_y][rnd_x] = tiles[MAP_STAIR_UP];
            _stairUp.x = rnd_x;
            _stairUp.y = rnd_y;
            break;
        }
    }

    // replace map with new one
    for(uint y = 1; y < _h - 1; y++) {
        for(uint x = 1; x < _w -1; x++) {
            _map[y][x] = flooded_map[y][x];
        }
    }

    // free memory used up by temporary maps
    for(uint i = 0; i < _h; i++) {
        delete [] new_map[i];
        delete [] flooded_map[i];
    }
    delete [] new_map;
    delete [] flooded_map;

    // scatter items around level
    for(uint i = 0; i < LEVEL_HEIGHT / 2; i++) {
        Die tmp = {1, _h-1, 0};
        uint y = DieRoll::Roll(tmp);
        tmp.Set(1, _w-1, 0);
        uint x = DieRoll::Roll(tmp);

        if(_map[y][x].type == MAP_FLOOR) _map[y][x].items.push_back(Item::Generate());
    }
}