Move the application of the GenXDistributionPokemon properties to separate functions

This allows us to use the genx_prepareDistributionPokemon() functions followed by GenXGameReader::addPokemon()
instead of GenXGameReader::addDistributionPokemon() in order to actually show the resulting GenXTrainerPokemon in
a stats screen in PokeMe64. After all: the genx_prepareDistributionPokemon() function does things like generate IV,
decide the trainer OT name and ID and apply shinyness chances.

So when showing the resulting pokemon in a stats screen, we need the actual resulting pokemon in order to show the right
stats, OT and shinyness
This commit is contained in:
Philippe Symons 2024-08-13 12:45:10 +02:00
parent 7b96cae992
commit 0fd91fb8e5
6 changed files with 100 additions and 75 deletions

View File

@ -4,6 +4,7 @@
#include "common.h"
class Gen1GameReader;
typedef struct Gen1DistributionPokemon Gen1DistributionPokemon;
enum class Gen1GameType
{
@ -118,4 +119,9 @@ uint16_t gen1_decodePokeText(const uint8_t* inputBuffer, uint16_t inputBufferLen
*/
uint16_t gen1_encodePokeText(const char* inputBuffer, uint16_t inputBufferLength, uint8_t* outputBuffer, uint16_t outputBufferLength, uint8_t terminator);
/**
* Prepares the gen 1 distribution pokemon for injection with Gen1GameReader::addPokemon()
*/
void gen1_prepareDistributionPokemon(Gen1GameReader& gameReader, const Gen1DistributionPokemon& distributionPoke, Gen1TrainerPokemon& poke, const char*& outTrainerName);
#endif

View File

@ -6,6 +6,8 @@
class Gen2GameReader;
class ISaveManager;
typedef struct Gen2DistributionPokemon Gen2DistributionPokemon;
// source: https://bulbapedia.bulbagarden.net/wiki/List_of_items_by_index_number_(Generation_II)
#define CRYSTAL_ITEM_ID_GS_BALL 0x73
@ -206,4 +208,9 @@ void gen2_makePokemonShiny(Gen2TrainerPokemon& poke);
const char* gen2_getItemListTypeString(Gen2ItemListType type);
/**
* Prepares the gen 2 distribution pokemon for injection with Gen2GameReader::addPokemon()
*/
void gen2_prepareDistributionPokemon(Gen2GameReader& gameReader, const Gen2DistributionPokemon& distributionPoke, Gen2TrainerPokemon& poke, const char*& outTrainerName);
#endif

View File

@ -4,6 +4,7 @@
#include "common.h"
#include <cstring>
#include <cstdlib>
#define POKEMON_BLUE_CARTRIDGE_TITLE "POKEMON BLUE"
#define POKEMON_RED_CARTRIDGE_TITLE "POKEMON RED"
@ -162,6 +163,40 @@ uint16_t gen1_encodePokeText(const char* inputBuffer, uint16_t inputBufferLength
return encodeText(gen1TextCodes, numEntries, inputBuffer, inputBufferLength, outputBuffer, outputBufferLength, terminator);
}
void gen1_prepareDistributionPokemon(Gen1GameReader& gameReader, const Gen1DistributionPokemon& distributionPoke, Gen1TrainerPokemon& poke, const char*& originalTrainerName)
{
if(distributionPoke.setPlayerAsOriginalTrainer)
{
originalTrainerName = gameReader.getTrainerName();
poke.original_trainer_ID = gameReader.getTrainerID();
}
else
{
originalTrainerName = distributionPoke.originalTrainer;
if(distributionPoke.regenerateTrainerID)
{
if(distributionPoke.originalTrainerID)
{
// limit set, apply it
poke.original_trainer_ID = (uint16_t)(rand() % distributionPoke.originalTrainerID);
}
else
{
// no limit. The max is the max of the uint16_t type
poke.original_trainer_ID =(uint16_t)(rand() % UINT16_MAX);
}
}
else
{
poke.original_trainer_ID = distributionPoke.originalTrainerID;
}
}
poke.iv_data[0] = distributionPoke.iv_data[0];
poke.iv_data[1] = distributionPoke.iv_data[1];
}
Gen1Checksum::Gen1Checksum()
: checksum_(0)
{

View File

@ -462,39 +462,10 @@ uint8_t Gen1GameReader::addPokemon(Gen1TrainerPokemon& poke, const char* origina
uint8_t Gen1GameReader::addDistributionPokemon(const Gen1DistributionPokemon& distributionPoke, const char* nickname)
{
Gen1TrainerPokemon poke = distributionPoke.poke;
const char* originalTrainerName;
if(distributionPoke.setPlayerAsOriginalTrainer)
{
originalTrainerName = getTrainerName();
poke.original_trainer_ID = getTrainerID();
}
else
{
originalTrainerName = distributionPoke.originalTrainer;
if(distributionPoke.regenerateTrainerID)
{
if(distributionPoke.originalTrainerID)
{
// limit set, apply it
poke.original_trainer_ID = (uint16_t)(rand() % distributionPoke.originalTrainerID);
}
else
{
// no limit. The max is the max of the uint16_t type
poke.original_trainer_ID =(uint16_t)(rand() % UINT16_MAX);
}
}
else
{
poke.original_trainer_ID = distributionPoke.originalTrainerID;
}
}
poke.iv_data[0] = distributionPoke.iv_data[0];
poke.iv_data[1] = distributionPoke.iv_data[1];
// apply the attributes of Gen1DistributionPokemon to the actual Gen2TrainerPokemon instance
gen1_prepareDistributionPokemon((*this), distributionPoke, poke, originalTrainerName);
return addPokemon(poke, originalTrainerName, nickname);
}

View File

@ -501,4 +501,52 @@ const char* gen2_getItemListTypeString(Gen2ItemListType type)
default:
return "Invalid";
}
}
void gen2_prepareDistributionPokemon(Gen2GameReader& gameReader, const Gen2DistributionPokemon& distributionPoke, Gen2TrainerPokemon& poke, const char*& originalTrainerName)
{
if (distributionPoke.setPlayerAsOriginalTrainer)
{
originalTrainerName = gameReader.getTrainerName();
poke.original_trainer_ID = gameReader.getTrainerID();
}
else
{
originalTrainerName = distributionPoke.originalTrainer;
if (distributionPoke.regenerateTrainerID)
{
if (distributionPoke.originalTrainerID)
{
// limit set, apply it
poke.original_trainer_ID = (uint16_t)(rand() % distributionPoke.originalTrainerID);
}
else
{
// no limit. The max is the max of the uint16_t type
poke.original_trainer_ID = (uint16_t)(rand() % UINT16_MAX);
}
}
else
{
poke.original_trainer_ID = distributionPoke.originalTrainerID;
}
}
if (distributionPoke.shinyChance != 0xFF && (rand() % 100) <= distributionPoke.shinyChance)
{
// the pokemon will be shiny
gen2_makePokemonShiny(poke);
}
else if (distributionPoke.randomizeIVs)
{
const uint16_t randomVal = (uint16_t)rand();
poke.iv_data[0] = (uint8_t)(randomVal >> 8);
poke.iv_data[1] = (uint8_t)(randomVal & 0xFF);
}
else
{
poke.iv_data[0] = distributionPoke.iv_data[0];
poke.iv_data[1] = distributionPoke.iv_data[1];
}
}

View File

@ -413,50 +413,8 @@ uint8_t Gen2GameReader::addDistributionPokemon(const Gen2DistributionPokemon &di
Gen2TrainerPokemon poke = distributionPoke.poke;
const char *originalTrainerName;
if (distributionPoke.setPlayerAsOriginalTrainer)
{
originalTrainerName = getTrainerName();
poke.original_trainer_ID = getTrainerID();
}
else
{
originalTrainerName = distributionPoke.originalTrainer;
if (distributionPoke.regenerateTrainerID)
{
if (distributionPoke.originalTrainerID)
{
// limit set, apply it
poke.original_trainer_ID = (uint16_t)(rand() % distributionPoke.originalTrainerID);
}
else
{
// no limit. The max is the max of the uint16_t type
poke.original_trainer_ID = (uint16_t)(rand() % UINT16_MAX);
}
}
else
{
poke.original_trainer_ID = distributionPoke.originalTrainerID;
}
}
if (distributionPoke.shinyChance != 0xFF && (rand() % 100) <= distributionPoke.shinyChance)
{
// the pokemon will be shiny
gen2_makePokemonShiny(poke);
}
else if (distributionPoke.randomizeIVs)
{
const uint16_t randomVal = (uint16_t)rand();
poke.iv_data[0] = (uint8_t)(randomVal >> 8);
poke.iv_data[1] = (uint8_t)(randomVal & 0xFF);
}
else
{
poke.iv_data[0] = distributionPoke.iv_data[0];
poke.iv_data[1] = distributionPoke.iv_data[1];
}
// apply the attributes of Gen2DistributionPokemon to the actual Gen2TrainerPokemon instance
gen2_prepareDistributionPokemon((*this), distributionPoke, poke, originalTrainerName);
return addPokemon(poke, distributionPoke.isEgg, originalTrainerName, nickname);
}