Avoid performance hit in Gen1PlayerPokemonStorage

Make it possible for Gen1PlayerPokemonStorages' Gen1Party and Gen1Box to
avoid the performance hit in ::getPokemon caused by the recalculation of
the pokemons' level. This recalculation would read the pokemon stats
datastructure, which could be slow on the N64 transfer pak.
This commit is contained in:
Philippe Symons 2024-07-23 23:40:19 +02:00
parent 4fc77f27af
commit 2adbacf43b
2 changed files with 19 additions and 9 deletions

View File

@ -24,7 +24,7 @@ public:
/**
* Reads the pokemon data structure at the specified partyIndex
*/
bool getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPokemon);
bool getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPokemon, bool shouldRecalculateLevel = true);
/**
* Overwrites the pokemon data structure at the specified partyIndex
*/
@ -56,7 +56,7 @@ public:
* Gets the pokemon species index at the given index within the box
*/
uint8_t getSpeciesAtIndex(uint8_t index);
bool getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon);
bool getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon, bool shouldRecalculateLevel = true);
bool setPokemon(uint8_t index, Gen1TrainerPokemon& poke);
uint8_t getNumberOfPokemon();
uint8_t getMaxNumberOfPokemon();

View File

@ -210,7 +210,7 @@ uint8_t Gen1Party::getSpeciesAtIndex(uint8_t partyIndex)
return partyMeta.species_index_list[partyIndex];
}
bool Gen1Party::getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPokemon)
bool Gen1Party::getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPokemon, bool shouldRecalculateLevel)
{
Gen1PokeStats stats;
const uint8_t PARTY_POKEMON_NUM_BYTES = 44;
@ -221,7 +221,7 @@ bool Gen1Party::getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPok
readCommonPokeData(saveManager_, outTrainerPokemon);
// according to https://bulbapedia.bulbagarden.net/wiki/Pok%C3%A9mon_data_structure_(Generation_I)
// the level is stored a second time here for some reason. Ignore it.
// the level is stored a second time here for some reason.
saveManager_.advance();
saveManager_.readUint16(outTrainerPokemon.max_hp, Endianness::BIG);
@ -231,8 +231,13 @@ bool Gen1Party::getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPok
saveManager_.readUint16(outTrainerPokemon.special, Endianness::BIG);
// the level field above is kinda unreliable. the only reliable way is to base it on the exp field
gameReader_.readPokemonStatsForIndex(outTrainerPokemon.poke_index, stats);
outTrainerPokemon.level = getLevelForExp(outTrainerPokemon.exp, stats.growth_rate);
// doing the recalculation causes a performance hit though, because the stats data is being read.
// shouldRecalculateLevel == false lets you avoid this.
if(shouldRecalculateLevel)
{
gameReader_.readPokemonStatsForIndex(outTrainerPokemon.poke_index, stats);
outTrainerPokemon.level = getLevelForExp(outTrainerPokemon.exp, stats.growth_rate);
}
return true;
}
@ -408,7 +413,7 @@ uint8_t Gen1Box::getSpeciesAtIndex(uint8_t index)
return boxMeta.species_index_list[index];
}
bool Gen1Box::getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon)
bool Gen1Box::getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon, bool shouldRecalculateLevel)
{
Gen1PokeStats stats;
const uint8_t BOX_POKEMON_NUM_BYTES = 33;
@ -423,8 +428,13 @@ bool Gen1Box::getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon)
readCommonPokeData(saveManager_, outTrainerPokemon);
// the level field above is kinda unreliable. the only reliable way is to base it on the exp field
gameReader_.readPokemonStatsForIndex(outTrainerPokemon.poke_index, stats);
outTrainerPokemon.level = getLevelForExp(outTrainerPokemon.exp, stats.growth_rate);
// doing the recalculation causes a performance hit though, because the stats data is being read.
// shouldRecalculateLevel == false lets you avoid this.
if(shouldRecalculateLevel)
{
gameReader_.readPokemonStatsForIndex(outTrainerPokemon.poke_index, stats);
outTrainerPokemon.level = getLevelForExp(outTrainerPokemon.exp, stats.growth_rate);
}
return true;
}