Table of Contents
Credit to DizzyEgg for this feature. This feature may also be directly pulled from DizzyEgg's nature_color branch.
This tutorial will color a stat's number based on whether the stat is boosted or reduced by the Pokemon's nature. This tutorial will use red for boost and blue for reduction, to match the vanilla games. Keep in mind that Egg's repo uses light red for reduction, instead.
Contents
1. Adding a function to color the stats
All of our changes will be in src/pokemon_summary_screen.c.
We will write a new function that accepts the nature modification as a parameter and colors the stats accordingly. Add this function:
//...
static void KeepMoveSelectorVisible(u8);
static void SummaryScreen_DestroyAnimDelayTask(void);
+static void BufferStat(u8 *dst, s8 natureMod, u32 stat, u32 strId, u32 n);
// const rom data
#include "data/text/move_descriptions.h"
#include "data/text/nature_names.h"
//...
static void BufferStat(u8 *dst, s8 natureMod, 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)
txtPtr = StringCopy(dst, sTextNatureNeutral);
else if (natureMod > 0)
txtPtr = StringCopy(dst, sTextNatureUp);
else
txtPtr = StringCopy(dst, sTextNatureDown);
ConvertIntToDecimalStringN(txtPtr, stat, STR_CONV_MODE_RIGHT_ALIGN, n);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(strId, dst);
}
This function checks the nature modification and adds the corresponding colors. The list of colors can be found in charmap.txt and the constants can be modified as you wish. Then, ConvertIntToDecimalStringN
is called to convert the stat into text. This function also leaves the color modifier from before intact. Finally, a placeholder is set using DynamicPlaceholderTextUtil_SetPlaceholderPtr.
We now need to update the other functions that buffer the stats to use our new function. This will be done in the next step.
2. Buffering the colored stats
The functions that set the placeholders and expand them for the summary screen are BufferLeftColumnStats
and BufferRightColumnStats
. All we need to do is change them to use our function, instead of directly setting the placeholder themselves.
Let's change the left column function first:
static void BufferLeftColumnStats(void)
{
- u8 *currentHPString = Alloc(8);
- u8 *maxHPString = Alloc(8);
- u8 *attackString = Alloc(8);
- u8 *defenseString = Alloc(8);
+ u8 *currentHPString = Alloc(20);
+ u8 *maxHPString = Alloc(20);
+ u8 *attackString = Alloc(20);
+ u8 *defenseString = Alloc(20);
+ const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.nature];
- ConvertIntToDecimalStringN(currentHPString, sMonSummaryScreen->summary.currentHP, STR_CONV_MODE_RIGHT_ALIGN, 3);
- ConvertIntToDecimalStringN(maxHPString, sMonSummaryScreen->summary.maxHP, STR_CONV_MODE_RIGHT_ALIGN, 3);
- ConvertIntToDecimalStringN(attackString, sMonSummaryScreen->summary.atk, STR_CONV_MODE_RIGHT_ALIGN, 7);
- ConvertIntToDecimalStringN(defenseString, sMonSummaryScreen->summary.def, STR_CONV_MODE_RIGHT_ALIGN, 7);
DynamicPlaceholderTextUtil_Reset();
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, currentHPString);
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, maxHPString);
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, attackString);
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, defenseString);
+ 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);
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsLeftColumnLayout);
Free(currentHPString);
Free(maxHPString);
Free(attackString);
Free(defenseString);
}
More memory needs to be allocated for the colored stats than before. We will also need to read from the nature table to pass in the nature modifiers. Finally, the text conversion is already handled in our method, so we don't need it in this function.
Now, let's modify the right column:
static void BufferRightColumnStats(void)
{
- ConvertIntToDecimalStringN(gStringVar1, sMonSummaryScreen->summary.spatk, STR_CONV_MODE_RIGHT_ALIGN, 3);
- ConvertIntToDecimalStringN(gStringVar2, sMonSummaryScreen->summary.spdef, STR_CONV_MODE_RIGHT_ALIGN, 3);
- ConvertIntToDecimalStringN(gStringVar3, sMonSummaryScreen->summary.speed, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ const s8 *natureMod = gNatureStatTable[sMonSummaryScreen->summary.nature];
DynamicPlaceholderTextUtil_Reset();
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gStringVar2);
- DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, gStringVar3);
+ 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);
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, sStatsRightColumnLayout);
}
And there you have it!