diff --git a/pokedex/struct/__init__.py b/pokedex/struct/__init__.py index 5876fe5..89469c0 100644 --- a/pokedex/struct/__init__.py +++ b/pokedex/struct/__init__.py @@ -265,7 +265,6 @@ class SaveFilePokemon(object): trainer['name'].strip('\0') or trainer['gender'] != 'male'): result['oiginal trainer'] = trainer - save(result, 'exp') save(result, 'happiness') save(result, 'original country') save(result, 'original version') @@ -274,6 +273,10 @@ class SaveFilePokemon(object): save(result, 'fateful encounter') save(result, 'personality') + save(result, 'level') + if self.exp != self.experience_rung.experience: + save(result, 'exp') + save(result, 'markings', transform=sorted) save(result, 'encounter type', condition=lambda et: (et and et != 'special')) @@ -420,6 +423,12 @@ class SaveFilePokemon(object): gender='gender', personality='personality', ) + if 'level' in dct: + if 'exp' in dct: + if self.level != dct['level']: + raise ValueError('level and exp not compatible') + else: + self.level = dct['level'] load_name('nickname', dct, 'nickname', 'nickname trash') if 'nicknamed' in dct: self.is_nicknamed = dct['nicknamed'] @@ -656,6 +665,14 @@ class SaveFilePokemon(object): def level(self): return self.experience_rung.level + @level.setter + def level(self, level): + growth_rate = self.species.growth_rate + self.exp = (self.session.query(tables.Experience) + .filter(tables.Experience.growth_rate == growth_rate) + .filter(tables.Experience.level == level) + .one().experience) + @cached_property def experience_rung(self): growth_rate = self.species.growth_rate diff --git a/pokedex/tests/test_struct.py b/pokedex/tests/test_struct.py index 6107c2c..ef37fec 100644 --- a/pokedex/tests/test_struct.py +++ b/pokedex/tests/test_struct.py @@ -36,6 +36,7 @@ def voltorb_and_dict(): expected = { 'gender': 'male', 'species': dict(id=100, name=u'Voltorb'), + 'level': 1, 'nickname': u'\0' * 11, 'nicknamed': False, 'nickname trash': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==', @@ -132,25 +133,48 @@ def test_nickname(use_update): @positional_params([True], [False]) def test_experience(use_update): pkmn, expected = voltorb_and_dict() - exp = 2340 + for exp in 2197, 2200: + if use_update: + pkmn.update(exp=exp) + else: + pkmn.exp = exp + assert pkmn.exp == exp + assert pkmn.experience_rung.experience <= pkmn.exp + assert pkmn.next_experience_rung.experience > pkmn.exp + assert pkmn.experience_rung.level + 1 == pkmn.next_experience_rung.level + assert (pkmn.experience_rung.growth_rate == + pkmn.next_experience_rung.growth_rate == + pkmn.species.growth_rate) + assert pkmn.level == pkmn.experience_rung.level + assert pkmn.exp_to_next == pkmn.next_experience_rung.experience - pkmn.exp + rung_difference = (pkmn.next_experience_rung.experience - + pkmn.experience_rung.experience) + assert pkmn.progress_to_next == ( + pkmn.exp - pkmn.experience_rung.experience) / float(rung_difference) + if exp == 2197: + expected['level'] = 13 + else: + expected['exp'] = exp + expected['level'] = 13 + check_with_roundtrip(5, pkmn, expected) + +def test_update_inconsistent_exp_level(): + pkmn, expected = voltorb_and_dict() + with pytest.raises(ValueError): + pkmn.update(exp=0, level=100) + +@positional_params([True], [False]) +def test_level(use_update): + pkmn, expected = voltorb_and_dict() + level = 10 if use_update: - pkmn.update(exp=exp) + pkmn.update(level=level) else: - pkmn.exp = exp - assert pkmn.exp == exp - assert pkmn.experience_rung.experience < pkmn.exp - assert pkmn.next_experience_rung.experience > pkmn.exp - assert pkmn.experience_rung.level + 1 == pkmn.next_experience_rung.level - assert (pkmn.experience_rung.growth_rate == - pkmn.next_experience_rung.growth_rate == - pkmn.species.growth_rate) - assert pkmn.level == pkmn.experience_rung.level - assert pkmn.exp_to_next == pkmn.next_experience_rung.experience - pkmn.exp - rung_difference = (pkmn.next_experience_rung.experience - - pkmn.experience_rung.experience) - assert pkmn.progress_to_next == ( - pkmn.exp - pkmn.experience_rung.experience) / float(rung_difference) - expected['exp'] = exp + pkmn.level = level + assert pkmn.level == level + assert pkmn.experience_rung.level == level + assert pkmn.experience_rung.experience == pkmn.exp + expected['level'] = level check_with_roundtrip(5, pkmn, expected) @positional_params([True], [False]) @@ -170,7 +194,6 @@ def test_squirtle_blob(): expected = { 'ability': {'id': 44, 'name': u'Rain Dish'}, 'date met': '2010-10-14', - 'exp': 560, 'gender': 'male', 'genes': {u'attack': 31, u'defense': 27, @@ -179,6 +202,7 @@ def test_squirtle_blob(): u'special defense': 3, u'speed': 7}, 'happiness': 70, + 'level': 10, 'met at level': 10, 'met location': {'id_dp': 75, 'name': u'Spring Path'}, 'moves': [{'id': 33, 'name': u'Tackle', 'pp': 35},