116 lines
3.3 KiB
C++
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;
|
|
}
|