work in progress, can be branched/merged
This commit is contained in:
160
src/level.cc
Normal file
160
src/level.cc
Normal file
@ -0,0 +1,160 @@
|
||||
#include "level.h"
|
||||
|
||||
level::level(character *player, RNG *rng, const feature enabled_features):
|
||||
enabled_features{enabled_features}, map{player, rng, enabled_features},
|
||||
player{player} {
|
||||
auto tiles = map.get_room_list();
|
||||
gen_potions(rng, tiles);
|
||||
gen_gold(rng, tiles);
|
||||
gen_enemies(rng, tiles);
|
||||
}
|
||||
|
||||
level::level(const std::string &map_data, character *player, RNG *rng,
|
||||
const feature enabled_features):
|
||||
enabled_features{enabled_features},
|
||||
map{player, map_data, rng, enabled_features}, player{player} {
|
||||
auto tiles = map.get_room_list();
|
||||
gen_potions(rng, tiles);
|
||||
gen_gold(rng, tiles);
|
||||
gen_enemies(rng, tiles);
|
||||
}
|
||||
|
||||
gold_list level::dragon_hoard() {
|
||||
gold_list result;
|
||||
|
||||
for (auto g : glist)
|
||||
if (g.amount == GOLD_DRAGON)
|
||||
result.push_back({g.amount, g.pos});
|
||||
return result;
|
||||
}
|
||||
|
||||
void level::gen_enemies(RNG *rng, std::vector<position_list> &tiles) {
|
||||
auto dhoard = dragon_hoard();
|
||||
int cnt = enabled_features & FEATURE_EXTRA_STUFF ?
|
||||
rng->rand_between(MIN_ENEMIE_CNT, MAX_ENEMIE_CNT + 1) :
|
||||
MIN_ENEMIE_CNT + dhoard.size();
|
||||
|
||||
chlist.reserve(cnt);
|
||||
pchlist.reserve(cnt);
|
||||
|
||||
for (size_t i = 0; i < dhoard.size(); ++i) {
|
||||
auto spots = get_available_around(dhoard[i].pos);
|
||||
pchlist.push_back(nullptr);
|
||||
new_dragon(rng, pchlist[i], rng->get_rand_in_vector(spots),
|
||||
dhoard[i].pos);
|
||||
chlist.push_back(pchlist[i].get());
|
||||
}
|
||||
|
||||
|
||||
for (int i = dhoard.size(); i < cnt; ++i) {
|
||||
pchlist.push_back(nullptr);
|
||||
new_enemy(rng, pchlist[i], get_rand_pos(rng, tiles),
|
||||
enabled_features & FEATURE_EXTRA_STUFF);
|
||||
pchlist[i]->set_room_num(map.which_room(pchlist[i]->get_position()));
|
||||
chlist.push_back(pchlist[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
position level::get_rand_pos(RNG *rng, std::vector<position_list> &tiles) {
|
||||
int room;
|
||||
position pos;
|
||||
room = rng->rand_under(tiles.size());
|
||||
|
||||
pos = rng->get_rand_in_vector(tiles[room]);
|
||||
remove_from_list(tiles[room], pos);
|
||||
|
||||
if (!tiles[room].size())
|
||||
tiles.erase(tiles.begin() + room);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void level::gen_gold(RNG *rng, std::vector<position_list> &tiles) {
|
||||
glist.reserve(GOLD_CNT);
|
||||
|
||||
for (int i = 0; i < GOLD_CNT; ++i)
|
||||
glist.push_back({rand_gold_pile(rng), get_rand_pos(rng, tiles)});
|
||||
}
|
||||
|
||||
void level::gen_potions(RNG *rng, std::vector<position_list> &tiles) {
|
||||
int cnt;
|
||||
int max_type;
|
||||
|
||||
if (enabled_features & FEATURE_EXTRA_STUFF) {
|
||||
cnt = rng->rand_between(MIN_POTION_CNT, MAX_POTION_CNT + 1);
|
||||
max_type = POTION_TYPE_CNT;
|
||||
} else {
|
||||
cnt = MIN_POTION_CNT;
|
||||
max_type = DEFAULT_POTION_TYPE_CNT;
|
||||
}
|
||||
|
||||
plist.reserve(cnt);
|
||||
pplist.reserve(cnt);
|
||||
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
pplist.push_back(nullptr);
|
||||
new_potion(pplist[i],
|
||||
(potion_type)rng->rand_under(max_type),
|
||||
get_rand_pos(rng, tiles));
|
||||
plist.push_back(pplist[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
void level::print(display *out) const {
|
||||
map.print(out);
|
||||
player->print(out, true);
|
||||
|
||||
for (auto ch : chlist)
|
||||
ch->print(out);
|
||||
|
||||
for (auto p : plist)
|
||||
p->print(out);
|
||||
|
||||
for (auto gold : glist)
|
||||
out->print_char(gold.pos, 'G', COLOR_PAIR(COLOR_YELLOW));
|
||||
}
|
||||
|
||||
bool level::is_available(const position &pos) const {
|
||||
if (!map.is_available(pos))
|
||||
return false;
|
||||
|
||||
for (auto ch : chlist)
|
||||
if (pos == ch->get_position())
|
||||
return false;
|
||||
|
||||
for (auto p : plist)
|
||||
if (pos == p->get_pos())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
position_list level::get_available_around(const position &pos) const {
|
||||
position_list result;
|
||||
|
||||
for (int i = 0; i < DIRECTION_CNT; ++i)
|
||||
if (is_available(pos + MOVE[i]))
|
||||
result.push_back(pos + MOVE[i]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
position level::get_up_stairs() const {
|
||||
return map.get_up_stairs();
|
||||
}
|
||||
|
||||
position level::get_down_stairs() const {
|
||||
return map.get_down_stairs();
|
||||
}
|
||||
|
||||
character_list &level::get_chlist() {
|
||||
return chlist;
|
||||
}
|
||||
|
||||
potion_list &level::get_plist() {
|
||||
return plist;
|
||||
}
|
||||
|
||||
gold_list &level::get_glist() {
|
||||
return glist;
|
||||
}
|
Reference in New Issue
Block a user