better managed ownership (two new functions in level.h)

This commit is contained in:
2024-07-16 23:36:31 -04:00
parent 3b164bbe9f
commit 3232d91ac1
14 changed files with 74 additions and 50 deletions

View File

@ -18,8 +18,10 @@ game_status CC3K::run() {
case main_menu: {
auto tmp = curr_menu->run(in);
if (tmp == -2)
if (tmp == -2) {
gresult.status = terminated;
return terminated;
}
if (tmp != -1) {
curr_menu = nullptr;
@ -55,6 +57,8 @@ game_status CC3K::run() {
curr_game->print();
out->render();
return in_game;
} else if (gresult.status == terminated) {
return terminated;
}
out->clear();

View File

@ -29,12 +29,12 @@ void character::set_pos(const position &npos) {
pos = npos;
}
void character::apply_effect(potion *effect) {
insert_effect(effect);
void character::apply_effect(std::unique_ptr<potion> effect) {
insert_effect(std::move(effect));
}
void character::insert_effect(potion *effect) {
effects.push_back(effect);
void character::insert_effect(std::unique_ptr<potion> effect) {
effects.push_back(std::move(effect));
for (int i = effects.size() - 1; i > 0 &&
effect->get_priority() < effects[i - 1]->get_priority(); --i)
@ -42,17 +42,17 @@ void character::insert_effect(potion *effect) {
}
result character::calc_effects() {
potion_list tmp;
potion_own_list tmp;
tmp.reserve(effects.size());
for (auto p : effects) {
p->apply(this->race, HP, ATK, DEF, base_hit_rate);
for (size_t i = 0; i < effects.size(); ++i) {
effects[i]->apply(this->race, HP, ATK, DEF, base_hit_rate);
if (HP <= 0)
return result::died;
if (p->get_duration() != 0)
tmp.push_back(p);
if (effects[i]->get_duration() != 0)
tmp.push_back(std::move(effects[i]));
}
tmp.shrink_to_fit();
@ -63,12 +63,12 @@ result character::calc_effects() {
}
void character::discard_level_effects() {
potion_list tmp;
potion_own_list tmp;
tmp.reserve(effects.size());
for (auto p : effects)
if (p->get_duration() > 0)
tmp.push_back(p);
for (size_t i = 0; i < effects.size(); ++i)
if (effects[i]->get_duration() > 0)
tmp.push_back(std::move(effects[i]));
tmp.shrink_to_fit();

View File

@ -26,7 +26,7 @@ public:
virtual long_result get_hit(character *ch, const int tATK,
const fraction &hit_rate) = 0;
virtual void apply_effect(potion *effect);
virtual void apply_effect(std::unique_ptr<potion> effect);
// override for different types
virtual void print(output *out) = 0;
@ -57,10 +57,10 @@ protected:
int DEF;
fraction base_hit_rate;
potion_list effects;
potion_own_list effects;
private:
void insert_effect(potion *effect);
void insert_effect(std::unique_ptr<potion> effect);
};
int calc_dmg(const int ATK, const int DEF);

View File

@ -19,6 +19,7 @@ cursor::cursor() {
cursor::~cursor() {
endwin();
refresh();
}
int cursor::getcmd() const {

View File

@ -87,14 +87,6 @@ long_result enemy_base::get_hit(character *ch, const int tATK,
}
int enemy_base::dies(level *lvl) {
auto &elist = lvl->get_elist();
for (size_t i = 0; i < elist.size(); ++i)
if (elist[i] == this) {
elist.erase(elist.begin() + i);
break;
}
if (race == race::rdragon) {
return 0;
} else if (race == race::rmerchant) {

View File

@ -75,6 +75,7 @@ character *game::move_enemies() {
if (ch->is_dead()) {
int g = ch->dies(levels[curr_level].get());
levels[curr_level]->erase_enemy(ch);
if (g)
levels[curr_level]->add_gold({g, ch->get_pos()});

View File

@ -237,14 +237,35 @@ position level::get_down_stairs() const {
return map.get_down_stairs();
}
enemy_list &level::get_elist() {
const enemy_list &level::get_elist() {
return elist;
}
potion_list &level::get_plist() {
const potion_list &level::get_plist() {
return plist;
}
gold_list &level::get_glist() {
return glist;
}
std::unique_ptr<potion> level::detach_potion(size_t idx) {
if (idx >= plist.size())
return nullptr;
auto tmp = std::move(pplist[idx]);
plist.erase(plist.begin() + idx);
pplist.erase(pplist.begin() + idx);
return tmp;
}
void level::erase_enemy(character *ch) {
if (ch == nullptr)
return;
for (size_t i = 0; i < elist.size(); ++i)
if (elist[i] == ch) {
elist.erase(elist.begin() + i);
pelist.erase(pelist.begin() + i);
}
}

View File

@ -45,11 +45,14 @@ public:
position get_down_stairs() const;
// you can delete the pointers to the stuff
enemy_list &get_elist();
potion_list &get_plist();
const enemy_list &get_elist();
const potion_list &get_plist();
gold_list &get_glist();
void add_gold(gold g);
void erase_enemy(character *ch);
std::unique_ptr<potion> detach_potion(size_t idx);
private:
// every gen will delete the positions in tiles
void gen_potions(RNG *rng, std::vector<position_list> &tiles);

View File

@ -32,19 +32,21 @@ int player_base::get_HP() const {
return this->HP;
}
long_result player_base::apply(potion *p) {
long_result player_base::apply(std::unique_ptr<potion> p) {
if (p == nullptr)
return {result::applied_nothing,
"PC tried to breathe the magic in the air. "};
apply_effect(p);
std::string name = p->get_name();
apply_effect(std::move(p));
if (race == rt_800)
return {result::applied,
"PC gets rusty joints (-5 HP). "};
"PC gets rusty joints (-50 HP). "};
return {result::applied,
(std::string)"PC applied potion of " + p->get_name() + ". "};
"PC applied potion of " + name + ". "};
}
long_result player_base::attack(character *ch) {
@ -68,6 +70,7 @@ long_result player_base::move(level *lvl,
if (tmp->is_dead()) {
int g = tmp->dies(lvl);
lvl->erase_enemy(tmp);
if (g)
res.msg += "PC gains " +
@ -131,8 +134,9 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
return res;
} else if (cmd >= apply_north && cmd <= apply_southwest) {
auto res = apply(get_potion_at(pos + MOVE[cmd - apply_north],
lvl->get_plist()));
size_t idx = get_potion_at(pos + MOVE[cmd - apply_north],
lvl->get_plist());
auto res = apply(lvl->detach_potion(idx));
return res;
} else if (cmd == apply_panic) {
return {result::fine,
@ -145,6 +149,7 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
if (tmp != nullptr && tmp->is_dead()) {
int g = tmp->dies(lvl);
lvl->erase_enemy(tmp);
if (g)
res.msg += "PC gains " +

View File

@ -8,13 +8,13 @@ enum game_command : int;
class player_base: public character {
protected:
int gold_cnt;
potion_list potions;
potion_own_list potions;
public:
player_base(RNG *rng, const feature enabled_features,
const enum race &nrace);
virtual long_result move(level *lvl, const position &p);
virtual long_result apply(potion *p);
virtual long_result apply(std::unique_ptr<potion> p);
virtual long_result attack(character *ch) override;
virtual long_result get_hit(character *ch, const int tATK,

View File

@ -9,7 +9,7 @@ const char *t_800::get_race_name() const {
return "T-800";
}
void t_800::apply_effect(potion *p) {
void t_800::apply_effect(std::unique_ptr<potion> p) {
HP -= RUSTY;
return;
}

View File

@ -5,11 +5,11 @@
class potion;
class t_800 final: public player_base {
static const int RUSTY = 5;
static const int RUSTY = 50;
public:
t_800(RNG *rng, const feature enabled_features);
const char *get_race_name() const override;
void apply_effect(potion *p) override;
void apply_effect(std::unique_ptr<potion> p) override;
};
#endif

View File

@ -47,15 +47,10 @@ void potion::print(output *out) {
out->print_char(pos, 'P', COLOR_PAIR(COLOR_GREEN));
}
potion *get_potion_at(const position &pos, potion_list &plist) {
potion *ret = nullptr;
size_t get_potion_at(const position &pos, const potion_list &plist) {
for (size_t i = 0; i < plist.size(); ++i)
if (plist[i]->get_pos() == pos) {
ret = plist[i];
plist.erase(plist.begin() + i);
return ret;
}
if (plist[i]->get_pos() == pos)
return i;
return ret;
return plist.size();
}

View File

@ -2,6 +2,7 @@
#define __POTION_H__
#include <vector>
#include <memory>
#include "fraction.h"
#include "output.h"
@ -40,7 +41,8 @@ public:
};
typedef std::vector<potion *> potion_list;
typedef std::vector<std::unique_ptr<potion> > potion_own_list;
potion *get_potion_at(const position &pos, potion_list &plist);
size_t get_potion_at(const position &pos, const potion_list &plist);
#endif