Consolidate natures (#4562)

* Added NatureInfo struct

* Added back animation variants to struct

* Added PokeBlock animations to struct

* Added Battle Palace info to struct

* Added nature girl messages to struct

* Reordered gNaturesInfo to match struct order

* Refactored nature stat table

* Fixed battle dome nature calculation

* Fixed neutral nature values

* Fixed bracket layout
This commit is contained in:
Frank DeBlasio 2024-05-19 04:14:31 -04:00 committed by GitHub
parent d811cd1c4c
commit 849bd0c8bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 419 additions and 351 deletions

View file

@ -59,7 +59,6 @@ u8 GetFirstFaintedPartyIndex(u8 battlerId);
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler);
extern void (* const gBattleScriptingCommandsTable[])(void);
extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];
extern const struct StatFractions gAccuracyStageRatios[];
#endif // GUARD_BATTLE_SCRIPT_COMMANDS_H

View file

@ -21,9 +21,4 @@
#define PALACE_MOVE_GROUP_DEFENSE 1
#define PALACE_MOVE_GROUP_SUPPORT 2
// In palace doubles battles Pokémon have a target preference depending on nature
#define PALACE_TARGET_STRONGER 0
#define PALACE_TARGET_WEAKER 1
#define PALACE_TARGET_RANDOM 2
#endif //GUARD_CONSTANTS_BATTLE_PALACE_H

View file

@ -558,6 +558,66 @@ struct Ability
u8 failsOnImposter:1; // doesn't work on an Imposter mon; when can we actually use this?
};
enum {
AFFINE_NONE,
AFFINE_TURN_UP,
AFFINE_TURN_UP_AND_DOWN,
AFFINE_TURN_DOWN,
AFFINE_TURN_DOWN_SLOW,
AFFINE_TURN_DOWN_SLIGHT,
AFFINE_TURN_UP_HIGH,
AFFINE_UNUSED_1,
AFFINE_UNUSED_2,
AFFINE_UNUSED_3,
NUM_MON_AFFINES,
};
// The animation the Pokémon does during the feeding scene depends on their nature.
// The below values are offsets into sMonPokeblockAnims of the animation data for that nature.
#define ANIM_HARDY 0
#define ANIM_LONELY (ANIM_HARDY + 3)
#define ANIM_BRAVE (ANIM_LONELY + 1)
#define ANIM_ADAMANT (ANIM_BRAVE + 1)
#define ANIM_NAUGHTY (ANIM_ADAMANT + 5)
#define ANIM_BOLD (ANIM_NAUGHTY + 3)
#define ANIM_DOCILE (ANIM_BOLD + 2)
#define ANIM_RELAXED (ANIM_DOCILE + 1)
#define ANIM_IMPISH (ANIM_RELAXED + 2)
#define ANIM_LAX (ANIM_IMPISH + 1)
#define ANIM_TIMID (ANIM_LAX + 1)
#define ANIM_HASTY (ANIM_TIMID + 5)
#define ANIM_SERIOUS (ANIM_HASTY + 2)
#define ANIM_JOLLY (ANIM_SERIOUS + 1)
#define ANIM_NAIVE (ANIM_JOLLY + 1)
#define ANIM_MODEST (ANIM_NAIVE + 4)
#define ANIM_MILD (ANIM_MODEST + 3)
#define ANIM_QUIET (ANIM_MILD + 1)
#define ANIM_BASHFUL (ANIM_QUIET + 2)
#define ANIM_RASH (ANIM_BASHFUL + 3)
#define ANIM_CALM (ANIM_RASH + 3)
#define ANIM_GENTLE (ANIM_CALM + 1)
#define ANIM_SASSY (ANIM_GENTLE + 1)
#define ANIM_CAREFUL (ANIM_SASSY + 1)
#define ANIM_QUIRKY (ANIM_CAREFUL + 5)
// In palace double battles, Pokémon have a target preference depending on nature
#define PALACE_TARGET_STRONGER 0
#define PALACE_TARGET_WEAKER 1
#define PALACE_TARGET_RANDOM 2
struct NatureInfo
{
const u8 *name;
u8 statUp;
u8 statDown;
u8 backAnim;
u8 pokeBlockAnim[2];
u8 battlePalacePercents[4];
u8 battlePalaceFlavorText;
u8 battlePalaceSmokescreen;
const u8 *natureGirlMessage;
};
#define SPINDA_SPOT_WIDTH 16
#define SPINDA_SPOT_HEIGHT 16
@ -623,9 +683,9 @@ extern const u8 gPPUpAddValues[];
extern const u8 gStatStageRatios[MAX_STAT_STAGE + 1][2];
extern const u16 gUnionRoomFacilityClasses[];
extern const struct SpriteTemplate gBattlerSpriteTemplates[];
extern const s8 gNatureStatTable[][5];
extern const u32 sExpCandyExperienceTable[];
extern const struct Ability gAbilitiesInfo[];
extern const struct NatureInfo gNaturesInfo[];
void ZeroBoxMonData(struct BoxPokemon *boxMon);
void ZeroMonData(struct Pokemon *mon);

View file

@ -7,7 +7,6 @@ extern u8 gLastViewedMonIndex;
extern const u8 *const gMoveDescriptionPointers[];
extern const u8 gNotDoneYetDescription[];
extern const u8 *const gNatureNamePointers[];
extern const struct SpriteTemplate gSpriteTemplate_MoveTypes;
extern const struct CompressedSpriteSheet gSpriteSheet_MoveTypes;

View file

