Sets neutral nature and ability 0 as default in trainer control (#4172)

* Sets neutral nature and ability 0 as default in trainer control

* add config to generate a random ability

* minor correction

* move config to battle.h

* fixed compiling
This commit is contained in:
Alex 2024-02-18 15:02:58 +01:00 committed by GitHub
parent d608af5662
commit 7ab23cf426
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 28 additions and 12 deletions

View file

@ -230,6 +230,7 @@
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS TRUE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_TRAINER_MON_RANDOM_ABILITY FALSE // If this is set to TRUE a random legal ability will be generated for a trainer mon
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config.
#define B_OVERWORLD_SNOW GEN_LATEST // In Gen9+, overworld Snow will summon snow instead of hail.

View file

@ -52,7 +52,6 @@ struct TrainerBacksprite
#define GET_MON_COORDS_HEIGHT(size)((size & 0xF) * 8)
#define TRAINER_PARTY_IVS(hp, atk, def, speed, spatk, spdef) (hp | (atk << 5) | (def << 10) | (speed << 15) | (spatk << 20) | (spdef << 25))
#define TRAINER_PARTY_EVS(hp, atk, def, speed, spatk, spdef) ((const u8[6]){hp,atk,def,spatk,spdef,speed})
#define TRAINER_PARTY_NATURE(nature) (nature+1)
struct TrainerMon
{

View file

@ -1928,7 +1928,7 @@ void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags)
{
u32 personalityValue;
s32 i, j;
s32 i;
u8 monsCount;
if (battleTypeFlags & BATTLE_TYPE_TRAINER && !(battleTypeFlags & (BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_EREADER_TRAINER
@ -1956,6 +1956,7 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
const struct TrainerMon *partyData = trainer->party;
u32 otIdType = OT_ID_RANDOM_NO_SHINY;
u32 fixedOtId = 0;
u32 ability = 0;
if (trainer->doubleBattle == TRUE)
personalityValue = 0x80;
@ -1969,8 +1970,7 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_MALE, partyData[i].species);
else if (partyData[i].gender == TRAINER_MON_FEMALE)
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_FEMALE, partyData[i].species);
if (partyData[i].nature != 0)
ModifyPersonalityForNature(&personalityValue, partyData[i].nature - 1);
ModifyPersonalityForNature(&personalityValue, partyData[i].nature);
if (partyData[i].isShiny)
{
otIdType = OT_ID_PRESET;
@ -1994,14 +1994,24 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
u32 maxAbilities = ARRAY_COUNT(speciesInfo->abilities);
for (j = 0; j < maxAbilities; ++j)
for (ability = 0; ability < maxAbilities; ++ability)
{
if (speciesInfo->abilities[j] == partyData[i].ability)
if (speciesInfo->abilities[ability] == partyData[i].ability)
break;
}
if (j < maxAbilities)
SetMonData(&party[i], MON_DATA_ABILITY_NUM, &j);
if (ability >= maxAbilities)
ability = 0;
}
else if (B_TRAINER_MON_RANDOM_ABILITY)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
ability = personalityHash % 3;
while (speciesInfo->abilities[ability] == ABILITY_NONE)
{
ability--;
}
}
SetMonData(&party[i], MON_DATA_ABILITY_NUM, &ability);
SetMonData(&party[i], MON_DATA_FRIENDSHIP, &(partyData[i].friendship));
if (partyData[i].ball != ITEM_NONE)
{

View file

@ -2,7 +2,7 @@ static const struct TrainerMon sParty_StevenPartner[] = {
{
.species = SPECIES_METANG,
.lvl = 42,
.nature = TRAINER_PARTY_NATURE(NATURE_BRAVE),
.nature = NATURE_BRAVE,
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
.ev = TRAINER_PARTY_EVS(0, 252, 252, 0, 6, 0),
.moves = {MOVE_LIGHT_SCREEN, MOVE_PSYCHIC, MOVE_REFLECT, MOVE_METAL_CLAW},
@ -10,7 +10,7 @@ static const struct TrainerMon sParty_StevenPartner[] = {
{
.species = SPECIES_SKARMORY,
.lvl = 43,
.nature = TRAINER_PARTY_NATURE(NATURE_IMPISH),
.nature = NATURE_IMPISH,
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
.ev = TRAINER_PARTY_EVS(252, 0, 0, 0, 6, 252),
.moves = {MOVE_TOXIC, MOVE_AERIAL_ACE, MOVE_PROTECT, MOVE_STEEL_WING},
@ -18,7 +18,7 @@ static const struct TrainerMon sParty_StevenPartner[] = {
{
.species = SPECIES_AGGRON,
.lvl = 44,
.nature = TRAINER_PARTY_NATURE(NATURE_ADAMANT),
.nature = NATURE_ADAMANT,
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
.ev = TRAINER_PARTY_EVS(0, 252, 0, 0, 252, 6),
.moves = {MOVE_THUNDER, MOVE_PROTECT, MOVE_SOLAR_BEAM, MOVE_DRAGON_CLAW},

View file

@ -26,7 +26,7 @@ static const struct TrainerMon sTestParty1[] =
.ev = TRAINER_PARTY_EVS(252, 0, 0, 252, 4, 0),
.lvl = 67,
.moves = {MOVE_AIR_SLASH, MOVE_BARRIER, MOVE_SOLAR_BEAM, MOVE_EXPLOSION},
.nature = TRAINER_PARTY_NATURE(NATURE_HASTY),
.nature = NATURE_HASTY,
.nickname = COMPOUND_STRING("Bubbles"),
.dynamaxLevel = 5,
},
@ -35,6 +35,10 @@ static const struct TrainerMon sTestParty1[] =
.ability = ABILITY_SHADOW_TAG,
.lvl = 5,
},
{
.species = SPECIES_WYNAUT,
.lvl = 5,
},
};
static const struct Trainer sTestTrainer1 =
@ -59,6 +63,7 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
EXPECT(GetMonAbility(&testParty[0]) == ABILITY_TELEPATHY);
EXPECT(GetMonAbility(&testParty[1]) == ABILITY_SHADOW_TAG);
EXPECT(GetMonAbility(&testParty[2]) == ABILITY_SHADOW_TAG);
EXPECT(GetMonData(&testParty[0], MON_DATA_FRIENDSHIP, 0) == 42);
EXPECT(GetMonData(&testParty[1], MON_DATA_FRIENDSHIP, 0) == 0);
@ -110,6 +115,7 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
EXPECT(GetMonGender(&testParty[0]) == MON_FEMALE);
EXPECT(GetNature(&testParty[0]) == NATURE_HASTY);
EXPECT(GetNature(&testParty[1]) == NATURE_HARDY);
EXPECT_EQ(GetMonData(&testParty[0], MON_DATA_DYNAMAX_LEVEL), 5);
EXPECT_EQ(GetMonData(&testParty[1], MON_DATA_DYNAMAX_LEVEL), 0);