- 7
- Posts
- 8
- Years
- Seen Feb 10, 2025
I've been working on making a hard level cap system that would give EXP only up to the level cap by modifying the ApplyExperienceMultipliers function in src/battle_script_commands.c:
Yet for some reason, the experience gained seems to be completely unaffected. For example, my level 20 Treecko will gain like 8 EXP from a level 3 Wurmple even though the level cap is set to 15.
For reference, GetCurrentLevelCap() is found in my src/level_caps.c file that I added. The inside looks like:
If anyone can help, it would be very appreciated.
C:
void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBattler)
{
u8 levelCap = GetCurrentLevelCap();
u8 expGetterLevel = GetMonData(&gPlayerParty[expGetterMonId], MON_DATA_LEVEL);
u32 holdEffect = GetMonHoldEffect(&gPlayerParty[expGetterMonId]);
u32 expGetterExp = GetMonData(&gPlayerParty[expGetterMonId], MON_DATA_EXP);
u32 expGetterSpecies = GetMonData(&gPlayerParty[expGetterMonId], MON_DATA_SPECIES);
u32 expCap = gExperienceTables[gSpeciesInfo[expGetterSpecies].growthRate][levelCap];
if (IsTradedMon(&gPlayerParty[expGetterMonId]))
*expAmount = (*expAmount * 150) / 100;
if (holdEffect == HOLD_EFFECT_LUCKY_EGG)
*expAmount = (*expAmount * 150) / 100;
if (B_UNEVOLVED_EXP_MULTIPLIER >= GEN_6 && IsMonPastEvolutionLevel(&gPlayerParty[expGetterMonId]))
*expAmount = (*expAmount * 4915) / 4096;
if (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(expGetterMonId) >= AFFECTION_FOUR_HEARTS)
*expAmount = (*expAmount * 4915) / 4096;
if (CheckBagHasItem(ITEM_EXP_CHARM, 1)) //is also for other exp boosting Powers if/when implemented
*expAmount = (*expAmount * 150) / 100;
if (B_SCALED_EXP >= GEN_5 && B_SCALED_EXP != GEN_6)
{
// Note: There is an edge case where if a pokemon receives a large amount of exp, it wouldn't be properly calculated
// because of multiplying by scaling factor(the value would simply be larger than an u32 can hold). Hence u64 is needed.
u64 value = *expAmount;
u8 faintedLevel = gBattleMons[faintedBattler].level;
value *= sExperienceScalingFactors[(faintedLevel * 2) + 10];
value /= sExperienceScalingFactors[faintedLevel + expGetterLevel + 10];
*expAmount = value + 1;
}
if ((expGetterExp + *expAmount) > expCap)
{
*expAmount = expCap - expGetterExp;
if (*expAmount < 0)
*expAmount = 0;
}
if (expGetterLevel >= levelCap)
*expAmount = 0;
}
For reference, GetCurrentLevelCap() is found in my src/level_caps.c file that I added. The inside looks like:
Code:
u8 GetCurrentBadgeCount(void)
{
u16 i, j, badgeCount = 0;
for (i = FLAG_BADGE01_GET; i < FLAG_BADGE01_GET + NUM_BADGES; i++)
{
if(FlagGet(i))
badgeCount++;
}
for (j = FLAG_DEFEATED_ELITE_4_DRAKE; j < FLAG_DEFEATED_ELITE_4_DRAKE + 4; j++)
{
if(FlagGet(j))
badgeCount++;
}
return badgeCount;
}
enum LevelCap {
LEVEL_CAP_NO_BADGES,
LEVEL_CAP_BADGE_1,
LEVEL_CAP_BADGE_2,
LEVEL_CAP_BADGE_3,
LEVEL_CAP_BADGE_4,
LEVEL_CAP_BADGE_5,
LEVEL_CAP_BADGE_6,
LEVEL_CAP_BADGE_7,
LEVEL_CAP_BADGE_8,
LEVEL_CAP_SYDNEY,
LEVEL_CAP_PHOEBE,
LEVEL_CAP_GLACIA,
LEVEL_CAP_DRAKE
};
static const u8 sLevelCapTable[] =
{
[LEVEL_CAP_NO_BADGES] = 15,
[LEVEL_CAP_BADGE_1] = 19,
[LEVEL_CAP_BADGE_2] = 24,
[LEVEL_CAP_BADGE_3] = 29,
[LEVEL_CAP_BADGE_4] = 31,
[LEVEL_CAP_BADGE_5] = 33,
[LEVEL_CAP_BADGE_6] = 42,
[LEVEL_CAP_BADGE_7] = 46,
[LEVEL_CAP_BADGE_8] = 49,
[LEVEL_CAP_SYDNEY] = 51,
[LEVEL_CAP_PHOEBE] = 53,
[LEVEL_CAP_GLACIA] = 55,
[LEVEL_CAP_DRAKE] = 58,
};
u32 GetCurrentLevelCap(void)
{
u8 badgeCount = GetCurrentBadgeCount();
if (FlagGet(FLAG_IS_CHAMPION))
return MAX_LEVEL;
else
return sLevelCapTable[badgeCount];
return MAX_LEVEL;
}