@ -15,37 +15,6 @@
static void SpriteCB_SmokescreenImpactMain(struct Sprite *);
static void SpriteCB_SmokescreenImpact(struct Sprite *);
// The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c
const u8 gBattlePalaceNatureToMoveTarget[NUM_NATURES] =
{
[NATURE_HARDY] = PALACE_TARGET_STRONGER,
[NATURE_LONELY] = PALACE_TARGET_STRONGER,
[NATURE_BRAVE] = PALACE_TARGET_WEAKER,
[NATURE_ADAMANT] = PALACE_TARGET_STRONGER,
[NATURE_NAUGHTY] = PALACE_TARGET_WEAKER,
[NATURE_BOLD] = PALACE_TARGET_WEAKER,
[NATURE_DOCILE] = PALACE_TARGET_RANDOM,
[NATURE_RELAXED] = PALACE_TARGET_STRONGER,
[NATURE_IMPISH] = PALACE_TARGET_STRONGER,
[NATURE_LAX] = PALACE_TARGET_STRONGER,
[NATURE_TIMID] = PALACE_TARGET_WEAKER,
[NATURE_HASTY] = PALACE_TARGET_WEAKER,
[NATURE_SERIOUS] = PALACE_TARGET_WEAKER,
[NATURE_JOLLY] = PALACE_TARGET_STRONGER,
[NATURE_NAIVE] = PALACE_TARGET_RANDOM,
[NATURE_MODEST] = PALACE_TARGET_WEAKER,
[NATURE_MILD] = PALACE_TARGET_STRONGER,
[NATURE_QUIET] = PALACE_TARGET_WEAKER,
[NATURE_BASHFUL] = PALACE_TARGET_WEAKER,
[NATURE_RASH] = PALACE_TARGET_STRONGER,
[NATURE_CALM] = PALACE_TARGET_STRONGER,
[NATURE_GENTLE] = PALACE_TARGET_STRONGER,
[NATURE_SASSY] = PALACE_TARGET_WEAKER,
[NATURE_CAREFUL] = PALACE_TARGET_WEAKER,
[NATURE_QUIRKY] = PALACE_TARGET_STRONGER,
};
static const struct CompressedSpriteSheet sSmokescreenImpactSpriteSheet =
{
.data = gSmokescreenImpactTiles, .size = 0x180, .tag = TAG_SMOKESCREEN

View file

@ -4410,11 +4410,15 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
else
nature = gSaveBlock2Ptr->frontier.domePlayerPartyData[i].nature;
if (gNatureStatTable[nature][j] > 0)
if (gNaturesInfo[nature].statUp == gNaturesInfo[nature].statDown)
{
allocatedArray[j + NUM_STATS + 1] += allocatedArray[j + 1];
}
else if (gNaturesInfo[nature].statUp == j + 1)
{
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 110) / 100;
}
else if (gNatureStatTable[nature][j] < 0)
else if (gNaturesInfo[nature].statDown == j + 1)
{
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100;
allocatedArray[j + NUM_STATS + NUM_NATURE_STATS + 2]++;
@ -4447,11 +4451,16 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
for (j = 0; j < NUM_NATURE_STATS; j++)
{
nature = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].nature;
if (gNatureStatTable[nature][j] > 0)
if (gNaturesInfo[nature].statUp == gNaturesInfo[nature].statDown)
{
allocatedArray[j + NUM_STATS + 1] += allocatedArray[j + 1];
}
else if (gNaturesInfo[nature].statUp == j + 1)
{
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 110) / 100;
}
else if (gNatureStatTable[nature][j] < 0)
else if (gNaturesInfo[nature].statDown == j + 1)
{
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100;
allocatedArray[j + NUM_STATS + NUM_NATURE_STATS + 2]++;

View file

@ -28,7 +28,6 @@
#include "constants/battle_move_effects.h"
extern const u8 gBattlePalaceNatureToMoveTarget[];
extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow;
extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow;
@ -138,7 +137,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler)
// Otherwise use move from "Support" group
for (; i < maxGroupNum; i++)
{
if (gBattlePalaceNatureToMoveGroupLikelihood[GetNatureFromPersonality(gBattleMons[battler].personality)][i] > percent)
if (gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalacePercents[i] > percent)
break;
}
selectedGroup = i - minGroupNum;
@ -328,7 +327,7 @@ static u16 GetBattlePalaceTarget(u32 battler)
if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp)
return (BATTLE_OPPOSITE(battler & BIT_SIDE) + (Random() & 2)) << 8;
switch (gBattlePalaceNatureToMoveTarget[GetNatureFromPersonality(gBattleMons[battler].personality)])
switch (gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceSmokescreen)
{
case PALACE_TARGET_STRONGER:
if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp)

View file

@ -1253,7 +1253,7 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon)
barFontGfx = &gMonSpritesGfxPtr->barFontGfx[0x520 + (GetBattlerPosition(gSprites[healthboxSpriteId].hMain_Battler) * 384)];
var = 5;
nature = GetNature(mon);
StringCopy(&text[6], gNatureNamePointers[nature]);
StringCopy(&text[6], gNaturesInfo[nature].name);
RenderTextHandleBold(barFontGfx, FONT_BOLD, text);
for (j = 6, i = 0; i < var; i++, j++)

View file

