#include "player.h" #include "constants.h" #include "enemy.h" #include "level.h" player_base::player_base(RNG *rng, const feature enabled_features, const enum race &nrace): character{rng, enabled_features, nrace, {0, 0}}, gold_cnt(0) {} void player_base::print(output *out) { out->print_char(pos, '@', COLOR_PAIR(COLOR_BLUE)); } std::string player_base::get_abbrev() const { return "PC"; } int player_base::get_gold() const { return this->gold_cnt; } int player_base::get_ATK() const { return this->ATK; } int player_base::get_DEF() const { return this->DEF; } int player_base::get_HP() const { return this->HP; } long_result player_base::apply(potion *p) { if (p == nullptr) return {result::applied_nothing, "PC tried to breathe the magic in the air. "}; apply_effect(p); if (race == rt_800) return {result::applied, "PC gets rusty joints (-5 HP). "}; return {result::applied, (std::string)"PC applied potion of " + p->get_name() + ". "}; } long_result player_base::attack(character *ch) { if (ch == nullptr) return {result::fine, "PC tried to attack thin air. "}; return ch->get_hit(this, ATK, base_hit_rate); } long_result player_base::move(level *lvl, const position &p) { if (enabled_features & FEATURE_NCURSES) { enemy_base *tmp = nullptr; if (lvl->is_available(p, true)) { pos = p; return {result::moved, ""}; } else if ((tmp = get_enemy_at(p, lvl->get_elist())) != nullptr) { auto res = attack((character *)tmp); if (tmp->is_dead()) tmp->dies(lvl, this); return res; } } else if (lvl->get_up_stairs() == p && enabled_features & FEATURE_REVISIT) { return {result::go_up, "PC went up the stairs. "}; } else if (lvl->get_down_stairs() == p) { return {result::go_down, "PC went down the stairs. "}; } else if (lvl->is_available(p, true)) { pos = p; return {result::moved, ""}; } return {result::fine, "PC tried to move into non-existent space. "}; } long_result player_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::died, ch->get_abbrev() + " deals " + std::to_string(tmp) + " damage to PC. PC is slain by " + ch->get_abbrev() + ". "}; return {result::hit, ch->get_abbrev() + " deals " + std::to_string(tmp) + " damage to PC. "}; } return {result::miss, ch->get_abbrev() + " tried to hit PC but missed. "}; } void player_base::add_gold(int amount) { gold_cnt += amount; } long_result player_base::interpret_command(level *lvl, game_command cmd) { if (cmd == game_command_terminate) { return {result::terminate, ""}; } else if (cmd >= move_north && cmd <= move_southwest) { auto res = move(lvl, pos + MOVE[cmd - move_north]); if (res.res == result::moved) start_turn(); gold g = get_gold_at(pos, lvl->get_glist()); gold_cnt += g.amount; return res; } else if (cmd >= apply_north && cmd <= apply_southwest) { auto res = apply(get_potion_at(pos + MOVE[cmd - apply_north], lvl->get_plist())); if (res.res == result::applied) start_turn(); return res; } else if (cmd == apply_panic) { return {result::fine, "PC tried to use in some non-existent direction. "}; } else if (cmd >= attack_north && cmd <= attack_southwest) { enemy_base *tmp = get_enemy_at(pos + MOVE[cmd - attack_north], lvl->get_elist()); if (tmp != nullptr) start_turn(); auto res = attack((character *)tmp); if (tmp != nullptr && tmp->is_dead()) tmp->dies(lvl, this); return res; } else if (cmd == up_stairs) { if (lvl->get_up_stairs() == pos && enabled_features & FEATURE_REVISIT) { start_turn(); return {go_up, "PC went up the stairs. "}; } return {result::fine, "PC tried to fly through the ceiling. "}; } else if (cmd == down_stairs) { if (lvl->get_down_stairs() == pos) { start_turn(); return {go_down, "PC went down the stairs. "}; } return {result::fine, "PC tried to dig through the floor. "}; } else if (cmd == the_world) { return{toggle_the_world, "PC toggled Stand: The World! "}; } else if (cmd == game_restart) { return {restart_game, ""}; } else if (cmd == game_command_pass) { return {result::fine, ""}; } return {unknown, "PC tried to produce some undefined behaviour. "}; }