work in progress, can be branched/merged

This commit is contained in:
2024-07-13 16:13:20 -04:00
parent ccf6dd0582
commit 5f3565fa86
8 changed files with 289 additions and 0 deletions

34
src/dragon.cc Normal file
View File

@ -0,0 +1,34 @@
#include "dragon.h"
dragon::dragon(RNG *rng, const position &pos):
character{rng, race::rdragon, pos} {
gold = 0;
hostile = true;
}
result dragon::attack(const direction dir, character_list &chlist) {
position tmp{pos + MOVE[dir]};
for (auto &ch : chlist)
if (tmp == ch->get_position()) {
return ch->get_hit(race, ATK, base_hit_rate);
}
return result::fine;
}
result dragon::get_hit(const enum race &race, const int atk,
const fraction hitrate) {
if (rng->trial(hitrate)) // This is a hit!
HP = std::max(HP - calc_dmg(atk, DEF), 0);
if (HP == 0)
return result::died;
return result::hit;
}
result dragon::move(const direction dir,
const position_list &available_positions) {
return result::fine;
}

17
src/dragon.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __DRAGON_H__
#define __DRAGON_H__
#include "characters.h"
class dragon final: public character {
public:
dragon(RNG *rng, const position &pos);
virtual result attack(const direction dir,
character_list &chlist) override;
virtual result get_hit(const enum race &race, const int atk,
const fraction hit_rate) override;
virtual result move(const direction dir,
const position_list &avilable_positions) override;
};
#endif

20
src/enemies.cc Normal file
View File

@ -0,0 +1,20 @@
#include "enemies.h"
// TODO: implement after characters
void new_enemy(RNG *rng, std::unique_ptr<character> &pch, const position &pos,
bool extras) {
if (extras) {
} else {
}
}
void new_dragon(RNG *rng, std::unique_ptr<character> &pch, const position &pos,
const position &fallback) {
const position nil{0, 0};
if (pos != nil)
pch = std::make_unique<dragon>(rng, pos);
else
pch = std::make_unique<dragon>(rng, fallback);
}

14
src/enemies.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __ENEMIES_H__
#define __ENEMIES_H__
#include <memory>
#include "characters.h"
#include "races.h"
void new_enemy(RNG *rng, std::unique_ptr<character> &pch, const position &pos,
bool extras);
void new_dragon(RNG *rng, std::unique_ptr<character> &pch, const position &pos,
const position &fallback);
#endif

18
src/gold.cc Normal file
View File

@ -0,0 +1,18 @@
#include "gold.h"
int rand_gold_pile(RNG *rng) {
const int denominator = 8;
const int normal = 5;
const int dragon = 6;
int tmp = rng->rand_under(denominator);
if (tmp < normal)
return GOLD_NORMAL;
else if (tmp < dragon)
return GOLD_DRAGON;
else
return GOLD_SMALL;
return 0;
}

160
src/level.cc Normal file
View 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;
}

13
src/potions.cc Normal file
View File

@ -0,0 +1,13 @@
#include "potions.h"
void new_potion(std::unique_ptr<potion> &pp, potion_type type,
const position &pos) {
switch (type) {
case potion_type::restore_health:
pp = std::make_unique<class restore_health>(pos);
break;
default:
break;
}
}

13
src/potions.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __POTIONS_H__
#define __POTIONS_H__
#include "potion.h"
#include "restore_health.h"
#include <memory>
#include <utility>
void new_potion(std::unique_ptr<potion> &pp, potion_type type,
const position &pos);
#endif