@ -1098,72 +1098,6 @@ static const u8 sTerrainToType[BATTLE_TERRAIN_COUNT] =
[BATTLE_TERRAIN_PLAIN] = (B_CAMOUFLAGE_TYPES >= GEN_4 ? TYPE_GROUND : TYPE_NORMAL),
};
// In Battle Palace, moves are chosen based on the pokemons nature rather than by the player
// Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*)
// Each nature has a certain percent chance of selecting a move from a particular group
// and a separate percent chance for each group when at or below 50% HP
// The table below doesn't list percentages for Support because you can subtract the other two
// Support percentages are listed in comments off to the side instead
#define PALACE_STYLE(atk, def, atkLow, defLow) {atk, atk + def, atkLow, atkLow + defLow}
const ALIGNED(4) u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4] =
{
[NATURE_HARDY] = PALACE_STYLE(61, 7, 61, 7), // 32% support >= 50% HP, 32% support < 50% HP
[NATURE_LONELY] = PALACE_STYLE(20, 25, 84, 8), // 55%, 8%
[NATURE_BRAVE] = PALACE_STYLE(70, 15, 32, 60), // 15%, 8%
[NATURE_ADAMANT] = PALACE_STYLE(38, 31, 70, 15), // 31%, 15%
[NATURE_NAUGHTY] = PALACE_STYLE(20, 70, 70, 22), // 10%, 8%
[NATURE_BOLD] = PALACE_STYLE(30, 20, 32, 58), // 50%, 10%
[NATURE_DOCILE] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
[NATURE_RELAXED] = PALACE_STYLE(25, 15, 75, 15), // 60%, 10%
[NATURE_IMPISH] = PALACE_STYLE(69, 6, 28, 55), // 25%, 17%
[NATURE_LAX] = PALACE_STYLE(35, 10, 29, 6), // 55%, 65%
[NATURE_TIMID] = PALACE_STYLE(62, 10, 30, 20), // 28%, 50%
[NATURE_HASTY] = PALACE_STYLE(58, 37, 88, 6), // 5%, 6%
[NATURE_SERIOUS] = PALACE_STYLE(34, 11, 29, 11), // 55%, 60%
[NATURE_JOLLY] = PALACE_STYLE(35, 5, 35, 60), // 60%, 5%
[NATURE_NAIVE] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
[NATURE_MODEST] = PALACE_STYLE(35, 45, 34, 60), // 20%, 6%
[NATURE_MILD] = PALACE_STYLE(44, 50, 34, 6), // 6%, 60%
[NATURE_QUIET] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
[NATURE_BASHFUL] = PALACE_STYLE(30, 58, 30, 58), // 12%, 12%
[NATURE_RASH] = PALACE_STYLE(30, 13, 27, 6), // 57%, 67%
[NATURE_CALM] = PALACE_STYLE(40, 50, 25, 62), // 10%, 13%
[NATURE_GENTLE] = PALACE_STYLE(18, 70, 90, 5), // 12%, 5%
[NATURE_SASSY] = PALACE_STYLE(88, 6, 22, 20), // 6%, 58%
[NATURE_CAREFUL] = PALACE_STYLE(42, 50, 42, 5), // 8%, 53%
[NATURE_QUIRKY] = PALACE_STYLE(56, 22, 56, 22) // 22%, 22%
};
static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] =
{
[NATURE_HARDY] = B_MSG_EAGER_FOR_MORE,
[NATURE_LONELY] = B_MSG_GLINT_IN_EYE,
[NATURE_BRAVE] = B_MSG_GETTING_IN_POS,
[NATURE_ADAMANT] = B_MSG_GLINT_IN_EYE,
[NATURE_NAUGHTY] = B_MSG_GLINT_IN_EYE,
[NATURE_BOLD] = B_MSG_GETTING_IN_POS,
[NATURE_DOCILE] = B_MSG_EAGER_FOR_MORE,
[NATURE_RELAXED] = B_MSG_GLINT_IN_EYE,
[NATURE_IMPISH] = B_MSG_GETTING_IN_POS,
[NATURE_LAX] = B_MSG_GROWL_DEEPLY,
[NATURE_TIMID] = B_MSG_GROWL_DEEPLY,
[NATURE_HASTY] = B_MSG_GLINT_IN_EYE,
[NATURE_SERIOUS] = B_MSG_EAGER_FOR_MORE,
[NATURE_JOLLY] = B_MSG_GETTING_IN_POS,
[NATURE_NAIVE] = B_MSG_EAGER_FOR_MORE,
[NATURE_MODEST] = B_MSG_GETTING_IN_POS,
[NATURE_MILD] = B_MSG_GROWL_DEEPLY,
[NATURE_QUIET] = B_MSG_EAGER_FOR_MORE,
[NATURE_BASHFUL] = B_MSG_EAGER_FOR_MORE,
[NATURE_RASH] = B_MSG_GROWL_DEEPLY,
[NATURE_CALM] = B_MSG_GETTING_IN_POS,
[NATURE_GENTLE] = B_MSG_GLINT_IN_EYE,
[NATURE_SASSY] = B_MSG_GROWL_DEEPLY,
[NATURE_CAREFUL] = B_MSG_GROWL_DEEPLY,
[NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE,
};
static bool32 NoTargetPresent(u8 battler, u32 move)
{
if (!IsBattlerAlive(gBattlerTarget))
@ -9236,7 +9170,7 @@ static void Cmd_various(void)
{
gBattleStruct->palaceFlags |= gBitTable[battler];
gBattleCommunication[0] = TRUE;
gBattleCommunication[MULTISTRING_CHOOSER] = sBattlePalaceNatureToFlavorTextId[GetNatureFromPersonality(gBattleMons[battler].personality)];
gBattleCommunication[MULTISTRING_CHOOSER] = gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceFlavorText;
}
break;
}

View file

@ -3367,7 +3367,7 @@ static void DebugAction_Give_Pokemon_SelectShiny(u8 taskId)
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar1, gNatureNamePointers[0]);
StringCopy(gStringVar1, gNaturesInfo[0].name);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonNature);
AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
@ -3403,7 +3403,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar1, gNatureNamePointers[gTasks[taskId].tInput]);
StringCopy(gStringVar1, gNaturesInfo[gTasks[taskId].tInput].name);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonNature);
AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
}

View file

@ -2792,41 +2792,13 @@ void SetBattleTowerLinkPlayerGfx(void)
void ShowNatureGirlMessage(void)
{
static const u8 *const sNatureGirlMessages[NUM_NATURES] = {
[NATURE_HARDY] = BattleFrontier_Lounge5_Text_NatureGirlHardy,
[NATURE_LONELY] = BattleFrontier_Lounge5_Text_NatureGirlLonely,
[NATURE_BRAVE] = BattleFrontier_Lounge5_Text_NatureGirlBrave,
[NATURE_ADAMANT] = BattleFrontier_Lounge5_Text_NatureGirlAdamant,
[NATURE_NAUGHTY] = BattleFrontier_Lounge5_Text_NatureGirlNaughty,
[NATURE_BOLD] = BattleFrontier_Lounge5_Text_NatureGirlBold,
[NATURE_DOCILE] = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
[NATURE_RELAXED] = BattleFrontier_Lounge5_Text_NatureGirlRelaxed,
[NATURE_IMPISH] = BattleFrontier_Lounge5_Text_NatureGirlImpish,
[NATURE_LAX] = BattleFrontier_Lounge5_Text_NatureGirlLax,
[NATURE_TIMID] = BattleFrontier_Lounge5_Text_NatureGirlTimid,
[NATURE_HASTY] = BattleFrontier_Lounge5_Text_NatureGirlHasty,
[NATURE_SERIOUS] = BattleFrontier_Lounge5_Text_NatureGirlSerious,
[NATURE_JOLLY] = BattleFrontier_Lounge5_Text_NatureGirlJolly,
[NATURE_NAIVE] = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
[NATURE_MODEST] = BattleFrontier_Lounge5_Text_NatureGirlModest,
[NATURE_MILD] = BattleFrontier_Lounge5_Text_NatureGirlMild,
[NATURE_QUIET] = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
[NATURE_BASHFUL] = BattleFrontier_Lounge5_Text_NatureGirlBashful,
[NATURE_RASH] = BattleFrontier_Lounge5_Text_NatureGirlRash,
[NATURE_CALM] = BattleFrontier_Lounge5_Text_NatureGirlCalm,
[NATURE_GENTLE] = BattleFrontier_Lounge5_Text_NatureGirlGentle,
[NATURE_SASSY] = BattleFrontier_Lounge5_Text_NatureGirlSassy,
[NATURE_CAREFUL] = BattleFrontier_Lounge5_Text_NatureGirlCareful,
[NATURE_QUIRKY] = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
};
u8 nature;
if (gSpecialVar_0x8004 >= PARTY_SIZE)
gSpecialVar_0x8004 = 0;
nature = GetNature(&gPlayerParty[gSpecialVar_0x8004]);
ShowFieldMessage(sNatureGirlMessages[nature]);
ShowFieldMessage(gNaturesInfo[nature].natureGirlMessage);
}
void UpdateFrontierGambler(u16 daysSince)

