Files
cc3k/src/enemy.cc

105 lines
3.4 KiB
C++

#include "enemy.h"
#include "constants.h"
#include "player.h"
#include "level.h"
enemy_base::enemy_base(RNG *rng, const feature enabled_features,
const enum race &nrace, const position &pos,
const int gen_room_num, std::string abbrev):
character{rng, enabled_features, nrace, pos},
room_num{gen_room_num}, abbrev{abbrev} {}
int enemy_base::get_room_num() const {
return room_num;
}
long_result enemy_base::act(level *lvl, character *pc, bool hostile) {
if (is_adjacent(pos, pc->get_pos()) && hostile)
return attack(pc);
if (enabled_features & FEATURE_ENEMIES_CHASE && hostile &&
distance_sqr(pos, pc->get_pos()) <= DIST_THRESHOLD_SQR) {
position tmp;
position target = {BIG_NUMBER, BIG_NUMBER};
for (int i = 0; i < DIRECTION_CNT; ++i) {
tmp = pos + MOVE[i];
if (((enabled_features & FEATURE_DOORS) ? true
: lvl->get_room(tmp) == room_num) &&
lvl->is_available(tmp) &&
distance_sqr(tmp, pc->get_pos()) <
distance_sqr(target, pc->get_pos()))
target = tmp;
}
if (target.x != BIG_NUMBER)
pos = target;
return {NOTHING, ""};
}
int choices_cnt = 0;
position choices[DIRECTION_CNT];
for (int i = 0; i < DIRECTION_CNT; ++i)
if (((enabled_features & FEATURE_DOORS) ?
true : lvl->get_room(pos + MOVE[i]) == room_num ) &&
lvl->is_available(pos + MOVE[i])) {
choices[choices_cnt] = pos + MOVE[i];
++choices_cnt;
}
if (choices_cnt)
pos = choices[rng->rand_under(choices_cnt)];
return {NOTHING, ""};
}
long_result enemy_base::attack(character *ch) {
return ch->get_hit(this, ATK, base_hit_rate);
}
std::string enemy_base::get_abbrev() const {
return abbrev;
}
long_result enemy_base::get_hit(character *ch, const int tATK,
const fraction &hit_rate) {
if (rng->trial(hit_rate)) {
int tmp = calc_dmg(tATK, DEF);
tmp = tmp > HP ? HP : tmp;
HP -= tmp;
if (HP == 0)
return {result::HIT,
"PC deals " + std::to_string(tmp) +
" damage to " + abbrev + " (" +
std::to_string(HP) + " HP). " +
abbrev + " is slain by PC. "};
return {result::HIT, "PC deals " +
std::to_string(tmp) + " damage to " + abbrev + " (" +
std::to_string(HP) + " HP). "};
}
return {MISS, "PC tried to hit " + abbrev + " but missed. "};
}
int enemy_base::dies(level *lvl) {
return rand_gold_drop(rng);
}
enemy_base *get_enemy_at(const position &pos, const enemy_list &elist) {
for (auto e : elist)
if (e->get_pos() == pos)
return e;
return nullptr;
}
void enemy_base::print(output *out) {
out->print_char(pos, CHAR_REP[race], COLOR_PAIR(COLOR_RED));
}