diff --git a/src/cc3k.cc b/src/cc3k.cc index 519606a..495dd73 100644 --- a/src/cc3k.cc +++ b/src/cc3k.cc @@ -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(); diff --git a/src/characters.cc b/src/characters.cc index aea13d0..cb1be92 100644 --- a/src/characters.cc +++ b/src/characters.cc @@ -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 effect) { + insert_effect(std::move(effect)); } -void character::insert_effect(potion *effect) { - effects.push_back(effect); +void character::insert_effect(std::unique_ptr 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(); diff --git a/src/characters.h b/src/characters.h index 980c985..8163ea8 100644 --- a/src/characters.h +++ b/src/characters.h @@ -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 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 effect); }; int calc_dmg(const int ATK, const int DEF); diff --git a/src/cursor.cc b/src/cursor.cc index 892a90c..c010ca6 100644 --- a/src/cursor.cc +++ b/src/cursor.cc @@ -19,6 +19,7 @@ cursor::cursor() { cursor::~cursor() { endwin(); + refresh(); } int cursor::getcmd() const { diff --git a/src/enemy.cc b/src/enemy.cc index db4aa83..89e8246 100644 --- a/src/enemy.cc +++ b/src/enemy.cc @@ -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) { diff --git a/src/game.cc b/src/game.cc index bd2297c..f1358a3 100644 --- a/src/game.cc +++ b/src/game.cc @@ -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()}); diff --git a/src/level.cc b/src/level.cc index 0995abd..62b5a1f 100644 --- a/src/level.cc +++ b/src/level.cc @@ -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 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); + } +} diff --git a/src/level.h b/src/level.h index 34f6ca7..2f02e3b 100644 --- a/src/level.h +++ b/src/level.h @@ -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 detach_potion(size_t idx); private: // every gen will delete the positions in tiles void gen_potions(RNG *rng, std::vector &tiles); diff --git a/src/player.cc b/src/player.cc index 677b675..0a83085 100644 --- a/src/player.cc +++ b/src/player.cc @@ -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 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 " + diff --git a/src/player.h b/src/player.h index 0139bc4..bc6e2f8 100644 --- a/src/player.h +++ b/src/player.h @@ -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 p); virtual long_result attack(character *ch) override; virtual long_result get_hit(character *ch, const int tATK, diff --git a/src/player/t_800.cc b/src/player/t_800.cc index b9bddb2..f84380d 100644 --- a/src/player/t_800.cc +++ b/src/player/t_800.cc @@ -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 p) { HP -= RUSTY; return; } diff --git a/src/player/t_800.h b/src/player/t_800.h index 987bbb6..e5c41b5 100644 --- a/src/player/t_800.h +++ b/src/player/t_800.h @@ -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 p) override; }; #endif diff --git a/src/potion.cc b/src/potion.cc index 95751e0..accd252 100644 --- a/src/potion.cc +++ b/src/potion.cc @@ -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(); } diff --git a/src/potion.h b/src/potion.h index 745e889..fd3de67 100644 --- a/src/potion.h +++ b/src/potion.h @@ -2,6 +2,7 @@ #define __POTION_H__ #include +#include #include "fraction.h" #include "output.h" @@ -40,7 +41,8 @@ public: }; typedef std::vector potion_list; +typedef std::vector > 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