View file

@ -40,51 +40,9 @@ enum {
NUM_ANIMDATA
};
enum {
AFFINE_NONE,
AFFINE_TURN_UP,
AFFINE_TURN_UP_AND_DOWN,
AFFINE_TURN_DOWN,
AFFINE_TURN_DOWN_SLOW,
AFFINE_TURN_DOWN_SLIGHT,
AFFINE_TURN_UP_HIGH,
AFFINE_UNUSED_1,
AFFINE_UNUSED_2,
AFFINE_UNUSED_3,
NUM_MON_AFFINES,
};
#define MON_X 48
#define MON_Y 80
// The animation the Pokémon does during the feeding scene depends on their nature.
// The below values are offsets into sMonPokeblockAnims of the animation data for that nature.
#define ANIM_HARDY 0
#define ANIM_LONELY (ANIM_HARDY + 3)
#define ANIM_BRAVE (ANIM_LONELY + 1)
#define ANIM_ADAMANT (ANIM_BRAVE + 1)
#define ANIM_NAUGHTY (ANIM_ADAMANT + 5)
#define ANIM_BOLD (ANIM_NAUGHTY + 3)
#define ANIM_DOCILE (ANIM_BOLD + 2)
#define ANIM_RELAXED (ANIM_DOCILE + 1)
#define ANIM_IMPISH (ANIM_RELAXED + 2)
#define ANIM_LAX (ANIM_IMPISH + 1)
#define ANIM_TIMID (ANIM_LAX + 1)
#define ANIM_HASTY (ANIM_TIMID + 5)
#define ANIM_SERIOUS (ANIM_HASTY + 2)
#define ANIM_JOLLY (ANIM_SERIOUS + 1)
#define ANIM_NAIVE (ANIM_JOLLY + 1)
#define ANIM_MODEST (ANIM_NAIVE + 4)
#define ANIM_MILD (ANIM_MODEST + 3)
#define ANIM_QUIET (ANIM_MILD + 1)
#define ANIM_BASHFUL (ANIM_QUIET + 2)
#define ANIM_RASH (ANIM_BASHFUL + 3)
#define ANIM_CALM (ANIM_RASH + 3)
#define ANIM_GENTLE (ANIM_CALM + 1)
#define ANIM_SASSY (ANIM_GENTLE + 1)
#define ANIM_CAREFUL (ANIM_SASSY + 1)
#define ANIM_QUIRKY (ANIM_CAREFUL + 5)
struct PokeblockFeed
{
struct Sprite *monSpritePtr;
@ -141,35 +99,6 @@ static void SpriteCB_ThrownPokeblock(struct Sprite *);
EWRAM_DATA static struct PokeblockFeed *sPokeblockFeed = NULL;
EWRAM_DATA static struct CompressedSpritePalette sPokeblockSpritePal = {0};
static const u8 sNatureToMonPokeblockAnim[NUM_NATURES][2] =
{
[NATURE_HARDY] = { ANIM_HARDY, AFFINE_NONE },
[NATURE_LONELY] = { ANIM_LONELY, AFFINE_NONE },
[NATURE_BRAVE] = { ANIM_BRAVE, AFFINE_TURN_UP },
[NATURE_ADAMANT] = { ANIM_ADAMANT, AFFINE_NONE },
[NATURE_NAUGHTY] = { ANIM_NAUGHTY, AFFINE_NONE },
[NATURE_BOLD] = { ANIM_BOLD, AFFINE_NONE },
[NATURE_DOCILE] = { ANIM_DOCILE, AFFINE_NONE },
[NATURE_RELAXED] = { ANIM_RELAXED, AFFINE_TURN_UP_AND_DOWN },
[NATURE_IMPISH] = { ANIM_IMPISH, AFFINE_NONE },
[NATURE_LAX] = { ANIM_LAX, AFFINE_NONE },
[NATURE_TIMID] = { ANIM_TIMID, AFFINE_NONE },
[NATURE_HASTY] = { ANIM_HASTY, AFFINE_NONE },
[NATURE_SERIOUS] = { ANIM_SERIOUS, AFFINE_TURN_DOWN },
[NATURE_JOLLY] = { ANIM_JOLLY, AFFINE_NONE },
[NATURE_NAIVE] = { ANIM_NAIVE, AFFINE_NONE },
[NATURE_MODEST] = { ANIM_MODEST, AFFINE_TURN_DOWN_SLOW },
[NATURE_MILD] = { ANIM_MILD, AFFINE_NONE },
[NATURE_QUIET] = { ANIM_QUIET, AFFINE_NONE },
[NATURE_BASHFUL] = { ANIM_BASHFUL, AFFINE_NONE },
[NATURE_RASH] = { ANIM_RASH, AFFINE_NONE },
[NATURE_CALM] = { ANIM_CALM, AFFINE_NONE },
[NATURE_GENTLE] = { ANIM_GENTLE, AFFINE_TURN_DOWN_SLIGHT },
[NATURE_SASSY] = { ANIM_SASSY, AFFINE_TURN_UP_HIGH },
[NATURE_CAREFUL] = { ANIM_CAREFUL, AFFINE_NONE },
[NATURE_QUIRKY] = { ANIM_QUIRKY, AFFINE_NONE },
};
// Data for the animation the Pokémon does while readying to jump for the Pokéblock
// Each nature can have up to 8 anim 'stages' it progresses through, and each stage has its own array of data.
// The elements in each array correspond in order to the following:
@ -996,7 +925,7 @@ static void CalculateMonAnimLength(void)
pokeblockFeed = sPokeblockFeed;
pokeblockFeed->monAnimLength = 1;
animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
animId = gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[0];
// Add up the time each stage of the animation will take
for (i = 0; i < 8; i++, animId++)
@ -1014,7 +943,7 @@ static void UpdateMonAnim(void)
switch (pokeblockFeed->animRunState)
{
case 0:
pokeblockFeed->animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
pokeblockFeed->animId = gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[0];
pokeblockFeed->monSpritePtr = &gSprites[pokeblockFeed->monSpriteId_];
pokeblockFeed->savedMonSprite = *pokeblockFeed->monSpritePtr;
pokeblockFeed->animRunState = 10;
@ -1023,7 +952,7 @@ static void UpdateMonAnim(void)
break;
case 10:
InitMonAnimStage();
if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != AFFINE_NONE)
if (gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[1] != AFFINE_NONE)
{
// Initialize affine anim
pokeblockFeed->monSpritePtr->oam.affineMode = ST_OAM_AFFINE_DOUBLE;
@ -1033,13 +962,13 @@ static void UpdateMonAnim(void)
}
pokeblockFeed->animRunState = 50;
case 50:
if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != AFFINE_NONE)
if (gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[1] != AFFINE_NONE)
{
// Start affine anim
if (!pokeblockFeed->noMonFlip) // double negation, so mon's sprite is flipped
StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] + NUM_MON_AFFINES);
StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[1] + NUM_MON_AFFINES);
else
StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1]);
StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, gNaturesInfo[pokeblockFeed->nature].pokeBlockAnim[1]);
}
pokeblockFeed->animRunState = 60;
break;

