#include "races.h"

#include <algorithm>
#include <math.h>

shade::shade(const position_list &available_positions):
        character{race::rshade} {
        pos = available_positions[rng.rand_under(available_positions.size())];
        gold = 0;
        hostile = true;
}

// IMPORTANT: remember to check if player is on the stairs
result shade::move(const direction dir,
                   const position_list &available_positions) {
        if (find(available_positions, pos + MOVE[dir])
            != available_positions.size()) {
                pos += MOVE[dir];
                return result::moved;
        }

        return result::fine;
}

result shade::attack(const direction dir, const character_list &chlist) {
        position tmp{pos + MOVE[dir]};

        for (auto &ch : chlist)
                if (tmp == ch->get_position()) {
                        return ch->get_hit(race, ATK, base_hitrate);
                }

        return result::fine;
}

result shade::move_or_attack(const direction dir,
                             const position_list &available_positions,
                             const character_list &chlist) {
        position tmp{pos + MOVE[dir]};

        if (find(available_positions, tmp)
            != available_positions.size()) {
                pos = tmp;
                return result::moved;
        }

        for (auto &ch : chlist)
                if (tmp == ch->get_position()) {
                        return ch->get_hit(race, ATK, base_hitrate);
                }

        return result::fine;
}

int calc_dmg(const int ATK, const int DEF) {
        return ceil((100 / (100 + DEF)) * ATK);
}

result shade::get_hit(const enum race &race, const int atk,
                      const float hitrate) {
        if (rng.rand_num() <= hitrate * (float)RAND_MAX) // This is a hit!
                HP = std::max(HP - calc_dmg(atk, DEF), 0);

        if (HP == 0)
                return result::died;

        return result::hit;
}
