veekun_pokedex/scripts/gen_iii_tutors.py

87 lines
2.7 KiB
Python
Raw Permalink Normal View History

2012-11-12 22:49:27 +00:00
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