mirror of
https://github.com/risingPhil/libpokemegb.git
synced 2026-03-21 17:44:24 -05:00
add setPokemon() function in Gen1PlayerPokemonStorage. This is useful for updating existing pokémon
This commit is contained in:
parent
747bdd4b4b
commit
77d5d152e9
|
|
@ -18,6 +18,7 @@ public:
|
|||
~Gen1Party();
|
||||
|
||||
bool getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon);
|
||||
bool setPokemon(uint8_t index, Gen1TrainerPokemon& poke);
|
||||
uint8_t getNumberOfPokemon();
|
||||
uint8_t getMaxNumberOfPokemon();
|
||||
const char* getPokemonNickname(uint8_t index);
|
||||
|
|
@ -41,6 +42,7 @@ public:
|
|||
~Gen1Box();
|
||||
|
||||
bool getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon);
|
||||
bool setPokemon(uint8_t index, Gen1TrainerPokemon& poke);
|
||||
uint8_t getNumberOfPokemon();
|
||||
uint8_t getMaxNumberOfPokemon();
|
||||
const char* getPokemonNickname(uint8_t index);
|
||||
|
|
|
|||
|
|
@ -224,6 +224,50 @@ bool Gen1Party::getPokemon(uint8_t partyIndex, Gen1TrainerPokemon& outTrainerPok
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Gen1Party::setPokemon(uint8_t partyIndex, Gen1TrainerPokemon& poke)
|
||||
{
|
||||
const uint8_t PARTY_POKEMON_NUM_BYTES = 44;
|
||||
const uint8_t FIRST_POKE_STRUCT_OFFSET = 8;
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
getPartyMetadata(saveManager_, partyMeta);
|
||||
|
||||
if(partyIndex >= partyMeta.number_of_pokemon)
|
||||
{
|
||||
// You can't use this function to add a pokemon. Only to replace one.
|
||||
return false;
|
||||
}
|
||||
|
||||
partyMeta.species_index_list[partyIndex] = poke.poke_index;
|
||||
|
||||
if(partyMeta.number_of_pokemon != getMaxNumberOfPokemon())
|
||||
{
|
||||
// we need to add a terminator
|
||||
partyMeta.species_index_list[partyMeta.number_of_pokemon] = 0xFF;
|
||||
}
|
||||
|
||||
writePartyMetadata(saveManager_, partyMeta);
|
||||
|
||||
// make sure the stat fields are filled in by recalculating them.
|
||||
// this is the same as what happens when withdrawing them from an ingame PC box
|
||||
gen1_recalculatePokeStats(gameReader_, poke);
|
||||
poke.current_hp = poke.max_hp;
|
||||
|
||||
saveManager_.seek(0x2F2C + FIRST_POKE_STRUCT_OFFSET + ((partyIndex)*PARTY_POKEMON_NUM_BYTES));
|
||||
writeCommonPokeData(saveManager_, poke);
|
||||
|
||||
// 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.
|
||||
saveManager_.writeByte(poke.level);
|
||||
|
||||
saveManager_.writeUint16(poke.max_hp, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.atk, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.def, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.speed, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.special, Endianness::BIG);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t Gen1Party::getNumberOfPokemon()
|
||||
{
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
|
|
@ -297,45 +341,28 @@ void Gen1Party::setOriginalTrainerOfPokemon(uint8_t partyIndex, const char* orig
|
|||
|
||||
bool Gen1Party::add(Gen1TrainerPokemon& poke, const char* originalTrainerID, const char* nickname)
|
||||
{
|
||||
const uint8_t PARTY_POKEMON_NUM_BYTES = 44;
|
||||
const uint8_t FIRST_POKE_STRUCT_OFFSET = 8;
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
getPartyMetadata(saveManager_, partyMeta);
|
||||
const uint8_t partyIndex = partyMeta.number_of_pokemon;
|
||||
|
||||
if(partyMeta.number_of_pokemon >= 6)
|
||||
if(partyIndex >= getMaxNumberOfPokemon())
|
||||
{
|
||||
// no room for this pokemon
|
||||
return false;
|
||||
}
|
||||
const uint8_t partyIndex = partyMeta.number_of_pokemon;
|
||||
partyMeta.species_index_list[partyIndex] = poke.poke_index;
|
||||
++partyMeta.number_of_pokemon;
|
||||
|
||||
if(partyMeta.number_of_pokemon != 6)
|
||||
if(partyMeta.number_of_pokemon != getMaxNumberOfPokemon())
|
||||
{
|
||||
// we need to add a terminator
|
||||
partyMeta.species_index_list[partyMeta.number_of_pokemon] = 0xFF;
|
||||
}
|
||||
|
||||
writePartyMetadata(saveManager_, partyMeta);
|
||||
|
||||
// make sure the stat fields are filled in by recalculating them.
|
||||
// this is the same as what happens when withdrawing them from an ingame PC box
|
||||
gen1_recalculatePokeStats(gameReader_, poke);
|
||||
poke.current_hp = poke.max_hp;
|
||||
|
||||
saveManager_.seek(0x2F2C + FIRST_POKE_STRUCT_OFFSET + ((partyIndex)*PARTY_POKEMON_NUM_BYTES));
|
||||
writeCommonPokeData(saveManager_, poke);
|
||||
|
||||
// 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.
|
||||
saveManager_.writeByte(poke.level);
|
||||
|
||||
saveManager_.writeUint16(poke.max_hp, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.atk, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.def, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.speed, Endianness::BIG);
|
||||
saveManager_.writeUint16(poke.special, Endianness::BIG);
|
||||
if(!setPokemon(partyIndex, poke))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// now store the original trainer string and name/nickname
|
||||
setOriginalTrainerOfPokemon(partyIndex, originalTrainerID);
|
||||
|
|
@ -376,6 +403,42 @@ bool Gen1Box::getPokemon(uint8_t index, Gen1TrainerPokemon& outTrainerPokemon)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Gen1Box::setPokemon(uint8_t index, Gen1TrainerPokemon& poke)
|
||||
{
|
||||
const uint8_t BOX_POKEMON_NUM_BYTES = 33;
|
||||
const uint8_t FIRST_POKE_STRUCT_OFFSET = 22;
|
||||
Gen1TrainerBoxMeta boxMeta;
|
||||
const uint8_t currentBoxIndex = gameReader_.getCurrentBoxIndex();
|
||||
getBoxMetadata(saveManager_, boxIndex_, currentBoxIndex, boxMeta);
|
||||
|
||||
if(index >= boxMeta.number_of_pokemon)
|
||||
{
|
||||
// You can't use this function to add a pokemon. Only to replace one.
|
||||
return false;
|
||||
}
|
||||
|
||||
boxMeta.species_index_list[index] = poke.poke_index;
|
||||
|
||||
writeBoxMetadata(saveManager_, boxIndex_, currentBoxIndex, boxMeta);
|
||||
|
||||
// make sure the stat fields are filled in by recalculating them.
|
||||
// this is the same as what happens when withdrawing them from an ingame PC box
|
||||
gen1_recalculatePokeStats(gameReader_, poke);
|
||||
poke.current_hp = poke.max_hp;
|
||||
|
||||
const uint8_t bankIndex = getGen1BoxBankIndex(boxIndex_, currentBoxIndex);
|
||||
const uint16_t boxOffset = getBoxBankOffset(boxIndex_, currentBoxIndex);
|
||||
saveManager_.seekToBankOffset(bankIndex, boxOffset + FIRST_POKE_STRUCT_OFFSET + (index * BOX_POKEMON_NUM_BYTES));
|
||||
|
||||
writeCommonPokeData(saveManager_, poke);
|
||||
|
||||
// now update the checksum. Note that this is NOT the only checksum that will need to be updated. There's also the whole bank checksum.
|
||||
// this needs to be updated by Gen1GameReader once it is done manipulating the boxes
|
||||
updateChecksum(currentBoxIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t Gen1Box::getNumberOfPokemon()
|
||||
{
|
||||
Gen1TrainerBoxMeta boxMeta;
|
||||
|
|
@ -465,40 +528,30 @@ void Gen1Box::setOriginalTrainerOfPokemon(uint8_t index, const char* originalTra
|
|||
|
||||
bool Gen1Box::add(Gen1TrainerPokemon& poke, const char* originalTrainerID, const char* nickname)
|
||||
{
|
||||
const uint8_t BOX_POKEMON_NUM_BYTES = 33;
|
||||
const uint8_t FIRST_POKE_STRUCT_OFFSET = 22;
|
||||
Gen1TrainerBoxMeta boxMeta;
|
||||
const uint8_t currentBoxIndex = gameReader_.getCurrentBoxIndex();
|
||||
getBoxMetadata(saveManager_, boxIndex_, currentBoxIndex, boxMeta);
|
||||
const uint8_t index = boxMeta.number_of_pokemon;
|
||||
|
||||
if(boxMeta.number_of_pokemon >= 6)
|
||||
if(index >= getMaxNumberOfPokemon())
|
||||
{
|
||||
// no room for this pokemon
|
||||
return false;
|
||||
}
|
||||
const uint8_t index = boxMeta.number_of_pokemon;
|
||||
const uint8_t bankIndex = getGen1BoxBankIndex(boxIndex_, currentBoxIndex);
|
||||
const uint16_t boxOffset = getBoxBankOffset(boxIndex_, currentBoxIndex);
|
||||
|
||||
boxMeta.species_index_list[index] = poke.poke_index;
|
||||
++boxMeta.number_of_pokemon;
|
||||
|
||||
if(boxMeta.number_of_pokemon != 6)
|
||||
if(boxMeta.number_of_pokemon != getMaxNumberOfPokemon())
|
||||
{
|
||||
// we need to add a terminator
|
||||
boxMeta.species_index_list[boxMeta.number_of_pokemon] = 0xFF;
|
||||
}
|
||||
|
||||
// make sure the stat fields are filled in by recalculating them.
|
||||
// this is the same as what happens when withdrawing them from an ingame PC box
|
||||
gen1_recalculatePokeStats(gameReader_, poke);
|
||||
poke.current_hp = poke.max_hp;
|
||||
|
||||
writeBoxMetadata(saveManager_, boxIndex_, currentBoxIndex, boxMeta);
|
||||
|
||||
saveManager_.seekToBankOffset(bankIndex, boxOffset + FIRST_POKE_STRUCT_OFFSET + (index * BOX_POKEMON_NUM_BYTES));
|
||||
|
||||
writeCommonPokeData(saveManager_, poke);
|
||||
if(!setPokemon(index, poke))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// now store the original trainer string and name/nickname
|
||||
setOriginalTrainerOfPokemon(index, originalTrainerID);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user