pokemon/pokemon_instance.cpp

116 lines
3.3 KiB
C++

#include "pokemon_instance.hpp"
static constexpr uint16_t _determine_stat(const uint32_t base_stat_value,
const uint32_t determinant_value,
const uint32_t stat_experience,
const uint32_t level)
{
const uint32_t x = base_stat_value + determinant_value;
const uint32_t y = sqrt_ceil<uint16_t>(stat_experience) / 4;
const uint32_t z = (x * 2 + y) * level;
return (z / 100);
}
static_assert(_determine_stat(106, 0b0100, 0, 70) == (234 - 10 - 70));
static_assert(_determine_stat(110, 0b1110, 0, 70) == (178 - 5));
static_assert(_determine_stat( 90, 0b0101, 0, 70) == (138 - 5));
static_assert(_determine_stat(130, 0b1000, 0, 70) == (198 - 5));
static_assert(_determine_stat(154, 0b0110, 0, 70) == (229 - 5));
void
pokemon_instance_t::determine_stats()
{
stat_values.hit_points = _determine_stat(pokemon[species].base_stat_values.hit_points,
determinant_values.hit_points(),
stat_experience.hit_points,
level
) + 10 + level;
stat_values.attack = _determine_stat(pokemon[species].base_stat_values.attack,
determinant_values.attack(),
stat_experience.attack,
level
) + 5;
stat_values.defense = _determine_stat(pokemon[species].base_stat_values.defense,
determinant_values.defense(),
stat_experience.defense,
level
) + 5;
stat_values.speed = _determine_stat(pokemon[species].base_stat_values.speed,
determinant_values.speed(),
stat_experience.speed,
level
) + 5;
stat_values.special = _determine_stat(pokemon[species].base_stat_values.special,
determinant_values.special(),
stat_experience.special,
level
) + 5;
}
void
pokemon_instance_t::learn_move(enum move_t::move move, int32_t index)
{
switch (index) {
case 0: [[fallthrough]];
case 1: [[fallthrough]];
case 2: [[fallthrough]];
case 3:
move_instances[index].type = move;
move_instances[index].pp = moves[move].pp;
break;
default:
{
int32_t ix = 0;
while (move_instances[ix].type != move_t::no_move) {
if (move_instances[ix].type == move) return; // do not double-learn move_instances
if (++ix == 4) {
move_instances[0] = move_instances[1];
move_instances[1] = move_instances[2];
move_instances[2] = move_instances[3];
ix--;
break;
}
}
move_instances[ix].type = move;
move_instances[ix].pp = moves[move].pp;
}
break;
}
}
void pokemon_instance_t::learn_all_moves()
{
move_instances[0].type = move_t::no_move;
move_instances[1].type = move_t::no_move;
move_instances[2].type = move_t::no_move;
move_instances[3].type = move_t::no_move;
const level_move_t * level_moves = pokemon[species].by_level.moves;
for (int32_t ix = 0; ix < pokemon[species].by_level.length; ix++) {
if (level_moves[ix].level <= level)
learn_move(level_moves[ix].move, -1);
else
break;
}
}
void
pokemon_instance_t::init(const enum pokemon_t::pokemon species,
const uint8_t level)
{
this->species = species;
this->level = level;
stat_experience = {0, 0, 0, 0, 0};
determinant_values.dvs = 0b1110'0101'1000'0110;
determine_stats();
learn_all_moves();
current_hit_points = stat_values.hit_points;
total_experience = 0; // fixme exp
ailment = ailment_t::ok;
}