pokeplatinum/tools/json2bin/evo.py

133 lines
4.3 KiB
Python

#!/usr/bin/env python3
from collections.abc import Sequence
import pathlib
import json2bin as j2b
from consts import (
items,
moves,
pokemon,
species
)
def get_evo_params(method: pokemon.PokemonEvoMethod, evo: Sequence):
maybe_param = evo[1]
final_param = 0
#None of these take an extra parameter
if method in set([
pokemon.PokemonEvoMethod.EVO_NONE,
pokemon.PokemonEvoMethod.EVO_HAPPINESS,
pokemon.PokemonEvoMethod.EVO_HAPPINESS_DAY,
pokemon.PokemonEvoMethod.EVO_HAPPINESS_NIGHT,
pokemon.PokemonEvoMethod.EVO_TRADE,
pokemon.PokemonEvoMethod.EVO_ELECTRIC_FIELD,
pokemon.PokemonEvoMethod.EVO_MOSSY_STONE,
pokemon.PokemonEvoMethod.EVO_ICY_STONE]):
final_param = 0
# These all specify a basic integer param
elif method in set([
pokemon.PokemonEvoMethod.EVO_LEVEL_UP,
pokemon.PokemonEvoMethod.EVO_LEVEL_ATK_GT_DEF,
pokemon.PokemonEvoMethod.EVO_LEVEL_ATK_EQ_DEF,
pokemon.PokemonEvoMethod.EVO_LEVEL_ATK_LT_DEF,
pokemon.PokemonEvoMethod.EVO_LEVEL_PID_LOW,
pokemon.PokemonEvoMethod.EVO_LEVEL_PID_HIGH,
pokemon.PokemonEvoMethod.EVO_LEVEL_NINJASK,
pokemon.PokemonEvoMethod.EVO_LEVEL_SHEDINJA,
pokemon.PokemonEvoMethod.EVO_LEVEL_MALE,
pokemon.PokemonEvoMethod.EVO_LEVEL_FEMALE,
pokemon.PokemonEvoMethod.EVO_BEAUTY]):
final_param = maybe_param
# These specify an item
elif method in set([
pokemon.PokemonEvoMethod.EVO_TRADE_WITH_ITEM,
pokemon.PokemonEvoMethod.EVO_USE_ITEM,
pokemon.PokemonEvoMethod.EVO_USE_ITEM_MALE,
pokemon.PokemonEvoMethod.EVO_USE_ITEM_FEMALE,
pokemon.PokemonEvoMethod.EVO_USE_ITEM_DAY,
pokemon.PokemonEvoMethod.EVO_USE_ITEM_NIGHT]):
final_param = items.Item[maybe_param].value
elif method == pokemon.PokemonEvoMethod.EVO_KNOW_MOVE:
final_param = moves.Move[maybe_param].value
elif method == pokemon.PokemonEvoMethod.EVO_MON_IN_PARTY:
final_param = species.PokemonSpecies[maybe_param].value
return final_param
def table_line(evo_method: int, evo_params: int, species: int) -> bytes:
binary = bytearray([])
binary.extend(evo_method.to_bytes(2, 'little'))
binary.extend(evo_params.to_bytes(2, 'little'))
binary.extend(species.to_bytes(2, 'little'))
return bytes(binary)
def parse_evolutions(table: Sequence, _size: int, _enum: None) -> bytes:
out = bytearray([])
for j in range(min(len(table), 7)):
evo = table[j]
method = pokemon.PokemonEvoMethod[evo[0]]
params = get_evo_params(method, evo)
target = species.PokemonSpecies[evo[-1]]
out.extend(table_line(method.value, params, target.value))
out.extend((0).to_bytes(44 - len(out), 'little'))
return out
SCHEMA = j2b.Parser() \
.register('evolutions', 44, parse_evolutions, optional=j2b.OptionalBehavior.PAD)
NATIONAL_DEX_COUNT = 493
FORM_INDICES = {
'DEOXYS' : {
'ATTACK': NATIONAL_DEX_COUNT + 3,
'DEFENSE': NATIONAL_DEX_COUNT + 4,
'SPEED': NATIONAL_DEX_COUNT + 5,
},
'WORMADAM': {
'SANDY': NATIONAL_DEX_COUNT + 6,
'TRASH': NATIONAL_DEX_COUNT + 7,
},
'GIRATINA': {
'ORIGIN': NATIONAL_DEX_COUNT + 8,
},
'SHAYMIN': {
'SKY': NATIONAL_DEX_COUNT + 9,
},
'ROTOM': {
'HEAT': NATIONAL_DEX_COUNT + 10,
'WASH': NATIONAL_DEX_COUNT + 11,
'FROST': NATIONAL_DEX_COUNT + 12,
'FAN': NATIONAL_DEX_COUNT + 13,
'MOW': NATIONAL_DEX_COUNT + 14,
},
}
def indexer(file_path: pathlib.Path) -> int:
name = file_path.parent.stem.upper()
if name == '000': return 0
if name == 'egg': return NATIONAL_DEX_COUNT + 1
if name == 'bad_egg': return NATIONAL_DEX_COUNT + 2
if file_path.parent.parent.stem == 'forms':
species_idx = file_path.parent.parent.parent.stem.upper()
form = file_path.parent.stem.upper()
return FORM_INDICES[species_idx][form]
return species.PokemonSpecies[f'SPECIES_{name}'].value
args = j2b.ARGPARSER.parse_args()
j2b.json2bin(args.source_dir,
SCHEMA,
args.private_dir,
args.output_dir,
indexer,
glob_pattern='**/data.json',
narc_name='evo',
narc_packer=args.knarc)