Implement writing localized properties through a wrapper object

This commit is contained in:
Eevee (Lexy Munroe) 2016-09-16 17:00:12 -07:00
parent 1cff16f256
commit 6c135e559e
2 changed files with 41 additions and 35 deletions

View file

@ -1601,18 +1601,35 @@ def bitfield_to_machines(bits, machine_moves):
return machines return machines
# TODO this is not correctly using my half-baked "slice" idea
class WriterWrapper: class WriterWrapper:
def __init__(self, locus, language): def __init__(self, locus, language):
self.locus = locus self.__dict__.update(dict(
self.language = language locus=locus,
language=language,
))
def __setattr__(self, key, value): def __setattr__(self, key, value):
# TODO finish this... # TODO yeah this is fucking ludicrous
# 1. disallow reassigning an existing attr with a value attr = type(self.locus).__dict__[key]
setattr(self.locus, key, value) # TODO i think my descriptor stuff needs some work here if i have to root around in __dict__
if isinstance(attr, schema._Localized):
if key not in self.locus.__dict__:
langdict = {}
setattr(self.locus, key, langdict)
else:
langdict = getattr(self.locus, key)
langdict[self.language] = value
else:
if key in self.locus.__dict__:
oldvalue = getattr(self.locus, key)
if value != oldvalue:
raise ValueError(
"Trying to set {!r}'s {} to {!r}, but it already "
"has a different value: {!r}"
.format(self.locus, key, value, oldvalue))
def __getattr__(self, key): setattr(self.locus, key, value)
return getattr(self.locus, key)
def main(base_root): def main(base_root):
@ -1661,16 +1678,11 @@ def main(base_root):
for id in range(cart.NUM_POKEMON): for id in range(cart.NUM_POKEMON):
pokemon = pokemons[POKEMON_IDENTIFIERS[id + 1]] pokemon = pokemons[POKEMON_IDENTIFIERS[id + 1]]
#writer = WriterWrapper(pokemon) writer = WriterWrapper(pokemon, language)
writer = pokemon
# TODO LOLLLL writer.name = cart.pokemon_names[id]
if 'name' not in writer.__dict__:
writer.name = {}
writer.name[cart.language] = cart.pokemon_names[id]
record = cart.pokemon_records[id] record = cart.pokemon_records[id]
# TODO put this in construct # TODO put this in construct
types = [record.type1] types = [record.type1]
if record.type1 != record.type2: if record.type1 != record.type2:
@ -1700,12 +1712,11 @@ def main(base_root):
level_up_moves.append({ level_up_moves.append({
level_up_move.level: level_up_move.move, level_up_move.level: level_up_move.move,
}) })
# TODO LOLLLL writer.moves = {
if 'moves' not in writer.__dict__: 'level-up': level_up_moves,
writer.moves = {} 'machines': bitfield_to_machines(
writer.moves['level-up'] = level_up_moves record.machines, cart.machine_moves),
writer.moves['machines'] = bitfield_to_machines( }
record.machines, cart.machine_moves)
# Evolution # Evolution
# TODO alas, the species here is a number, because it's an # TODO alas, the species here is a number, because it's an
@ -1724,13 +1735,8 @@ def main(base_root):
# Pokédex flavor # Pokédex flavor
flavor_struct = cart.pokedex_entries[id] flavor_struct = cart.pokedex_entries[id]
# TODO LOLLLL writer.genus = flavor_struct.genus.decrypt(language)
if 'genus' not in writer.__dict__: writer.flavor_text = flavor_struct.flavor_text.decrypt(language)
writer.genus = {}
writer.genus[cart.language] = flavor_struct.genus.decrypt(language)
if 'flavor_text' not in writer.__dict__:
writer.flavor_text = {}
writer.flavor_text[cart.language] = flavor_struct.flavor_text.decrypt(language)
if cart.uses_metric: if cart.uses_metric:
writer.height = 1000 * flavor_struct.height_decimeters writer.height = 1000 * flavor_struct.height_decimeters
writer.weight = 100000000 * flavor_struct.weight_hectograms writer.weight = 100000000 * flavor_struct.weight_hectograms

View file

@ -128,7 +128,7 @@ class Locus(metaclass=LocusMeta):
def __repr__(self): def __repr__(self):
return "<{}: {}>".format( return "<{}: {}>".format(
type(self).__qualname__, type(self).__qualname__,
self.identifier, '???', # TODO where is self.identifier assigned when writing?
) )
@ -160,9 +160,8 @@ Pokedex = _ForwardDeclaration()
class Pokémon(VersionedLocus): class Pokémon(VersionedLocus):
# TODO version, language. but those are kind of meta-fields; do they need # TODO version, language. but those are kind of meta-fields; do they need
# treating specially? # treating specially?
# TODO in old games, names are unique per game; in later games, they differ
# per language. what do i do about that? name = _Localized(str)
name = _Value(str)
types = _List(Type, min=1, max=2) types = _List(Type, min=1, max=2)
base_stats = _Map(Stat, int) base_stats = _Map(Stat, int)
@ -174,8 +173,8 @@ class Pokémon(VersionedLocus):
# TODO family? # TODO family?
evolutions = _List(Evolution) evolutions = _List(Evolution)
genus = _Value(str) genus = _Localized(str)
flavor_text = _Value(str) flavor_text = _Localized(str)
# TODO maybe want little wrapper types that can display as either imperial # TODO maybe want little wrapper types that can display as either imperial
# or metric # or metric
# TODO maybe also dump as metric rather than plain numbers # TODO maybe also dump as metric rather than plain numbers
@ -184,13 +183,14 @@ class Pokémon(VersionedLocus):
# both metric and imperial values as integers with no loss of precision: # both metric and imperial values as integers with no loss of precision:
# myriameters (tenths of a millimeter) and micrograms. # myriameters (tenths of a millimeter) and micrograms.
# Divide by 100 for centimeters, or by 254 for inches # Divide by 100 for centimeters, or by 254 for inches
height = _Value(int) height = _Localized(int)
# Divide by one billion for kilograms, or by 453592370 for pounds # Divide by one billion for kilograms, or by 453592370 for pounds
weight = _Value(int) weight = _Localized(int)
# TODO this belongs to a place, not to a pokemon # TODO this belongs to a place, not to a pokemon
#encounters = _Value(EncounterMap) #encounters = _Value(EncounterMap)
# TODO having a custom type here is handy, but it's not a locus
moves = _Value(MoveSet) moves = _Value(MoveSet)
# TODO should this be written in hex, maybe? # TODO should this be written in hex, maybe?