finished the bulk of game

This commit is contained in:
2024-07-14 21:32:41 -04:00
parent b3475b7530
commit af8bc4112c
110 changed files with 1876 additions and 1481 deletions

115
src/enemy.cc Normal file
View File

@ -0,0 +1,115 @@
#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} {
base_hit_rate_reset = {1, 2};
}
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 &&
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 (lvl->get_room(tmp) == room_num &&
lvl->is_available(tmp) &&
distance_sqr(tmp, pc->get_pos()) <
distance_sqr(target, pc->get_pos()))
target = tmp;
}
pos = target;
return {fine, ""};
}
int choices_cnt = 0;
position choices[DIRECTION_CNT];
for (int i = 0; i < DIRECTION_CNT; ++i)
if (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 {fine, ""};
}
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 + ". " + abbrev +
" is slain by PC. "};
return {result::hit, "PC deals " +
std::to_string(tmp) + " damage to " + abbrev};
}
return {miss, "PC tried to hit " + abbrev + " but missed. "};
}
void enemy_base::dies(level *lvl, character *pc) {
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;
} else if (race == race::rmerchant) {
lvl->add_gold({GOLD_MERCHANT, pos});
} else if (race == race::rhuman) {
lvl->add_gold({GOLD_NORMAL, pos});
auto plist = lvl->get_available_around_all(pos);
lvl->add_gold({GOLD_NORMAL,
rng->get_rand_in_vector(plist)});
}
((player_base *)pc)->add_gold(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;
}