From 9fdbf141d3dc96884d8ed1b25b23fbd239c7c46b Mon Sep 17 00:00:00 2001 From: Peisong Xiao Date: Sat, 13 Jul 2024 14:02:30 -0400 Subject: [PATCH] TODO: modify other races constructors did some reworking --- src/arguments.cc | 3 ++ src/characters.cc | 20 ++++++++-- src/characters.h | 15 +++++-- src/constants.h | 22 +++++++---- src/goblin.cc | 9 ++--- src/goblin.h | 6 +-- src/gold.h | 19 +++++++++ src/level.h | 42 ++++++++++++++++---- src/map.cc | 91 +++++++++++++++++++++++-------------------- src/map.cc.bak | 68 -------------------------------- src/map.h | 11 ++++-- src/position.cc | 20 ++++------ src/position.h | 5 +-- src/potion.cc | 4 ++ src/potion.h | 3 ++ src/races.h | 1 + src/restore_health.cc | 4 +- src/restore_health.h | 2 +- src/rng.cc | 33 ++++++++++++++-- src/rng.h | 11 +++--- src/shade.cc | 9 ++--- src/shade.h | 3 +- src/vampire.cc | 9 ++--- src/vampire.h | 3 +- 24 files changed, 227 insertions(+), 186 deletions(-) delete mode 100644 src/map.cc.bak diff --git a/src/arguments.cc b/src/arguments.cc index bcfe2f2..f51c4fd 100644 --- a/src/arguments.cc +++ b/src/arguments.cc @@ -41,6 +41,8 @@ feature proc_args(int argc, char **argv, result |= FEATURE_MENU; } else if (str == "-c") { result |= FEATURE_ENEMIES_CHASE; + } else if (str == "-C") { + result |= FEATURE_COLORFUL; } else if (str == "-i") { result |= FEATURE_INVENTORY; } else if (str == "-t") { @@ -186,6 +188,7 @@ void print_args_list() { -r : Randomly generate maps\n\ -m : Enabled a main menu + options\n\ -c : Enemies chase the player (through doors and up stairs)\n\ +-C : Give things better coloring\n\ -i : Enable inventory\n\ -t : Enable throw\n\ -R : Enable revisiting levels\n\ diff --git a/src/characters.cc b/src/characters.cc index 704a058..b3473b6 100644 --- a/src/characters.cc +++ b/src/characters.cc @@ -2,11 +2,10 @@ #include -character::character(RNG *rng, const enum race &nrace): - rng{rng}, - race{nrace}, HP{STARTING_HP[race]}, +character::character(RNG *rng, const enum race &nrace, const position &pos): + rng{rng}, race{nrace}, HP{STARTING_HP[race]}, ATK{STARTING_ATK[race]}, DEF{STARTING_DEF[race]}, - base_hit_rate{1, 1} {} + base_hit_rate{1, 1}, pos{pos} {} void character::start_turn() { ATK = STARTING_ATK[race]; @@ -14,6 +13,11 @@ void character::start_turn() { base_hit_rate = {1, 1}; } +void character::print(display *out, bool color, bool player) { + out->print_char(pos, player ? '@' : CHARACTER_REP[race], + COLOR_PAIR(COLOR_BLACK_ON_WHITE)); +} + enum race character::get_race() const { return race; } @@ -46,10 +50,18 @@ fraction character::get_hitrate() const { return base_hit_rate; } +int character::get_room_num() const { + return room_num; +} + bool character::is_hostile() const { return hostile; } +void character::set_room_num(const int room) { + room_num = room; +} + void character::set_position(const position &npos) { pos = npos; } diff --git a/src/characters.h b/src/characters.h index e23719f..5393126 100644 --- a/src/characters.h +++ b/src/characters.h @@ -6,6 +6,7 @@ #include #include "constants.h" +#include "display.h" #include "fraction.h" #include "position.h" #include "potions.h" @@ -15,11 +16,12 @@ class character; // forward declaration // Note: player should not be in the character list -typedef std::vector character_list; +typedef std::vector character_list; class character { public: - character(RNG *rng, const race &nrace); // fills out the starting stats + character(RNG *rng, const race &nrace, + const position &pos); // fills out the starting stats // usually I wouldn't do this but considering that the map has // a super small size an O(n) solution is acceptable @@ -36,6 +38,10 @@ public: potion_list &potions); virtual result get_hit(const enum race &race, const int atk, const fraction hitrate) = 0; + + // overload for different races + virtual void print(display *out, bool color = false, bool player = false); + result apply_effects(); void discard_level_effects(); void start_turn(); @@ -49,6 +55,7 @@ public: float get_hitrate_real() const; fraction get_hitrate() const; bool is_hostile() const; + int get_room_num() const; void set_position(const position &npos); void set_HP(const int nHP); @@ -56,7 +63,8 @@ public: void set_DEF(const int nDEF); void set_gold(const int ngold); void set_hitrate(const fraction nhitrate); - void set_hostile(const bool is_hostile); + virtual void set_hostile(const bool is_hostile); + void set_room_num(const int room); // if stat is hostile, positive to set it to hostile, // negative to set it to peaceful @@ -81,6 +89,7 @@ protected: potion_list effects; // applied potions bool hostile; + int room_num; private: void insert_potion(potion *p); }; diff --git a/src/constants.h b/src/constants.h index 25590e8..2e696bd 100644 --- a/src/constants.h +++ b/src/constants.h @@ -31,17 +31,19 @@ enum game_command {game_command_terminate = 0, enum stat_name {HP, ATK, DEF, hostile}; -const int RACE_CNT = 4; // TODO: update as you go +const int RACE_CNT = 5; // TODO: update as you go -enum race {rshade = 0, rvampire, rgoblin, rdrow /* TODO: fill out the other races (including enemies) */}; +enum race {rshade = 0, rvampire, rgoblin, rdrow, rdragon /* TODO: fill out the other races (including enemies) */}; // TODO: fill out the other races (including enemies) -const int MAX_HP[RACE_CNT] = {125, INF, 110, 150}; -const int STARTING_HP[RACE_CNT] = {125, 50, 110, 150}; -const int STARTING_ATK[RACE_CNT] = {25, 25, 15, 25}; -const int STARTING_DEF[RACE_CNT] = {25, 25, 20, 15}; -const char CHARACTER_REP[RACE_CNT] = {'S', 'V', 'G', 'D'}; +const int MAX_HP[RACE_CNT] = {125, INF, 110, 150, 150}; +const int STARTING_HP[RACE_CNT] = {125, 50, 110, 150, 150}; +const int STARTING_ATK[RACE_CNT] = {25, 25, 15, 25, 20}; +const int STARTING_DEF[RACE_CNT] = {25, 25, 20, 15, 20}; +const char CHARACTER_REP[RACE_CNT] = {'S', 'V', 'G', 'd', 'D'}; +const int POTION_TYPE_CNT = 6; +const int DEFAULT_POTION_TYPE_CNT = 6; enum potion_type {restore_health = 0, boost_atk, boost_def, poison_health, wound_atk, wound_def }; @@ -94,6 +96,7 @@ const feature FEATURE_IN_FILE = 1 << 9; const feature FEATURE_OUT_FILE = 1 << 10; const feature FEATURE_EXTRA_STUFF = 1 << 11; const feature FEATURE_EXTRA_LEVELS = 1 << 12; +const feature FEATURE_COLORFUL = 1 << 13; const feature FEATURE_PANIC_SEED = 1 << 27; const feature FEATURE_PANIC_FILE = 1 << 28; @@ -109,4 +112,9 @@ const int COLOR_BLACK_ON_WHITE = 8; typedef std::vector position_list; typedef std::vector direction_list; +const int GOLD_SMALL = 1; +const int GOLD_NORMAL = 2; +const int GOLD_MERCHANT = 4; +const int GOLD_DRAGON = 6; + #endif diff --git a/src/goblin.cc b/src/goblin.cc index 3155232..9abc4ac 100644 --- a/src/goblin.cc +++ b/src/goblin.cc @@ -2,9 +2,8 @@ #include #include -goblin::goblin(RNG *rng, const position_list &available_positions): - character{rng, race::rshade} { - pos = available_positions[rng->rand_under(available_positions.size())]; +goblin::goblin(RNG *rng, const position &pos): + character{rng, race::rshade, pos} { gold = 0; hostile = true; } @@ -13,8 +12,8 @@ result goblin::attack(const direction dir, character_list &chlist) { position tmp{pos + MOVE[dir]}; for (auto &ch : chlist) - if (tmp == ch.get_position()) { - auto res = ch.get_hit(race, ATK, base_hit_rate); + if (tmp == ch->get_position()) { + auto res = ch->get_hit(race, ATK, base_hit_rate); if (res == result::died) { gold += GAIN_GOLD; diff --git a/src/goblin.h b/src/goblin.h index c416a4f..a1d81cf 100644 --- a/src/goblin.h +++ b/src/goblin.h @@ -2,12 +2,10 @@ #define __GOBLIN_H__ #include "characters.h" -const int GAIN_GOLD = 5; - class goblin final: public character { + static const int GAIN_GOLD = 5; public: - goblin(RNG *rng, - const position_list &available_positions); + goblin(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, diff --git a/src/gold.h b/src/gold.h index 738f066..92bc7c8 100644 --- a/src/gold.h +++ b/src/gold.h @@ -2,7 +2,9 @@ #define __GOLD_H__ #include +#include "constants.h" #include "position.h" +#include "rng.h" struct gold { int amount; @@ -11,4 +13,21 @@ struct gold { typedef std::vector gold_list; +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; +} + #endif diff --git a/src/level.h b/src/level.h index 4488d5f..3174861 100644 --- a/src/level.h +++ b/src/level.h @@ -2,30 +2,56 @@ #define __LEVEL_H__ #include +#include +#include #include "display.h" -#include "characters.h" -#include "potion.h" +#include "enemies.h" +#include "potions.h" #include "constants.h" #include "gold.h" #include "map.h" class level { private: + static const int MAX_POTION_CNT = 15; + static const int MAX_ENEMIE_CNT = 30; + static const int MIN_POTION_CNT = 10; + static const int MIN_ENEMIE_CNT = 20; + static const int GOLD_CNT = 10; + + const feature enabled_features; game_map map; - const character &player; + character *player; + std::vector>pchlist; + std::vector>pplist; character_list chlist; potion_list plist; gold_list glist; public: // randomly generate a map - level(const character &player); + level(character *player, RNG *rng, const feature enabled_features); // read map from a string - level(const std::string &map_data, const character &player); - void print(display &out) const; - void run(); - position_list get_available_positions() const; + level(const std::string &map_data, character *player, RNG *rng, + const feature enabled_features); + void print(display *out) const; + + bool is_available(const position &pos) const; + position_list get_available_around(const position &pos) const; position get_up_stairs() const; position get_down_stairs() const; + + // you can delete the pointers to the stuff + character_list &get_chlist(); + potion_list &get_plist(); + gold_list &get_glist(); +private: + // every gen will delete the positions in tiles + void gen_potions(RNG *rng, std::vector &tiles); + void gen_gold(RNG *rng, std::vector &tiles); + void gen_enemies(RNG *rng, std::vector &tiles); + + position get_rand_pos(RNG *rng, std::vector &tiles); + gold_list dragon_hoard(); }; #endif diff --git a/src/map.cc b/src/map.cc index 6401513..24f64e8 100644 --- a/src/map.cc +++ b/src/map.cc @@ -1,11 +1,10 @@ #include "map.h" #include -#include #include -game_map::game_map(RNG *rng, const feature enabled_features): +game_map::game_map(character *player, RNG *rng, const feature enabled_features): enabled_features{enabled_features} { map.reserve(MAP_HEIGHT * MAP_WIDTH); @@ -26,21 +25,40 @@ game_map::game_map(RNG *rng, const feature enabled_features): gen_path(layer_data, rng); - for (std::size_t i = 0; i < map.size(); ++i) - if (map[i] >= 0 && map[i] < MAX_ROOM_CNT) - empty_spots.push_back(remap_index(i)); - down_stairs = rng->get_rand_in_vector(empty_spots); + rooms_tile_list.reserve(room_data.size()); + + for (size_t i = 0; i < room_data.size(); ++i) + rooms_tile_list.push_back({}); + + for (size_t i = 0; i < map.size(); ++i) + if (map[i] >= 0 && map[i] < MAX_ROOM_CNT) + rooms_tile_list[map[i]].push_back(remap_index(i)); + + for (size_t i = 0; i < rooms_tile_list.size(); ++i) + rooms_tile_list[i].shrink_to_fit(); + + rooms_tile_list.shrink_to_fit(); + + int player_room = rng->rand_under(room_data.size()); + player->set_position(rng->get_rand_in_vector(rooms_tile_list[player_room])); + + gen_stairs(player_room, rng); +} + +void game_map::gen_stairs(int player_room, RNG *rng) { + down_stairs = rng->get_rand_in_vector(rooms_tile_list[ + rng->exclude_middle(0, room_data.size(), player_room)]); if (enabled_features & FEATURE_REVISIT) { - auto tmp = remove_from_list(empty_spots, down_stairs); - up_stairs = rng->get_rand_in_vector(tmp); + up_stairs = rng->get_rand_in_vector(rooms_tile_list[player_room]); map[remap_position(up_stairs)] = '<'; map[remap_position(down_stairs)] = '>'; } else { map[remap_position(down_stairs)] = '\\'; } + } position game_map::random_size(int min_width, int min_height, @@ -50,11 +68,15 @@ position game_map::random_size(int min_width, int min_height, rng->rand_between(min_height, max_height + 1)}; } -game_map::game_map(const std::string &map_data, +game_map::game_map(character *player, const std::string &map_data, RNG *rng, const feature enabled_features): enabled_features{enabled_features} { int map_size = MAP_HEIGHT * MAP_WIDTH; map.reserve(map_size); + rooms_tile_list.reserve(MAX_ROOM_CNT); + + for (int i = 0; i < MAX_ROOM_CNT; ++i) + rooms_tile_list.push_back({}); int max_room_num = 0; @@ -67,24 +89,17 @@ game_map::game_map(const std::string &map_data, } if (map_data[i] >= '0' && map_data[i] <= '9') - empty_spots.push_back(remap_index(i)); - } - - down_stairs = rng->get_rand_in_vector(empty_spots); - - - if (enabled_features & FEATURE_REVISIT) { - auto tmp = remove_from_list(empty_spots, down_stairs); - up_stairs = rng->get_rand_in_vector(tmp); - - map[remap_position(up_stairs)] = '<'; - map[remap_position(down_stairs)] = '>'; - } else { - map[remap_position(down_stairs)] = '\\'; + rooms_tile_list[map_data[i] - '0'].push_back(remap_index(i)); } for (int i = 0; i <= max_room_num; ++i) room_data.push_back({0, 0, 0, 0}); + + int player_room = rng->rand_under(room_data.size()); + player->set_position(rng->get_rand_in_vector(rooms_tile_list[player_room])); + + gen_stairs(player_room, rng); + } bool game_map::is_available(const position &pos) const { @@ -113,6 +128,14 @@ void game_map::print(display *out) const { map[i] == '<' ? COLOR_PAIR(COLOR_BLUE) : A_NORMAL); } +int game_map::which_room(const position &pos) const { + if (pos.y > MAP_HEIGHT || pos.x > MAP_WIDTH || pos.x < 0 || pos.y < 0) + return -1; + + char tmp = map[remap_position(pos)]; + return tmp < MAX_ROOM_CNT ? tmp : -1; +} + position game_map::get_up_stairs() const { return up_stairs; } @@ -130,29 +153,11 @@ int game_map::get_down_stairs_room() const { } position_list game_map::get_room_list(int idx) const { - position_list result; - - for (size_t i = 0; i < map.size(); ++i) { - if (map[i] == idx) - result.push_back(remap_index(i)); - } - - result.shrink_to_fit(); - return result; + return rooms_tile_list[idx]; } std::vector game_map::get_room_list() const { - std::vector result; - result.reserve(room_data.size()); - - for (size_t i = 0; i < room_data.size(); ++i) - result.push_back({}); - - for (size_t i = 0; i < map.size(); ++i) - if (map[i] >= 0 && map[i] < MAX_ROOM_CNT) - result[map[i]].push_back(remap_index(i)); - - return result; + return rooms_tile_list; } std::vector> game_map::gen_room_dims(RNG *rng) { diff --git a/src/map.cc.bak b/src/map.cc.bak deleted file mode 100644 index d9827cd..0000000 --- a/src/map.cc.bak +++ /dev/null @@ -1,68 +0,0 @@ -#include "map.h" - -#include -#include -#include -#include - -game_map::game_map(int lvl) { - level = lvl; - // TODO: randomly generate a map -} - -game_map::game_map(const std::string &map_data, int lvl) { - level = lvl; - std::istringstream iss{map_data}; - - std::string line; - - for (int i = 0; i < MAP_HEIGHT; ++i) { - getline(iss, line); - map[i] = line; - } -} - -game_map::~game_map() {} - -int game_map::get_level() const { - return this->level; -} - -std::vector game_map::get_available_positions() const { - std::vector result; - - for (int line = 0; line < MAP_HEIGHT; ++line) - for (int x = 0; x < MAP_WIDTH; ++x) - if (map[line][x] == '.' || - map[line][x] == '#' || - map[line][x] == '+') - result.push_back(position{x, line}); - return result; -} - -void game_map::print() const { - - // TODO: write a print function using ncurses -} - -void game_map::print(display &display) const { - for (int i = 0; i < MAP_HEIGHT; ++i) - display.print_str(position{0, i}, map[i]); -} - -void game_map::apply_potion(character *who, const stat_name statn, - const int amount) { - effects.push_back(effect{who, statn, amount}); - who->apply_buff(statn, amount); -} - -void game_map::enter_level(character *who) { - for (auto eff : effects) - if (eff.who == who) - who->apply_buff(eff.statn, eff.amount); -} - -void game_map::leave_level(character *who) { - who->set_ATK(STARTING_ATK[who->get_race()]); - who->set_DEF(STARTING_DEF[who->get_race()]); -} diff --git a/src/map.h b/src/map.h index f96b529..1e348ab 100644 --- a/src/map.h +++ b/src/map.h @@ -8,6 +8,7 @@ #include "position.h" #include "rng.h" #include "fraction.h" +#include "characters.h" class game_map final { private: @@ -26,10 +27,9 @@ private: const feature enabled_features; std::vector map; - // IMPORTANT: keep empty_spots ordered - position_list empty_spots; position up_stairs; position down_stairs; + std::vector rooms_tile_list; public: struct room { int top; @@ -51,13 +51,14 @@ public: } }; // randomly generate a map - game_map(RNG *rng, const feature enabled_features); + game_map(character *player, RNG *rng, const feature enabled_features); // read map from a string - game_map(const std::string &map_data, RNG *rng, + game_map(character *player, const std::string &map_data, RNG *rng, const feature enabled_features); bool is_available(const position &pos) const; position_list get_available_around(const position &pos) const; + int which_room(const position &pos) const; position_list get_room_list(int idx) const; std::vector get_room_list() const; @@ -115,6 +116,8 @@ private: void connect(position s, position t); room hit_room(const position &a); bool hit_room(const position &a, const room &r); + + void gen_stairs(int player_room, RNG *rng); }; const std::string default_map = diff --git a/src/position.cc b/src/position.cc index b30636d..452d9c2 100644 --- a/src/position.cc +++ b/src/position.cc @@ -65,16 +65,12 @@ std::vector remove_from_list(const std::vector return result; } -std::vector remove_from_list(const std::vector - &sorted_positions, - position &excluded) { - - std::vector result{sorted_positions.size() - 1}; - - for (auto src : sorted_positions) { - if (src != excluded) - result.push_back(src); - } - - return result; +void remove_from_list(std::vector + &positions, + position &excluded) { + for (auto i = positions.begin(); i != positions.end(); ++i) + if (*i == excluded) { + positions.erase(i); + return; + } } diff --git a/src/position.h b/src/position.h index b7a6d55..c796540 100644 --- a/src/position.h +++ b/src/position.h @@ -24,7 +24,6 @@ std::size_t find(const std::vector &sorted_list, std::vector remove_from_list(const std::vector &sorted_positions, std::vector excluded); -std::vector remove_from_list(const std::vector - &sorted_positions, - position &excluded); +void remove_from_list(std::vector &sorted_positions, + position &excluded); #endif diff --git a/src/potion.cc b/src/potion.cc index b2e5e36..38bf023 100644 --- a/src/potion.cc +++ b/src/potion.cc @@ -40,3 +40,7 @@ potion &potion::operator=(potion &&p) { pos = p.pos; return *this; } + +void potion::print(display *out, bool color) { + out->print_char(pos, 'P'); +} diff --git a/src/potion.h b/src/potion.h index 64d6786..9dcc92e 100644 --- a/src/potion.h +++ b/src/potion.h @@ -4,6 +4,7 @@ #include #include "constants.h" #include "fraction.h" +#include "display.h" // IMPORTANT: pop all potions of duration == 0, and when entering a // new level, pop all potions of duration == -1 @@ -31,6 +32,8 @@ public: int get_duration() const; position get_pos() const; void set_pos(const position &npos); + + virtual void print(display *out, bool color = false); }; typedef std::vector potion_list; diff --git a/src/races.h b/src/races.h index dd3862e..ddd0058 100644 --- a/src/races.h +++ b/src/races.h @@ -4,5 +4,6 @@ #include "shade.h" #include "goblin.h" #include "vampire.h" +#include "dragon.h" #endif diff --git a/src/restore_health.cc b/src/restore_health.cc index b1fa352..97cd861 100644 --- a/src/restore_health.cc +++ b/src/restore_health.cc @@ -2,8 +2,8 @@ #include -restore_health::restore_health(): - potion{potion_type::restore_health, -1, {0, 0}} {} +restore_health::restore_health(const position &pos): + potion{potion_type::restore_health, -1, pos} {} void restore_health::apply(const enum race &race, int &HP, int &ATK, int &DEF, fraction &base_hit_rate) { diff --git a/src/restore_health.h b/src/restore_health.h index 30916af..4f00a75 100644 --- a/src/restore_health.h +++ b/src/restore_health.h @@ -5,7 +5,7 @@ class restore_health final: public potion { public: - restore_health(); + restore_health(const position &pos); void apply(const enum race &race, int &HP, int &ATK, int &DEF, fraction &base_hit_rate) override; int get_priority() const override; diff --git a/src/rng.cc b/src/rng.cc index 07a0105..6a65f35 100644 --- a/src/rng.cc +++ b/src/rng.cc @@ -33,9 +33,36 @@ int RNG::get_curr_rand_num() const { } bool RNG::trial(const fraction &psuccess) { - return (rand() % psuccess.denominator) < psuccess.numerator; + return ((curr_rand_num = rand()) % psuccess.denominator) < + psuccess.numerator; } -bool RNG::coin_flip() const { - return rand() % 2; +bool RNG::coin_flip() { + return (curr_rand_num = rand()) % 2; +} + +int RNG::exclude_middle(const int lower_bound, const int upper_bound, + const int excluded) { + curr_rand_num = rand(); + int tmp = (curr_rand_num % (upper_bound - lower_bound - 1)); + return tmp >= excluded ? tmp + 1 : tmp; +} + +template T RNG::rand_exclude(std::vector &vec, T &target) { + std::size_t idx = 0; + + for (; idx < vec.size(); ++idx) + if (vec[idx] == target) + break; + + return vec[exclude_middle(0, vec.size(), idx)]; +} + +template T RNG::get_rand_in_vector(std::vector &vec) { + if (!vec.size()) + return T{}; + + curr_rand_num = rand(); + + return vec[curr_rand_num % vec.size()]; } diff --git a/src/rng.h b/src/rng.h index 4283770..aba6324 100644 --- a/src/rng.h +++ b/src/rng.h @@ -28,13 +28,14 @@ public: bool trial(const fraction &psuccess); - bool coin_flip() const; + bool coin_flip(); - template T &get_rand_in_vector(std::vector &vec) { - curr_rand_num = rand(); + int exclude_middle(const int lower_bound, const int upper_bound, + const int excluded); - return vec[curr_rand_num % vec.size()]; - } + template T rand_exclude(std::vector &vec, T &target); + + template T get_rand_in_vector(std::vector &vec); }; #endif diff --git a/src/shade.cc b/src/shade.cc index 38bbe96..9fcac64 100644 --- a/src/shade.cc +++ b/src/shade.cc @@ -3,9 +3,8 @@ #include #include -shade::shade(RNG *rng, const position_list &available_positions): - character{rng, race::rshade} { - pos = available_positions[rng->rand_under(available_positions.size())]; +shade::shade(RNG *rng, const position &pos): + character{rng, race::rshade, pos} { gold = 0; hostile = true; } @@ -14,8 +13,8 @@ result shade::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); + if (tmp == ch->get_position()) { + return ch->get_hit(race, ATK, base_hit_rate); } return result::fine; diff --git a/src/shade.h b/src/shade.h index 9848045..59a748c 100644 --- a/src/shade.h +++ b/src/shade.h @@ -5,8 +5,7 @@ class shade final: public character { public: - shade(RNG *rng, const position_list - &available_positions); // spawn at a random place + shade(RNG *rng, const position &pos); // spawn at a random place virtual result attack(const direction dir, character_list &chlist) override; virtual result get_hit(const enum race &race, const int atk, diff --git a/src/vampire.cc b/src/vampire.cc index 2528977..705a69f 100644 --- a/src/vampire.cc +++ b/src/vampire.cc @@ -2,9 +2,8 @@ #include #include -vampire::vampire(RNG *rng, const position_list &available_positions): - character{rng, race::rshade} { - pos = available_positions[rng->rand_under(available_positions.size())]; +vampire::vampire(RNG *rng, const position &pos): + character{rng, race::rshade, pos} { gold = 0; hostile = true; } @@ -13,8 +12,8 @@ result vampire::attack(const direction dir, character_list &chlist) { position tmp{pos + MOVE[dir]}; for (auto &ch : chlist) - if (tmp == ch.get_position()) { - auto res = ch.get_hit(race, ATK, base_hit_rate); + if (tmp == ch->get_position()) { + auto res = ch->get_hit(race, ATK, base_hit_rate); if (res != result::miss) { HP += GAIN_HP; diff --git a/src/vampire.h b/src/vampire.h index b74900c..7a68922 100644 --- a/src/vampire.h +++ b/src/vampire.h @@ -6,8 +6,7 @@ const int GAIN_HP = 5; class vampire final: public character { public: - vampire(RNG *rng, - const position_list &available_positions); + vampire(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,