mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
|
from struct import Struct
|
||
|
from sys import argv
|
||
|
|
||
|
max_pokemon = 411 # Gen III indices are a Gen-I-esque mess past Celebi
|
||
|
|
||
|
# I got the first fifteen from FR by looking at tutor NPCs' scripts. I got the
|
||
|
# full list from Emerald by searching for the first fifteen; the list starts at
|
||
|
# 0x61500C.
|
||
|
moves = ['mega-punch', 'swords-dance', 'mega-kick', 'body-slam', 'double-edge',
|
||
|
'counter', 'seismic-toss', 'mimic', 'metronome', 'softboiled',
|
||
|
'dream-eater', 'thunder-wave', 'explosion', 'rock-slide', 'substitute',
|
||
|
|
||
|
# Emerald only
|
||
|
'dynamicpunch', 'rollout', 'psych-up', 'snore', 'icy-wind', 'endure',
|
||
|
'mud-slap', 'ice-punch', 'swagger', 'sleep-talk', 'swift', 'defense-curl',
|
||
|
'thunderpunch', 'fire-punch', 'fury-cutter']
|
||
|
|
||
|
query_template = """
|
||
|
insert into pokemon_moves (pokemon_id, version_group_id, move_id,
|
||
|
pokemon_move_method_id, level, "order") values (
|
||
|
(select pokemon_id from pokemon_game_indices where version_id={version}
|
||
|
and game_index={game_index}),
|
||
|
{version_group},
|
||
|
(select id from moves where identifier='{move}'),
|
||
|
3, 0, null
|
||
|
);
|
||
|
"""
|
||
|
|
||
|
version_constants = {
|
||
|
'POKEMON FIRE': {
|
||
|
'version_id': 10,
|
||
|
'version_group_id': 7,
|
||
|
'offset': 0x459B80,
|
||
|
'moves': 15
|
||
|
},
|
||
|
|
||
|
'POKEMON LEAF': {
|
||
|
'version_id': 11,
|
||
|
'version_group_id': 7,
|
||
|
'offset': 0x4595A0,
|
||
|
'moves': 15
|
||
|
},
|
||
|
|
||
|
'POKEMON EMER': {
|
||
|
'version_id': 9,
|
||
|
'version_group_id': 6,
|
||
|
'offset': 0x61504C,
|
||
|
'moves': 30
|
||
|
}
|
||
|
}
|
||
|
|
||
|
with open(argv[1], 'rb') as rom:
|
||
|
rom.seek(0xA0)
|
||
|
version = rom.read(12).decode('ASCII')
|
||
|
stuff = version_constants[version]
|
||
|
|
||
|
# Flags go from least significant bit to most significant, and then to the
|
||
|
# next byte, just like TMs, but there are few enough of them that we can
|
||
|
# treat the whole field as a little-endian int.
|
||
|
if stuff['moves'] == 15:
|
||
|
flag_struct = Struct('<H')
|
||
|
else:
|
||
|
flag_struct = Struct('<L')
|
||
|
|
||
|
rom.seek(stuff['offset'])
|
||
|
|
||
|
# For LeafGreen, we want to skip straight to Defense Deoxys.
|
||
|
if version == 'POKEMON LEAF':
|
||
|
ids = [410]
|
||
|
rom.seek(2 * 409, 1)
|
||
|
else:
|
||
|
ids = range(1, max_pokemon + 1)
|
||
|
|
||
|
for pokemon in ids:
|
||
|
# Read the flags
|
||
|
flags, = flag_struct.unpack(rom.read(flag_struct.size))
|
||
|
for move in range(stuff['moves']):
|
||
|
if flags & 1:
|
||
|
# This Pokémon learns this move! Dump an SQL insert.
|
||
|
print(query_template.format(
|
||
|
version=stuff['version_id'],
|
||
|
game_index=pokemon,
|
||
|
version_group=stuff['version_group_id'],
|
||
|
move=moves[move],
|
||
|
))
|
||
|
flags >>= 1
|