View file

@ -358,62 +358,318 @@ const struct SpindaSpot gSpindaSpotGraphics[] =
{.x = 34, .y = 26, .image = INCBIN_U16("graphics/pokemon/spinda/spots/spot_3.1bpp")}
};
const u8 *const gNatureNamePointers[NUM_NATURES] =
{
[NATURE_HARDY] = COMPOUND_STRING("Hardy"),
[NATURE_LONELY] = COMPOUND_STRING("Lonely"),
[NATURE_BRAVE] = COMPOUND_STRING("Brave"),
[NATURE_ADAMANT] = COMPOUND_STRING("Adamant"),
[NATURE_NAUGHTY] = COMPOUND_STRING("Naughty"),
[NATURE_BOLD] = COMPOUND_STRING("Bold"),
[NATURE_DOCILE] = COMPOUND_STRING("Docile"),
[NATURE_RELAXED] = COMPOUND_STRING("Relaxed"),
[NATURE_IMPISH] = COMPOUND_STRING("Impish"),
[NATURE_LAX] = COMPOUND_STRING("Lax"),
[NATURE_TIMID] = COMPOUND_STRING("Timid"),
[NATURE_HASTY] = COMPOUND_STRING("Hasty"),
[NATURE_SERIOUS] = COMPOUND_STRING("Serious"),
[NATURE_JOLLY] = COMPOUND_STRING("Jolly"),
[NATURE_NAIVE] = COMPOUND_STRING("Naive"),
[NATURE_MODEST] = COMPOUND_STRING("Modest"),
[NATURE_MILD] = COMPOUND_STRING("Mild"),
[NATURE_QUIET] = COMPOUND_STRING("Quiet"),
[NATURE_BASHFUL] = COMPOUND_STRING("Bashful"),
[NATURE_RASH] = COMPOUND_STRING("Rash"),
[NATURE_CALM] = COMPOUND_STRING("Calm"),
[NATURE_GENTLE] = COMPOUND_STRING("Gentle"),
[NATURE_SASSY] = COMPOUND_STRING("Sassy"),
[NATURE_CAREFUL] = COMPOUND_STRING("Careful"),
[NATURE_QUIRKY] = COMPOUND_STRING("Quirky"),
};
// In Battle Palace, moves are chosen based on the pokemons nature rather than by the player
// Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*)
// Each nature has a certain percent chance of selecting a move from a particular group
// and a separate percent chance for each group when at or below 50% HP
// The table below doesn't list percentages for Support because you can subtract the other two
// Support percentages are listed in comments off to the side instead
#define PALACE_STYLE(atk, def, atkLow, defLow) {atk, atk + def, atkLow, atkLow + defLow}
const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] =
{ // Attack Defense Speed Sp.Atk Sp. Def
[NATURE_HARDY] = { 0, 0, 0, 0, 0 },
[NATURE_LONELY] = { +1, -1, 0, 0, 0 },
[NATURE_BRAVE] = { +1, 0, -1, 0, 0 },
[NATURE_ADAMANT] = { +1, 0, 0, -1, 0 },
[NATURE_NAUGHTY] = { +1, 0, 0, 0, -1 },
[NATURE_BOLD] = { -1, +1, 0, 0, 0 },
[NATURE_DOCILE] = { 0, 0, 0, 0, 0 },
[NATURE_RELAXED] = { 0, +1, -1, 0, 0 },
[NATURE_IMPISH] = { 0, +1, 0, -1, 0 },
[NATURE_LAX] = { 0, +1, 0, 0, -1 },
[NATURE_TIMID] = { -1, 0, +1, 0, 0 },
[NATURE_HASTY] = { 0, -1, +1, 0, 0 },
[NATURE_SERIOUS] = { 0, 0, 0, 0, 0 },
[NATURE_JOLLY] = { 0, 0, +1, -1, 0 },
[NATURE_NAIVE] = { 0, 0, +1, 0, -1 },
[NATURE_MODEST] = { -1, 0, 0, +1, 0 },
[NATURE_MILD] = { 0, -1, 0, +1, 0 },
[NATURE_QUIET] = { 0, 0, -1, +1, 0 },
[NATURE_BASHFUL] = { 0, 0, 0, 0, 0 },
[NATURE_RASH] = { 0, 0, 0, +1, -1 },
[NATURE_CALM] = { -1, 0, 0, 0, +1 },
[NATURE_GENTLE] = { 0, -1, 0, 0, +1 },
[NATURE_SASSY] = { 0, 0, -1, 0, +1 },
[NATURE_CAREFUL] = { 0, 0, 0, -1, +1 },
[NATURE_QUIRKY] = { 0, 0, 0, 0, 0 },
// The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c
const struct NatureInfo gNaturesInfo[NUM_NATURES] =
{
[NATURE_HARDY] =
{
.name = COMPOUND_STRING("Hardy"),
.statUp = STAT_ATK,
.statDown = STAT_ATK,
.backAnim = 0,
.pokeBlockAnim = {ANIM_HARDY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlHardy,
.battlePalacePercents = PALACE_STYLE(61, 7, 61, 7), //32% support >= 50% HP, 32% support < 50% HP
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_LONELY] =
{
.name = COMPOUND_STRING("Lonely"),
.statUp = STAT_ATK,
.statDown = STAT_DEF,
.backAnim = 2,
.pokeBlockAnim = {ANIM_LONELY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlLonely,
.battlePalacePercents = PALACE_STYLE(20, 25, 84, 8), //55%, 8%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_BRAVE] =
{
.name = COMPOUND_STRING("Brave"),
.statUp = STAT_ATK,
.statDown = STAT_SPEED,
.backAnim = 0,
.pokeBlockAnim = {ANIM_BRAVE, AFFINE_TURN_UP},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlBrave,
.battlePalacePercents = PALACE_STYLE(70, 15, 32, 60), //15%, 8%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_ADAMANT] =
{
.name = COMPOUND_STRING("Adamant"),
.statUp = STAT_ATK,
.statDown = STAT_SPATK,
.backAnim = 0,
.pokeBlockAnim = {ANIM_ADAMANT, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlAdamant,
.battlePalacePercents = PALACE_STYLE(38, 31, 70, 15), //31%, 15%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_NAUGHTY] =
{
.name = COMPOUND_STRING("Naughty"),
.statUp = STAT_ATK,
.statDown = STAT_SPDEF,
.backAnim = 0,
.pokeBlockAnim = {ANIM_NAUGHTY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlNaughty,
.battlePalacePercents = PALACE_STYLE(20, 70, 70, 22), //10%, 8%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_BOLD] =
{
.name = COMPOUND_STRING("Bold"),
.statUp = STAT_DEF,
.statDown = STAT_ATK,
.backAnim = 1,
.pokeBlockAnim = {ANIM_BOLD, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlBold,
.battlePalacePercents = PALACE_STYLE(30, 20, 32, 58), //50%, 10%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_DOCILE] =
{
.name = COMPOUND_STRING("Docile"),
.statUp = STAT_DEF,
.statDown = STAT_DEF,
.backAnim = 1,
.pokeBlockAnim = {ANIM_DOCILE, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
.battlePalacePercents = PALACE_STYLE(56, 22, 56, 22), //22%, 22%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_RANDOM,
},
[NATURE_RELAXED] =
{
.name = COMPOUND_STRING("Relaxed"),
.statUp = STAT_DEF,
.statDown = STAT_SPEED,
.backAnim = 1,
.pokeBlockAnim = {ANIM_RELAXED, AFFINE_TURN_UP_AND_DOWN},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlRelaxed,
.battlePalacePercents = PALACE_STYLE(25, 15, 75, 15), //60%, 10%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_IMPISH] =
{
.name = COMPOUND_STRING("Impish"),
.statUp = STAT_DEF,
.statDown = STAT_SPATK,
.backAnim = 0,
.pokeBlockAnim = {ANIM_IMPISH, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlImpish,
.battlePalacePercents = PALACE_STYLE(69, 6, 28, 55), //25%, 17%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_LAX] =
{
.name = COMPOUND_STRING("Lax"),
.statUp = STAT_DEF,
.statDown = STAT_SPDEF,
.backAnim = 1,
.pokeBlockAnim = {ANIM_LAX, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlLax,
.battlePalacePercents = PALACE_STYLE(35, 10, 29, 6), //55%, 65%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_TIMID] =
{
.name = COMPOUND_STRING("Timid"),
.statUp = STAT_SPEED,
.statDown = STAT_ATK,
.backAnim = 2,
.pokeBlockAnim = {ANIM_TIMID, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlTimid,
.battlePalacePercents = PALACE_STYLE(62, 10, 30, 20), //28%, 50%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_HASTY] =
{
.name = COMPOUND_STRING("Hasty"),
.statUp = STAT_SPEED,
.statDown = STAT_DEF,
.backAnim = 0,
.pokeBlockAnim = {ANIM_HASTY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlHasty,
.battlePalacePercents = PALACE_STYLE(58, 37, 88, 6), //5%, 6%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_SERIOUS] =
{
.name = COMPOUND_STRING("Serious"),
.statUp = STAT_SPEED,
.statDown = STAT_SPEED,
.backAnim = 1,
.pokeBlockAnim = {ANIM_SERIOUS, AFFINE_TURN_DOWN},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlSerious,
.battlePalacePercents = PALACE_STYLE(34, 11, 29, 11), //55%, 60%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_JOLLY] =
{
.name = COMPOUND_STRING("Jolly"),
.statUp = STAT_SPEED,
.statDown = STAT_SPATK,
.backAnim = 0,
.pokeBlockAnim = {ANIM_JOLLY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlJolly,
.battlePalacePercents = PALACE_STYLE(35, 5, 35, 60), //60%, 5%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_NAIVE] =
{
.name = COMPOUND_STRING("Naive"),
.statUp = STAT_SPEED,
.statDown = STAT_SPDEF,
.backAnim = 0,
.pokeBlockAnim = {ANIM_NAIVE, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
.battlePalacePercents = PALACE_STYLE(56, 22, 56, 22), //22%, 22%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_RANDOM,
},
[NATURE_MODEST] =
{
.name = COMPOUND_STRING("Modest"),
.statUp = STAT_SPATK,
.statDown = STAT_ATK,
.backAnim = 2,
.pokeBlockAnim = {ANIM_MODEST, AFFINE_TURN_DOWN_SLOW},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlModest,
.battlePalacePercents = PALACE_STYLE(35, 45, 34, 60), //20%, 6%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_MILD] =
{
.name = COMPOUND_STRING("Mild"),
.statUp = STAT_SPATK,
.statDown = STAT_DEF,
.backAnim = 2,
.pokeBlockAnim = {ANIM_MILD, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlMild,
.battlePalacePercents = PALACE_STYLE(44, 50, 34, 6), //6%, 60%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_QUIET] =
{
.name = COMPOUND_STRING("Quiet"),
.statUp = STAT_SPATK,
.statDown = STAT_SPEED,
.backAnim = 2,
.pokeBlockAnim = {ANIM_QUIET, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
.battlePalacePercents = PALACE_STYLE(56, 22, 56, 22), //22%, 22%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_BASHFUL] =
{
.name = COMPOUND_STRING("Bashful"),
.statUp = STAT_SPATK,
.statDown = STAT_SPATK,
.backAnim = 2,
.pokeBlockAnim = {ANIM_BASHFUL, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlBashful,
.battlePalacePercents = PALACE_STYLE(30, 58, 30, 58), //12%, 12%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_RASH] =
{
.name = COMPOUND_STRING("Rash"),
.statUp = STAT_SPATK,
.statDown = STAT_SPDEF,
.backAnim = 1,
.pokeBlockAnim = {ANIM_RASH, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlRash,
.battlePalacePercents = PALACE_STYLE(30, 13, 27, 6), //57%, 67%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_CALM] =
{
.name = COMPOUND_STRING("Calm"),
.statUp = STAT_SPDEF,
.statDown = STAT_ATK,
.backAnim = 1,
.pokeBlockAnim = {ANIM_CALM, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlCalm,
.battlePalacePercents = PALACE_STYLE(40, 50, 25, 62), //10%, 13%
.battlePalaceFlavorText = B_MSG_GETTING_IN_POS,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_GENTLE] =
{
.name = COMPOUND_STRING("Gentle"),
.statUp = STAT_SPDEF,
.statDown = STAT_DEF,
.backAnim = 2,
.pokeBlockAnim = {ANIM_GENTLE, AFFINE_TURN_DOWN_SLIGHT},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlGentle,
.battlePalacePercents = PALACE_STYLE(18, 70, 90, 5), //12%, 5%
.battlePalaceFlavorText = B_MSG_GLINT_IN_EYE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
[NATURE_SASSY] =
{
.name = COMPOUND_STRING("Sassy"),
.statDown = STAT_SPDEF,
.statUp = STAT_SPEED,
.backAnim = 1,
.pokeBlockAnim = {ANIM_SASSY, AFFINE_TURN_UP_HIGH},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlSassy,
.battlePalacePercents = PALACE_STYLE(88, 6, 22, 20), //6%, 58%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_CAREFUL] =
{
.name = COMPOUND_STRING("Careful"),
.statUp = STAT_SPDEF,
.statDown = STAT_SPATK,
.backAnim = 2,
.pokeBlockAnim = {ANIM_CAREFUL, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlCareful,
.battlePalacePercents = PALACE_STYLE(42, 50, 42, 5), //8%, 53%
.battlePalaceFlavorText = B_MSG_GROWL_DEEPLY,
.battlePalaceSmokescreen = PALACE_TARGET_WEAKER,
},
[NATURE_QUIRKY] =
{
.name = COMPOUND_STRING("Quirky"),
.statUp = STAT_SPDEF,
.statDown = STAT_SPDEF,
.backAnim = 1,
.pokeBlockAnim = {ANIM_QUIRKY, AFFINE_NONE},
.natureGirlMessage = BattleFrontier_Lounge5_Text_NatureGirlDocileNaiveQuietQuirky,
.battlePalacePercents = PALACE_STYLE(56, 22, 56, 22), //22%, 22%
.battlePalaceFlavorText = B_MSG_EAGER_FOR_MORE,
.battlePalaceSmokescreen = PALACE_TARGET_STRONGER,
},
};
#include "data/graphics/pokemon.h"
@ -4811,38 +5067,15 @@ u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
u16 ModifyStatByNature(u8 nature, u16 stat, u8 statIndex)
{
// Because this is a u16 it will be unable to store the
// result of the multiplication for any stat > 595 for a
// positive nature and > 728 for a negative nature.
// Neither occur in the base game, but this can happen if
// any Nature-affected base stat is increased to a value
// above 248. The closest by default is Shuckle at 230.
#ifdef BUGFIX
u32 retVal;
#else
u16 retVal;
#endif
// Don't modify HP, Accuracy, or Evasion by nature
if (statIndex <= STAT_HP || statIndex > NUM_NATURE_STATS)
if (statIndex <= STAT_HP || statIndex > NUM_NATURE_STATS || gNaturesInfo[nature].statUp == gNaturesInfo[nature].statDown)
return stat;
else if (statIndex == gNaturesInfo[nature].statUp)
return stat * 110 / 100;
else if (statIndex == gNaturesInfo[nature].statDown)
return stat * 90 / 100;
else
return stat;
switch (gNatureStatTable[nature][statIndex - 1])
{
case 1:
retVal = stat * 110;
retVal /= 100;
break;
case -1:
retVal = stat * 90;
retVal /= 100;
break;
default:
retVal = stat;
break;
}
return retVal;
}
#define IS_LEAGUE_BATTLE(trainerClass) \

View file

@ -428,35 +428,6 @@ static const u8 sBackAnimationIds[] =
[(BACK_ANIM_SHAKE_GLOW_BLUE - 1) * 3] = ANIM_SHAKE_GLOW_BLUE_FAST, ANIM_SHAKE_GLOW_BLUE, ANIM_SHAKE_GLOW_BLUE_SLOW,
};
static const u8 sBackAnimNatureModTable[NUM_NATURES] =
{
[NATURE_HARDY] = 0,
[NATURE_LONELY] = 2,
[NATURE_BRAVE] = 0,
[NATURE_ADAMANT] = 0,
[NATURE_NAUGHTY] = 0,
[NATURE_BOLD] = 1,
[NATURE_DOCILE] = 1,
[NATURE_RELAXED] = 1,
[NATURE_IMPISH] = 0,
[NATURE_LAX] = 1,
[NATURE_TIMID] = 2,
[NATURE_HASTY] = 0,
[NATURE_SERIOUS] = 1,
[NATURE_JOLLY] = 0,
[NATURE_NAIVE] = 0,
[NATURE_MODEST] = 2,
[NATURE_MILD] = 2,
[NATURE_QUIET] = 2,
[NATURE_BASHFUL] = 2,
[NATURE_RASH] = 1,
[NATURE_CALM] = 1,
[NATURE_GENTLE] = 2,
[NATURE_SASSY] = 1,
[NATURE_CAREFUL] = 2,
[NATURE_QUIRKY] = 1,
};
static const union AffineAnimCmd sMonAffineAnim_0[] =
{
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
@ -579,7 +550,7 @@ void LaunchAnimationTaskForBackSprite(struct Sprite *sprite, u8 backAnimSet)
nature = GetNature(&gPlayerParty[gBattlerPartyIndexes[battlerId]]);
// * 3 below because each back anim has 3 variants depending on nature
animId = 3 * backAnimSet + sBackAnimNatureModTable[nature];
animId = 3 * backAnimSet + gNaturesInfo[nature].backAnim;
gTasks[taskId].tAnimId = sBackAnimationIds[animId];
}

View file

@ -3261,7 +3261,7 @@ static void PrintMonTrainerMemo(void)
static void BufferNatureString(void)
{
struct PokemonSummaryScreenData *sumStruct = sMonSummaryScreen;
DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, gNatureNamePointers[sumStruct->summary.nature]);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, gNaturesInfo[sumStruct->summary.nature].name);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(5, gText_EmptyString5);
}
@ -3478,19 +3478,21 @@ static void PrintRibbonCount(void)
PrintTextOnWindow(AddWindowFromTemplateList(sPageSkillsTemplate, PSS_DATA_WINDOW_SKILLS_RIBBON_COUNT), text, x, 1, 0, 0);
}
static void BufferStat(u8 *dst, s8 natureMod, u32 stat, u32 strId, u32 n)
static void BufferStat(u8 *dst, u8 statIndex, u32 stat, u32 strId, u32 n)
{
static const u8 sTextNatureDown[] = _("{COLOR}{08}");
static const u8 sTextNatureUp[] = _("{COLOR}{05}");
static const u8 sTextNatureNeutral[] = _("{COLOR}{01}");
u8 *txtPtr;
if (natureMod == 0 || !SUMMARY_SCREEN_NATURE_COLORS)
if (statIndex == 0 || !SUMMARY_SCREEN_NATURE_COLORS || gNaturesInfo[sMonSummaryScreen->summary.mintNature].statUp == gNaturesInfo[sMonSummaryScreen->summary.mintNature].statDown)
txtPtr = StringCopy(dst, sTextNatureNeutral);
else if (natureMod > 0)
else if (statIndex == gNaturesInfo[sMonSummaryScreen->summary.mintNature].statUp)
txtPtr = StringCopy(dst, sTextNatureUp);
else
else if (statIndex == gNaturesInfo[sMonSummaryScreen->summary.mintNature].statDown)
txtPtr = StringCopy(dst, sTextNatureDown);
else
txtPtr = StringCopy(dst, sTextNatureNeutral);
ConvertIntToDecimalStringN(txtPtr, stat, STR_CONV_MODE_RIGHT_ALIGN, n);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(strId, dst);
@ -3502,13 +3504,12 @@ static void BufferLeftColumnStats(void)
u8 *maxHPString = Alloc(20);
u8 *attackString = Alloc(20);
u8 *defenseString = Alloc(20);
const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.mintNature];
DynamicPlaceholderTextUtil_Reset();
BufferStat(currentHPString, 0, sMonSummaryScreen->summary.currentHP, 0, 3);
BufferStat(maxHPString, 0, sMonSummaryScreen->summary.maxHP, 1, 3);
BufferStat(attackString, natureMod[STAT_ATK - 1], sMonSummaryScreen->summary.atk, 2, 7);
BufferStat(defenseString, natureMod[STAT_DEF - 1], sMonSummaryScreen->summary.def, 3, 7);
BufferStat(attackString, STAT_ATK, sMonSummaryScreen->summary.atk, 2, 7);
BufferStat(defenseString, STAT_DEF, sMonSummaryScreen->summary.def, 3, 7);
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsLeftColumnLayout);
Free(currentHPString);
@ -3524,12 +3525,10 @@ static void PrintLeftColumnStats(void)
static void BufferRightColumnStats(void)
{
const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.mintNature];
DynamicPlaceholderTextUtil_Reset();
BufferStat(gStringVar1, natureMod[STAT_SPATK - 1], sMonSummaryScreen->summary.spatk, 0, 3);
BufferStat(gStringVar2, natureMod[STAT_SPDEF - 1], sMonSummaryScreen->summary.spdef, 1, 3);
BufferStat(gStringVar3, natureMod[STAT_SPEED - 1], sMonSummaryScreen->summary.speed, 2, 3);
BufferStat(gStringVar1, STAT_SPATK, sMonSummaryScreen->summary.spatk, 0, 3);
BufferStat(gStringVar2, STAT_SPDEF, sMonSummaryScreen->summary.spdef, 1, 3);
BufferStat(gStringVar3, STAT_SPEED, sMonSummaryScreen->summary.speed, 2, 3);
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsRightColumnLayout);
}

View file

@ -1393,7 +1393,7 @@ static void UpdateMonInfoText(u16 loadId, bool8 firstPrint)
partyIndex = GetPartyIdFromSelectionId(sMenu->info.curSelection);
nature = GetNature(&gPlayerParty[partyIndex]);
str = StringCopy(sMenu->info.natureText, gText_NatureSlash);
str = StringCopy(str, gNatureNamePointers[nature]);
str = StringCopy(str, gNaturesInfo[nature].name);
AddTextPrinterParameterized3(WIN_NATURE, FONT_NORMAL, 2, 1, sNatureTextColors, 0, sMenu->info.natureText);
}