Files
cc3k/src/player.cc

176 lines
5.8 KiB
C++

#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. "};
}