• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Conquest protagonist in the poll by clicking here.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[pokeemerald-expansion] Pokémon keep getting EXP despite level caps. What am I doing wrong?

  • 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:
    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;
    }
    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:
    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;
    }
    If anyone can help, it would be very appreciated.
     
    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:
    ...
    If anyone can help, it would be very appreciated.
    You would be getting no exp if this condition was true
    Code:
    if (expGetterLevel >= levelCap)
    So I'm guessing that the value of one of those variables is not what you expect. You could print their values to see if that is the case.
     
    Thanks for the suggestion. Unfortunately, my problem now is that the debugger doesn't seem to be working for me. I placed DebugPrintf("expGetterLevel: %d", expGetterLevel); underneath all of the declarations, and yet no matter how I configure the logger in mGBA I can't get it to print.
     
    Thanks for the suggestion. Unfortunately, my problem now is that the debugger doesn't seem to be working for me. I placed DebugPrintf("expGetterLevel: %d", expGetterLevel); underneath all of the declarations, and yet no matter how I configure the logger in mGBA I can't get it to print.
    Make sure to comment out NDEBUG inside include/config.h.
     
    Back
    Top