This also includes a handful of functions for creating instances of a pokemon species, though certainly not complete.
320 lines
8.1 KiB
Python
320 lines
8.1 KiB
Python
"""
|
|
- constants
|
|
|
|
pokedex indicies:
|
|
- dex_constants
|
|
|
|
by constants index:
|
|
- evos_moves (pointer table)
|
|
- names
|
|
- dex_entries (pointer table)
|
|
|
|
by dex_constants value:
|
|
- base_stats (DEX_*)
|
|
(references Front/Back pic)
|
|
|
|
translation from constants to dex_constants:
|
|
- dex_order
|
|
|
|
from pic to gfx/ filename:
|
|
- pic
|
|
"""
|
|
|
|
from itertools import chain, starmap
|
|
from generate.generate import renderer
|
|
from generate.binary import start_size_value
|
|
from parse import parse
|
|
|
|
#from pprint import pprint
|
|
#print(parse.pokemon_dex_constants_list())
|
|
#print(parse.pokemon_constants_list())
|
|
#print(parse.pokemon_names_list())
|
|
#print(parse.pokemon_dex_entries_list())
|
|
#print(parse.pokemon_dex_order_list())
|
|
#pprint(parse.pokemon_base_stats_list())
|
|
|
|
"""
|
|
struct base_stat_values_t {
|
|
uint8_t hit_points;
|
|
uint8_t attack;
|
|
uint8_t defense;
|
|
uint8_t speed;
|
|
uint8_t special;
|
|
};
|
|
|
|
struct level_move_t {
|
|
uint8_t level;
|
|
enum move_t::move move;
|
|
};
|
|
|
|
struct evolution_t {
|
|
enum type {
|
|
item,
|
|
level,
|
|
trade
|
|
};
|
|
|
|
enum type type;
|
|
uint8_t item; // fixme
|
|
uint8_t level;
|
|
enum pokemon_t::pokemon pokemon;
|
|
};
|
|
|
|
struct pokemon_t {
|
|
base_stat_values_t stat_values;
|
|
type_t types[2];
|
|
uint8_t catch_rate;
|
|
uint8_t base_exp;
|
|
uint8_t growth_rate;
|
|
struct {
|
|
uint8_t front;
|
|
uint8_t back;
|
|
} pics;
|
|
struct {
|
|
level_move_t * moves;
|
|
uint8_t length;
|
|
} by_level;
|
|
struct {
|
|
enum move_t::move * moves;
|
|
uint8_t length;
|
|
} by_tmhm;
|
|
struct {
|
|
evolution_t * evolution; // might be null
|
|
uint8_t length;
|
|
} evolutions;
|
|
};
|
|
|
|
[pokemon_t::pidgey] = {
|
|
.base_stat_values = {10, 15, 20, 42, 66},
|
|
.types = {type_t::normal, type_t::flying},
|
|
.catch_rate = 80,
|
|
.base_exp = 100,
|
|
.growth_rate = 0, // fixme
|
|
.pics = {
|
|
.front = 0, // fixme
|
|
.back = 0, // fixme
|
|
},
|
|
.by_level = {
|
|
.moves = {
|
|
{
|
|
.level = 1,
|
|
.move = move_t::peck,
|
|
},
|
|
},
|
|
.length = 1,
|
|
},
|
|
.by_tmhm = {
|
|
.moves = {
|
|
move_t::surf,
|
|
},
|
|
.length = 1,
|
|
},
|
|
.evolutions = {
|
|
.evolutions = {
|
|
.type = pokemon_t::evolution_t::level,
|
|
.required_item = 0, // fixme
|
|
.required_level = 10,
|
|
.pokemon = pokemon_t::pidgeotto,
|
|
},
|
|
.length = 1,
|
|
},
|
|
};
|
|
"""
|
|
|
|
def dex_constant_to_enum_name(dex_constant):
|
|
assert dex_constant.startswith("DEX_")
|
|
name = dex_constant.removeprefix("DEX_")
|
|
return name.lower()
|
|
|
|
def enum_inc():
|
|
yield "enum pokemon {"
|
|
for dex_constant in parse.pokemon_dex_constants_list():
|
|
name = dex_constant_to_enum_name(dex_constant)
|
|
yield f"{name.lower()},"
|
|
yield "};"
|
|
|
|
def generate_enum_inc():
|
|
render, out = renderer()
|
|
render(enum_inc())
|
|
return out
|
|
|
|
def level_move(level, move):
|
|
return [
|
|
"{",
|
|
f".level = {level},",
|
|
f".move = move_t::{move.lower()},",
|
|
"},",
|
|
]
|
|
|
|
def moves_by_level(level_1_learnset, learnset):
|
|
"""
|
|
level_1_learnset=('TACKLE', 'GROWL', 'NO_MOVE', 'NO_MOVE')
|
|
learnset=[(7, 'LEECH_SEED'),
|
|
(13, 'VINE_WHIP'),
|
|
(20, 'POISONPOWDER'),
|
|
(27, 'RAZOR_LEAF'),
|
|
(34, 'GROWTH'),
|
|
(41, 'SLEEP_POWDER'),
|
|
(48, 'SOLARBEAM')]
|
|
"""
|
|
|
|
_learnset = [(1, s) for s in level_1_learnset
|
|
if s != 'NO_MOVE'] + learnset
|
|
|
|
return [
|
|
".by_level = {",
|
|
".moves = (level_move_t[]){",
|
|
*chain.from_iterable(starmap(level_move, _learnset)),
|
|
"},",
|
|
f".length = {len(_learnset)},",
|
|
"},",
|
|
]
|
|
|
|
def moves_by_tmhm(tmhm):
|
|
moves = [
|
|
f"move_t::{move.lower()},"
|
|
for move in tmhm
|
|
if move != 'UNUSED'
|
|
]
|
|
return [
|
|
".by_tmhm = {",
|
|
".moves = (enum move_t::move[]){",
|
|
*moves,
|
|
"},",
|
|
f".length = {len(moves)},",
|
|
"},"
|
|
]
|
|
|
|
def evolution(ev):
|
|
type, _item_name, level, pokemon_name = ev
|
|
assert type.startswith('EV_')
|
|
type = type.removeprefix('EV_').lower()
|
|
return [
|
|
"{",
|
|
f".type = pokemon_t::evolution_t::{type},",
|
|
".required_item = 0, // fixme",
|
|
f".required_level = {level},",
|
|
f".pokemon = pokemon_t::{pokemon_name.lower()},",
|
|
"},",
|
|
]
|
|
|
|
def evolutions(evs):
|
|
return [
|
|
".evolutions = {",
|
|
".evolution = (pokemon_t::evolution_t[]){",
|
|
*chain.from_iterable(evolution(ev) for ev in evs),
|
|
"},",
|
|
f".length = {len(evs)},",
|
|
"},",
|
|
]
|
|
|
|
def stat_values(stat_values):
|
|
return [
|
|
f".hit_points = {stat_values.hit_points},",
|
|
f".attack = {stat_values.attack},",
|
|
f".defense = {stat_values.defense},",
|
|
f".speed = {stat_values.speed},",
|
|
f".special = {stat_values.special},",
|
|
]
|
|
|
|
def pic_path(path):
|
|
assert path.endswith('.pic')
|
|
return f"{path.removesuffix('.pic')}.2bpp"
|
|
|
|
def pics(pic_front_back):
|
|
front, back = pic_front_back
|
|
front_path = pic_path(parse.pic_list()[front])
|
|
back_path = pic_path(parse.pic_list()[back])
|
|
return [
|
|
".front = {",
|
|
*start_size_value(front_path),
|
|
"},",
|
|
".back = {",
|
|
*start_size_value(back_path),
|
|
"},",
|
|
]
|
|
|
|
def growth_name(growth_constant):
|
|
assert growth_constant.startswith('GROWTH_')
|
|
growth_rate = growth_constant.removeprefix('GROWTH_')
|
|
return growth_rate.lower()
|
|
|
|
def dex_constant_name_to_constant_index(dex_constant_name):
|
|
return parse.pokemon_dex_order_list().index(dex_constant_name)
|
|
|
|
def pokemon(base_stats, evos_moves):
|
|
constant_index = dex_constant_name_to_constant_index(base_stats.pokedex_id)
|
|
pokemon_name = parse.pokemon_names_list()[constant_index]
|
|
enum_name = dex_constant_to_enum_name(base_stats.pokedex_id)
|
|
types = ", ".join(
|
|
f"type_t::{type.lower()}"
|
|
for type in base_stats.types
|
|
)
|
|
growth_rate = growth_name(base_stats.growth_rate)
|
|
return [
|
|
f"[pokemon_t::{enum_name}] = {{",
|
|
f'.name = reinterpret_cast<const uint8_t *>("{pokemon_name}"),',
|
|
".base_stat_values = {",
|
|
*stat_values(base_stats.stat_values),
|
|
"},",
|
|
f".types = {{{types}}},",
|
|
f".catch_rate = {base_stats.catch_rate},",
|
|
f".base_exp = {base_stats.base_exp},",
|
|
f".growth_rate = growth_t::{growth_rate},",
|
|
".pic = {",
|
|
*pics(base_stats.pic_front_back),
|
|
"},",
|
|
*moves_by_level(base_stats.level_1_learnset, evos_moves.learnset),
|
|
*moves_by_tmhm(base_stats.tmhm),
|
|
*evolutions(evos_moves.evolutions),
|
|
"},"
|
|
]
|
|
|
|
def evos_moves(constant_index):
|
|
evos_moves_list = parse.pokemon_evos_moves_list()
|
|
pointer_table = evos_moves_list[0]
|
|
evos_moves = evos_moves_list[1:]
|
|
by_label = {em.label: em for em in evos_moves}
|
|
return by_label[pointer_table[constant_index]]
|
|
|
|
def base_stats_by_dex_id():
|
|
by_dex_id = {
|
|
base_stat.pokedex_id: base_stat
|
|
for base_stat in parse.pokemon_base_stats_list()
|
|
}
|
|
assert len(by_dex_id) == len(parse.pokemon_base_stats_list())
|
|
return by_dex_id
|
|
|
|
def pokemon_initializers():
|
|
by_dex_id = base_stats_by_dex_id()
|
|
for dex_constant_name in parse.pokemon_dex_constants_list():
|
|
base_stats = by_dex_id[dex_constant_name]
|
|
constant_index = dex_constant_name_to_constant_index(dex_constant_name)
|
|
yield from pokemon(base_stats, evos_moves(constant_index))
|
|
|
|
def source_includes():
|
|
yield "#include <cstdint>"
|
|
yield ""
|
|
yield '#include "../../pokemon.hpp"'
|
|
yield ""
|
|
for dex_constant_name in parse.pokemon_dex_constants_list():
|
|
by_dex_id = base_stats_by_dex_id()
|
|
base_stats = by_dex_id[dex_constant_name]
|
|
front, back = base_stats.pic_front_back
|
|
front_path = pic_path(parse.pic_list()[front])
|
|
back_path = pic_path(parse.pic_list()[back])
|
|
yield f'#include "../../res/{front_path}.h"'
|
|
yield f'#include "../../res/{back_path}.h"'
|
|
yield ""
|
|
|
|
def pokemon_source():
|
|
yield "const pokemon_t pokemon[] = {"
|
|
yield from pokemon_initializers()
|
|
yield "};"
|
|
|
|
def generate_source():
|
|
render, out = renderer()
|
|
render(source_includes())
|
|
render(pokemon_source())
|
|
return out
|