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

View File

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

View File

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

View File

@ -19,6 +19,7 @@ cursor::cursor() {
cursor::~cursor() { cursor::~cursor() {
endwin(); endwin();
refresh();
} }
int cursor::getcmd() const { 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) { 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) { if (race == race::rdragon) {
return 0; return 0;
} else if (race == race::rmerchant) { } else if (race == race::rmerchant) {

View File

@ -75,6 +75,7 @@ character *game::move_enemies() {
if (ch->is_dead()) { if (ch->is_dead()) {
int g = ch->dies(levels[curr_level].get()); int g = ch->dies(levels[curr_level].get());
levels[curr_level]->erase_enemy(ch);
if (g) if (g)
levels[curr_level]->add_gold({g, ch->get_pos()}); 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(); return map.get_down_stairs();
} }
enemy_list &level::get_elist() { const enemy_list &level::get_elist() {
return elist; return elist;
} }
potion_list &level::get_plist() { const potion_list &level::get_plist() {
return plist; return plist;
} }
gold_list &level::get_glist() { gold_list &level::get_glist() {
return 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; position get_down_stairs() const;
// you can delete the pointers to the stuff // you can delete the pointers to the stuff
enemy_list &get_elist(); const enemy_list &get_elist();
potion_list &get_plist(); const potion_list &get_plist();
gold_list &get_glist(); gold_list &get_glist();
void add_gold(gold g); void add_gold(gold g);
void erase_enemy(character *ch);
std::unique_ptr<potion> detach_potion(size_t idx);
private: private:
// every gen will delete the positions in tiles // every gen will delete the positions in tiles
void gen_potions(RNG *rng, std::vector<position_list> &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; return this->HP;
} }
long_result player_base::apply(potion *p) { long_result player_base::apply(std::unique_ptr<potion> p) {
if (p == nullptr) if (p == nullptr)
return {result::applied_nothing, return {result::applied_nothing,
"PC tried to breathe the magic in the air. "}; "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) if (race == rt_800)
return {result::applied, return {result::applied,
"PC gets rusty joints (-5 HP). "}; "PC gets rusty joints (-50 HP). "};
return {result::applied, return {result::applied,
(std::string)"PC applied potion of " + p->get_name() + ". "}; "PC applied potion of " + name + ". "};
} }
long_result player_base::attack(character *ch) { long_result player_base::attack(character *ch) {
@ -68,6 +70,7 @@ long_result player_base::move(level *lvl,
if (tmp->is_dead()) { if (tmp->is_dead()) {
int g = tmp->dies(lvl); int g = tmp->dies(lvl);
lvl->erase_enemy(tmp);
if (g) if (g)
res.msg += "PC gains " + res.msg += "PC gains " +
@ -131,8 +134,9 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
return res; return res;
} else if (cmd >= apply_north && cmd <= apply_southwest) { } else if (cmd >= apply_north && cmd <= apply_southwest) {
auto res = apply(get_potion_at(pos + MOVE[cmd - apply_north], size_t idx = get_potion_at(pos + MOVE[cmd - apply_north],
lvl->get_plist())); lvl->get_plist());
auto res = apply(lvl->detach_potion(idx));
return res; return res;
} else if (cmd == apply_panic) { } else if (cmd == apply_panic) {
return {result::fine, return {result::fine,
@ -145,6 +149,7 @@ long_result player_base::interpret_command(level *lvl, game_command cmd) {
if (tmp != nullptr && tmp->is_dead()) { if (tmp != nullptr && tmp->is_dead()) {
int g = tmp->dies(lvl); int g = tmp->dies(lvl);
lvl->erase_enemy(tmp);
if (g) if (g)
res.msg += "PC gains " + res.msg += "PC gains " +

View File

@ -8,13 +8,13 @@ enum game_command : int;
class player_base: public character { class player_base: public character {
protected: protected:
int gold_cnt; int gold_cnt;
potion_list potions; potion_own_list potions;
public: public:
player_base(RNG *rng, const feature enabled_features, player_base(RNG *rng, const feature enabled_features,
const enum race &nrace); const enum race &nrace);
virtual long_result move(level *lvl, const position &p); 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 attack(character *ch) override;
virtual long_result get_hit(character *ch, const int tATK, 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"; return "T-800";
} }
void t_800::apply_effect(potion *p) { void t_800::apply_effect(std::unique_ptr<potion> p) {
HP -= RUSTY; HP -= RUSTY;
return; return;
} }

View File

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

View File

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

View File

@ -2,6 +2,7 @@
#define __POTION_H__ #define __POTION_H__
#include <vector> #include <vector>
#include <memory>
#include "fraction.h" #include "fraction.h"
#include "output.h" #include "output.h"
@ -40,7 +41,8 @@ public:
}; };
typedef std::vector<potion *> potion_list; 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 #endif