pokemon/window/stats.cpp

230 lines
6.5 KiB
C++

#include "../font.hpp"
#include "../number.hpp"
#include "../graphic.hpp"
#include "../gen/pokemon/types.hpp"
#include "../gen/pokemon/moves.hpp"
#include "../pokemon_instance.hpp"
#include "../ailment.hpp"
#define S reinterpret_cast<const uint8_t *>
const uint8_t * status_string(const pokemon_instance_t& pokemon_instance)
{
if (pokemon_instance.current_hit_points == 0)
return S("FNT");
else
return ailments[pokemon_instance.ailment].name;
}
static void draw_stats_top_right_border_with_name(const uint32_t base_pattern,
const pokemon_instance_t& pokemon_instance)
{
draw_battle_border(base_pattern, {19, 1}, {8, 7});
// name
draw_text(base_pattern, pokemon[pokemon_instance.species].name, 9, 1);
}
static void draw_stats_pokedex_number(const uint32_t base_pattern,
const pokemon_instance_t& pokemon_instance)
{
// pokedex number
put_char(base_pattern, 1, 7, stats::no);
put_char(base_pattern, 2, 7, stats::no_dot);
const int32_t pokedex_number = static_cast<int32_t>(pokemon_instance.species) + 1;
draw_number_right_align(base_pattern,
{3, 7},
pokedex_number,
3, // width
ascii_to_font('0') // fill
);
}
void draw_stats1(const uint32_t base_pattern,
const pokemon_instance_t& pokemon_instance)
{
// white out the entire screen
draw_box_background(base_pattern, {-1, -1}, {20, 18});
// front picture label
{
draw_stats_pokedex_number(base_pattern, pokemon_instance);
}
// top status battle box
{
// name and border
draw_stats_top_right_border_with_name(base_pattern, pokemon_instance);
// level
put_char(base_pattern, 14, 2, battle_border::level);
draw_number_left_align(base_pattern, {15, 2},
pokemon_instance.level,
3); // width
// hp
draw_hp_bar_with_numbers(base_pattern, pokemon_instance, {11, 3});
// status
draw_text(base_pattern, S("STATUS/"), 9, 6);
draw_text(base_pattern, status_string(pokemon_instance), 16, 6);
}
// bottom right border
{
draw_battle_border(base_pattern, {19, 9}, {12, 17});
int32_t distinct_types = (pokemon[pokemon_instance.species].types[0]
!= pokemon[pokemon_instance.species].types[1]) + 1;
for (int32_t ix = 0; ix < distinct_types; ix++) {
const enum type_t::type type = pokemon[pokemon_instance.species].types[ix];
draw_text(base_pattern, S("TYPE"), 10, 9 + (2 * ix));
put_char(base_pattern, 14, 9 + (2 * ix), ascii_to_font('1' + ix));
put_char(base_pattern, 15, 9 + (2 * ix), ascii_to_font('/'));
draw_text(base_pattern, types[type].name, 11, 10 + (2 * ix));
}
}
{ // bottom left dialog box
draw_box_border(base_pattern, {0, 8}, {9, 17});
draw_text(base_pattern, S("ATTACK"), 1, 9 + 0);
draw_text(base_pattern, S("DEFENSE"), 1, 9 + 2);
draw_text(base_pattern, S("SPEED"), 1, 9 + 4);
draw_text(base_pattern, S("SPECIAL"), 1, 9 + 6);
draw_number_right_align(base_pattern, {6, 10 + 0},
pokemon_instance.stat_values.attack,
3, ascii_to_font(' ')); // width, fill
draw_number_right_align(base_pattern, {6, 10 + 2},
pokemon_instance.stat_values.defense,
3, ascii_to_font(' ')); // width, fill
draw_number_right_align(base_pattern, {6, 10 + 4},
pokemon_instance.stat_values.speed,
3, ascii_to_font(' ')); // width, fill
draw_number_right_align(base_pattern, {6, 10 + 6},
pokemon_instance.stat_values.special,
3, ascii_to_font(' ')); // width, fill
} // end bottom left dialog box
}
void draw_stats_move(const uint32_t base_pattern,
const pokemon_instance_t& pokemon_instance,
const int32_t _ix)
{
const int32_t ix = _ix & 0b11;
const int32_t y_offset = 2 * ix;
constexpr int32_t name_x = 2;
constexpr int32_t name_y = 9;
constexpr int32_t pp_x = 11;
constexpr int32_t pp_y = 10;
// move name
const move_instance_t& move_instance = pokemon_instance.move_instances[ix];
if (move_instance.type != move_t::no_move) {
const move_t& move = moves[move_instance.type];
// name
draw_text(base_pattern, move.name, name_x, name_y + y_offset);
// pp
put_char(base_pattern, pp_x + 0, pp_y + y_offset, stats::p);
put_char(base_pattern, pp_x + 1, pp_y + y_offset, stats::p);
draw_number_right_align(base_pattern, {pp_x + 3, pp_y + y_offset},
move_instance.pp,
2, ascii_to_font(' ')); // width, fill
put_char(base_pattern, pp_x + 5, pp_y + y_offset, ascii_to_font('/'));
draw_number_right_align(base_pattern, {pp_x + 6, pp_y + y_offset},
moves[move_instance.type].pp,
2, ascii_to_font(' ')); // width, fill
} else {
// name
put_char(base_pattern, name_x, name_y + y_offset, ascii_to_font('-'));
// pp
put_char(base_pattern, pp_x + 0, pp_y + y_offset, ascii_to_font('-'));
put_char(base_pattern, pp_x + 1, pp_y + y_offset, ascii_to_font('-'));
}
}
void draw_stats2(const uint32_t base_pattern,
const pokemon_instance_t& pokemon_instance)
{
// white out the entire screen
draw_box_background(base_pattern, {-1, -1}, {20, 18});
// front picture label
{
draw_stats_pokedex_number(base_pattern, pokemon_instance);
}
// top status battle box
{
// name and border
draw_stats_top_right_border_with_name(base_pattern, pokemon_instance);
// exp points
draw_text(base_pattern, S("EXP POINTS"), 9, 3);
draw_number_right_align(base_pattern,
{13, 4},
pokemon_instance.total_experience,
6, // width
ascii_to_font(' ') // fill
);
// level up
draw_text(base_pattern, S("LEVEL UP"), 9, 5);
put_char(base_pattern, 14, 6, stats::to);
put_char(base_pattern, 16, 6, battle_border::level);
const int32_t next_level = pokemon_instance.level < 100
? (pokemon_instance.level + 1)
: 100;
int32_t exp_to = 1234;
if (next_level < 100) {
draw_number_left_align(base_pattern,
{17, 6},
next_level,
2 // width
);
} else {
draw_number_left_align(base_pattern,
{16, 6},
next_level,
3 // width
);
}
// exp
draw_number_right_align(base_pattern,
{9, 6},
exp_to,
5, // width
ascii_to_font(' ') // fill
);
}
// bottom move list
{
draw_box_border(base_pattern, {0, 8}, {19, 17});
draw_stats_move(base_pattern, pokemon_instance, 0);
draw_stats_move(base_pattern, pokemon_instance, 1);
draw_stats_move(base_pattern, pokemon_instance, 2);
draw_stats_move(base_pattern, pokemon_instance, 3);
}
}
#undef S