New attack function for single character in characters.h, need implementation (example in shade.h)

This commit is contained in:
2024-07-13 17:13:10 -04:00
parent df9e2d31df
commit 8da12f5360
7 changed files with 127 additions and 5 deletions

View File

@ -202,6 +202,17 @@ result character::move_or_attack(const direction dir,
return this->attack(dir, chlist);
}
result character::move_or_attack(const direction dir,
const position_list &available_positions,
character *ch) {
auto res = this->move(dir, available_positions);
if (res != result::fine)
return res;
return this->attack(dir, ch);
}
int calc_dmg(const int ATK, const int DEF) {
return ceil((100 / (100 + DEF)) * ATK);

View File

@ -34,6 +34,12 @@ public:
virtual result move_or_attack(const direction dir,
const position_list &available_positions,
character_list &chlist);
virtual result attack(const direction dir, character *ch) = 0;
virtual result move_or_attack(const direction dir,
const position_list &available_positions,
character *ch);
virtual void apply(direction &dir,
potion_list &potions);
virtual result get_hit(const enum race &race, const int atk,

View File

@ -9,9 +9,11 @@ const int INF = 0x3F3F3F3F;
enum error {none};
// TODO: update result to include subject
enum result {fine, died, go_down, hit, moved, miss};
enum result {fine, died, go_down, go_up, hit, moved, miss};
enum game_status {terminated, main_menu, in_game, options};
enum game_status {terminated, main_menu, in_game, options,
dead, won, escaped, restart
};
enum game_command {game_command_terminate = 0,
move_north, move_south, move_east, move_west,

76
src/game.cc Normal file
View File

@ -0,0 +1,76 @@
#include "game.h"
#include "races.h"
game::game(const enum race starting_race,
const feature enabled_features,
input *new_in,
display *new_out,
logger *new_log,
RNG *new_rng):
enabled_features{enabled_features},
in{new_in}, out{new_out}, log{new_log}, rng{new_rng} {
const position nil{0, 0};
the_world = false;
// TODO: add the other races
switch (starting_race) {
case race::rshade:
player = std::make_unique<shade>(rng, nil);
break;
}
if (enabled_features & FEATURE_EXTRA_LEVELS)
max_level = rng->rand_between(MIN_LEVEL_CNT, MAX_LEVEL_CNT + 1);
else
max_level = DEFAULT_MAX_LEVEL;
levels.reserve(max_level);
curr_level = 0;
new_level();
}
void game::new_level() {
if (enabled_features & FEATURE_RAND_MAP)
levels.push_back(std::make_unique<level>(player.get(),
rng, enabled_features));
else
levels.push_back(std::make_unique<level>(default_map, player.get(),
rng, enabled_features));
}
game_status game::run() {
auto res = player_moves(in->get_command());
switch (res) {
case result::died:
return game_status::dead;
case result::go_down: {
if (curr_level == max_level - 1)
return game_status::won;
player->discard_level_effects();
++curr_level;
new_level();
break;
}
case result::go_up: {
if (curr_level == 0)
return game_status::escaped;
--curr_level;
player->set_position(levels[curr_level]->get_down_stairs());
break;
}
default:
break;
}
return game_status::in_game;
}

View File

@ -7,26 +7,43 @@
#include "input.h"
#include "rng.h"
#include "characters.h"
#include "map.h"
#include "level.h"
#include "log.h"
class game final {
private:
feature features;
static const size_t MAX_LEVEL_CNT = 50;
static const size_t MIN_LEVEL_CNT = 30;
static const size_t DEFAULT_MAX_LEVEL = 5;
const feature enabled_features;
input *in;
display *out;
logger *log;
RNG *rng;
std::unique_ptr<character> player;
std::vector<std::unique_ptr<level>> levels;
size_t max_level;
size_t curr_level;
bool the_world;
public:
game(const feature enabled_features,
game(const enum race starting_race,
const feature enabled_features,
input *new_in,
display *new_out,
logger *new_log,
RNG *new_rng);
game_status run();
size_t get_curr_level() const;
const character *get_player() const;
private:
result player_moves(game_command cmd);
void new_level();
void move_enemies();
};
#endif

View File

@ -20,6 +20,15 @@ result shade::attack(const direction dir, character_list &chlist) {
return result::fine;
}
result shade::attack(const direction dir, character *ch) {
position tmp{pos + MOVE[dir]};
if (tmp == ch->get_position())
return ch->get_hit(race, ATK, base_hit_rate);
return result::fine;
}
result shade::get_hit(const enum race &race, const int atk,
const fraction hitrate) {
if (rng->trial(hitrate)) // This is a hit!

View File

@ -10,6 +10,7 @@ public:
character_list &chlist) override;
virtual result get_hit(const enum race &race, const int atk,
const fraction hit_rate) override;
virtual result attack(const direction dir, character *ch) override;
};
#endif