mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Use helper function for saving
This commit is contained in:
parent
14ea7a0adf
commit
a2a63938a6
2 changed files with 83 additions and 99 deletions
|
@ -12,6 +12,7 @@ import struct
|
||||||
import base64
|
import base64
|
||||||
import datetime
|
import datetime
|
||||||
import contextlib
|
import contextlib
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
import sqlalchemy.orm.exc
|
import sqlalchemy.orm.exc
|
||||||
|
|
||||||
|
@ -219,19 +220,48 @@ class SaveFilePokemon(object):
|
||||||
"""
|
"""
|
||||||
st = self.structure
|
st = self.structure
|
||||||
|
|
||||||
def save_trash(result, name, string):
|
NO_VALUE = object()
|
||||||
|
def save(target_dict, key, value=NO_VALUE, transform=None,
|
||||||
|
condition=lambda x: x):
|
||||||
|
"""Set a dict key to a value, if a condition is true
|
||||||
|
|
||||||
|
If value is not given, it is looked up on self.
|
||||||
|
The value can be transformed by a function before setting.
|
||||||
|
"""
|
||||||
|
if value is NO_VALUE:
|
||||||
|
attrname = key.replace(' ', '_')
|
||||||
|
value = getattr(self, attrname)
|
||||||
|
if condition(value):
|
||||||
|
if transform:
|
||||||
|
value = transform(value)
|
||||||
|
target_dict[key] = value
|
||||||
|
|
||||||
|
def save_string(target_dict, string_key, trash_key, string):
|
||||||
|
"""Save a string, including trash bytes"""
|
||||||
|
target_dict[string_key] = unicode(string)
|
||||||
trash = getattr(string, 'original', None)
|
trash = getattr(string, 'original', None)
|
||||||
if trash:
|
if trash:
|
||||||
expected = (string + u'\uffff').encode('utf-16LE')
|
expected = (string + u'\uffff').encode('utf-16LE')
|
||||||
if trash.rstrip('\0') != expected:
|
if trash.rstrip('\0') != expected:
|
||||||
result[name] = base64.b64encode(trash)
|
target_dict[trash_key] = base64.b64encode(trash)
|
||||||
|
|
||||||
|
def save_object(target_dict, key, value=NO_VALUE, **extra):
|
||||||
|
"""Objects are represented as dicts with "name" and a bunch of IDs
|
||||||
|
|
||||||
|
The name is for humans. The ID is the number from the struct.
|
||||||
|
"""
|
||||||
|
save(target_dict, key, value=value, transform=lambda value:
|
||||||
|
dict(name=value.name, **extra))
|
||||||
|
|
||||||
result = dict(
|
result = dict(
|
||||||
species=dict(id=self.species.id, name=self.species.name),
|
species=dict(id=self.species.id, name=self.species.name),
|
||||||
)
|
)
|
||||||
ability = self.ability
|
if self.form != self.species.default_form:
|
||||||
if ability:
|
result['form'] = dict(id=st.form_id, name=self.form.form_name)
|
||||||
result['ability'] = dict(id=st.ability_id, name=ability.name)
|
|
||||||
|
save_object(result, 'ability', id=st.ability_id)
|
||||||
|
save_object(result, 'held item', id=st.held_item_id)
|
||||||
|
save_object(result, 'pokeball', id=st.dppt_pokeball or st.hgss_pokeball)
|
||||||
|
|
||||||
trainer = dict(
|
trainer = dict(
|
||||||
id=self.original_trainer_id,
|
id=self.original_trainer_id,
|
||||||
|
@ -239,86 +269,52 @@ class SaveFilePokemon(object):
|
||||||
name=unicode(self.original_trainer_name),
|
name=unicode(self.original_trainer_name),
|
||||||
gender=self.original_trainer_gender
|
gender=self.original_trainer_gender
|
||||||
)
|
)
|
||||||
save_trash(trainer, 'name trash', self.original_trainer_name)
|
save_string(trainer, 'name', 'name trash', self.original_trainer_name)
|
||||||
if (trainer['id'] or trainer['secret'] or
|
if (trainer['id'] or trainer['secret'] or
|
||||||
trainer['name'].strip('\0') or trainer['gender'] != 'male'):
|
trainer['name'].strip('\0') or trainer['gender'] != 'male'):
|
||||||
result['oiginal trainer'] = trainer
|
result['oiginal trainer'] = trainer
|
||||||
|
|
||||||
if self.form != self.species.default_form:
|
save(result, 'exp')
|
||||||
result['form'] = dict(id=st.form_id, name=self.form.form_name)
|
save(result, 'happiness')
|
||||||
if self.held_item:
|
save(result, 'markings', transform=sorted)
|
||||||
result['held item'] = dict(id=st.held_item_id, name=self.held_item.name)
|
save(result, 'original country')
|
||||||
if self.exp:
|
save(result, 'original version')
|
||||||
result['exp'] = self.exp
|
save(result, 'encounter type', condition=lambda et:
|
||||||
if self.happiness:
|
(et and et != 'special'))
|
||||||
result['happiness'] = self.happiness
|
save_string(result, 'nickname', 'nickname trash', self.nickname)
|
||||||
if self.markings:
|
save(result, 'egg received', self.date_egg_received,
|
||||||
result['markings'] = sorted(self.markings)
|
transform=lambda x: x.isoformat())
|
||||||
if self.original_country and self.original_country != '_unset':
|
save(result, 'date met',
|
||||||
result['original country'] = self.original_country
|
transform=lambda x: x.isoformat())
|
||||||
if self.original_version and self.original_version != '_unset':
|
save(result, 'pokerus data', self.pokerus)
|
||||||
result['original version'] = self.original_version
|
save(result, 'met at level')
|
||||||
if self.encounter_type and self.encounter_type != 'special':
|
save(result, 'nicknamed', self.is_nicknamed)
|
||||||
result['encounter type'] = self.encounter_type
|
save(result, 'is egg')
|
||||||
if self.nickname:
|
save(result, 'fateful encounter')
|
||||||
result['nickname'] = unicode(self.nickname)
|
save(result, 'personality')
|
||||||
save_trash(result, 'nickname trash', self.nickname)
|
save(result, 'gender', condition=lambda g: g != 'genderless')
|
||||||
if self.egg_location:
|
save(result, 'has hidden ability', self.hidden_ability)
|
||||||
result['egg location'] = dict(
|
save(result, 'ribbons',
|
||||||
id=st.pt_egg_location_id or st.dp_egg_location_id,
|
sorted(r.replace('_', ' ') for r in self.ribbons))
|
||||||
name=self.egg_location.name)
|
|
||||||
elif st.pt_egg_location_id or st.dp_egg_location_id:
|
|
||||||
result['egg location'] = dict(
|
|
||||||
id=st.pt_egg_location_id or st.dp_egg_location_id)
|
|
||||||
if st.dp_egg_location_id:
|
|
||||||
result['egg location slot'] = 'dp'
|
|
||||||
if self.met_location:
|
|
||||||
result['met location'] = dict(
|
|
||||||
id=st.pt_met_location_id or st.dp_met_location_id,
|
|
||||||
name=self.met_location.name)
|
|
||||||
elif st.pt_met_location_id or st.dp_met_location_id:
|
|
||||||
result['egg location'] = dict(
|
|
||||||
id=st.pt_met_location_id or st.dp_met_location_id)
|
|
||||||
if st.dp_met_location_id:
|
|
||||||
result['met location slot'] = 'dp'
|
|
||||||
if self.date_egg_received:
|
|
||||||
result['egg received'] = self.date_egg_received.isoformat()
|
|
||||||
if self.date_met:
|
|
||||||
result['date met'] = self.date_met.isoformat()
|
|
||||||
if self.pokerus:
|
|
||||||
result['pokerus data'] = self.pokerus
|
|
||||||
if self.pokeball:
|
|
||||||
result['pokeball'] = dict(
|
|
||||||
id=st.dppt_pokeball or st.hgss_pokeball,
|
|
||||||
name=self.pokeball.name)
|
|
||||||
if self.met_at_level:
|
|
||||||
result['met at level'] = self.met_at_level
|
|
||||||
|
|
||||||
if self.is_nicknamed:
|
for loc_type in 'egg', 'met':
|
||||||
result['nicknamed'] = True
|
loc_dict = dict()
|
||||||
if self.is_egg:
|
save(loc_dict, 'id_pt', st['pt_{0}_location_id'.format(loc_type)])
|
||||||
result['is egg'] = True
|
save(loc_dict, 'id_dp', st['dp_{0}_location_id'.format(loc_type)])
|
||||||
if self.fateful_encounter:
|
save(loc_dict, 'name',
|
||||||
result['fateful encounter'] = True
|
getattr(self, '{0}_location'.format(loc_type)),
|
||||||
if self.personality:
|
transform=attrgetter('name'))
|
||||||
result['personality'] = self.personality
|
save(result, '{0} location'.format(loc_type), loc_dict)
|
||||||
if self.gender != 'genderless':
|
|
||||||
result['gender'] = self.gender
|
|
||||||
|
|
||||||
if st.hidden_ability:
|
|
||||||
result['has hidden ability'] = st.hidden_ability
|
|
||||||
|
|
||||||
moves = result['moves'] = []
|
moves = result['moves'] = []
|
||||||
for i, move_object in enumerate(self.moves, 1):
|
for i, move_object in enumerate(self.moves, 1):
|
||||||
move = {}
|
move = {}
|
||||||
if move_object:
|
save(move, 'id', move_object, transform=attrgetter('id'))
|
||||||
move['id'] = move_object.id
|
save(move, 'name', move_object, transform=attrgetter('name'))
|
||||||
move['name'] = move_object.name
|
save(move, 'pp ups', st['move%s_pp_ups' % i])
|
||||||
move['pp'] = st['move%s_pp' % i]
|
pp = st['move%s_pp' % i]
|
||||||
pp_up = st['move%s_pp_ups' % i]
|
if move or pp:
|
||||||
if pp_up:
|
move['pp'] = pp
|
||||||
move['pp ups'] = pp_up
|
|
||||||
if move:
|
|
||||||
moves.append(move)
|
moves.append(move)
|
||||||
|
|
||||||
effort = {}
|
effort = {}
|
||||||
|
@ -332,16 +328,10 @@ class SaveFilePokemon(object):
|
||||||
effort[dct_stat_identifier] = st['effort_' + st_stat_identifier]
|
effort[dct_stat_identifier] = st['effort_' + st_stat_identifier]
|
||||||
for contest_stat in 'cool', 'beauty', 'cute', 'smart', 'tough', 'sheen':
|
for contest_stat in 'cool', 'beauty', 'cute', 'smart', 'tough', 'sheen':
|
||||||
contest_stats[contest_stat] = st['contest_' + contest_stat]
|
contest_stats[contest_stat] = st['contest_' + contest_stat]
|
||||||
if any(effort.values()):
|
save(result, 'effort', effort, condition=any)
|
||||||
result['effort'] = effort
|
save(result, 'genes', genes, condition=any)
|
||||||
if any(genes.values()):
|
save(result, 'contest stats', contest_stats, condition=any)
|
||||||
result['genes'] = genes
|
|
||||||
if any(contest_stats.values()):
|
|
||||||
result['contest stats'] = contest_stats
|
|
||||||
|
|
||||||
ribbons = sorted(r.replace('_', ' ') for r in self.ribbons)
|
|
||||||
if ribbons:
|
|
||||||
result['ribbons'] = ribbons
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def update(self, dct, **kwargs):
|
def update(self, dct, **kwargs):
|
||||||
|
@ -434,18 +424,14 @@ class SaveFilePokemon(object):
|
||||||
is_nicknamed='nicknamed',
|
is_nicknamed='nicknamed',
|
||||||
)
|
)
|
||||||
for loc_type in 'egg', 'met':
|
for loc_type in 'egg', 'met':
|
||||||
key = '{0} location'.format(loc_type)
|
loc_dict = dct.get('{0} location'.format(loc_type))
|
||||||
if key in dct:
|
if loc_dict:
|
||||||
dp_attr = 'dp_{0}_location_id'.format(loc_type)
|
dp_attr = 'dp_{0}_location_id'.format(loc_type)
|
||||||
pt_attr = 'pt_{0}_location_id'.format(loc_type)
|
pt_attr = 'pt_{0}_location_id'.format(loc_type)
|
||||||
if dct.get('{0} location slot'.format(loc_type)) == 'dp':
|
if 'id_dp' in loc_dict:
|
||||||
attr = dp_attr
|
st[dp_attr] = loc_dict['id_dp']
|
||||||
other_attr = pt_attr
|
if 'id_pt' in loc_dict:
|
||||||
else:
|
st[pt_attr] = loc_dict['id_pt']
|
||||||
attr = pt_attr
|
|
||||||
other_attr = dp_attr
|
|
||||||
st[attr] = dct[key]['id']
|
|
||||||
st[other_attr] = 0
|
|
||||||
delattr(self, '{0}_location'.format(loc_type))
|
delattr(self, '{0}_location'.format(loc_type))
|
||||||
if 'date met' in dct:
|
if 'date met' in dct:
|
||||||
self.date_met = datetime.datetime.strptime(
|
self.date_met = datetime.datetime.strptime(
|
||||||
|
@ -798,7 +784,6 @@ class SaveFilePokemon(object):
|
||||||
for ribbonset_name in (
|
for ribbonset_name in (
|
||||||
'sinnoh_ribbons', 'hoenn_ribbons', 'sinnoh_contest_ribbons'):
|
'sinnoh_ribbons', 'hoenn_ribbons', 'sinnoh_contest_ribbons'):
|
||||||
ribbonset = self.structure[ribbonset_name]
|
ribbonset = self.structure[ribbonset_name]
|
||||||
print ribbonset
|
|
||||||
for ribbon_name in ribbonset:
|
for ribbon_name in ribbonset:
|
||||||
ribbonset[ribbon_name] = (ribbon_name in ribbons)
|
ribbonset[ribbon_name] = (ribbon_name in ribbons)
|
||||||
ribbons.discard(ribbon_name)
|
ribbons.discard(ribbon_name)
|
||||||
|
@ -948,7 +933,8 @@ class SaveFilePokemonGen5(SaveFilePokemon):
|
||||||
if 'nature' in dct:
|
if 'nature' in dct:
|
||||||
self.structure.nature_id = dct['nature']['id']
|
self.structure.nature_id = dct['nature']['id']
|
||||||
if 'has hidden ability' not in dct:
|
if 'has hidden ability' not in dct:
|
||||||
self.hidden_ability = (self.pokemon.dream_ability == self.ability)
|
self.hidden_ability = (self.ability == self.pokemon.dream_ability
|
||||||
|
and self.ability not in self.pokemon.abilities)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def nature(self):
|
def nature(self):
|
||||||
|
|
|
@ -721,7 +721,6 @@ def make_pokemon_struct(generation):
|
||||||
Flag('circle'),
|
Flag('circle'),
|
||||||
),
|
),
|
||||||
LeakyEnum(ULInt8('original_country'),
|
LeakyEnum(ULInt8('original_country'),
|
||||||
_unset = 0,
|
|
||||||
jp=1,
|
jp=1,
|
||||||
us=2,
|
us=2,
|
||||||
fr=3,
|
fr=3,
|
||||||
|
@ -855,7 +854,6 @@ def make_pokemon_struct(generation):
|
||||||
PokemonStringAdapter(String('nickname', 22), 22),
|
PokemonStringAdapter(String('nickname', 22), 22),
|
||||||
Padding(1),
|
Padding(1),
|
||||||
LeakyEnum(ULInt8('original_version'),
|
LeakyEnum(ULInt8('original_version'),
|
||||||
_unset = 0,
|
|
||||||
sapphire = 1,
|
sapphire = 1,
|
||||||
ruby = 2,
|
ruby = 2,
|
||||||
emerald = 3,
|
emerald = 3,
|
||||||
|
|
Loading…
Reference in a new issue