-
Notifications
You must be signed in to change notification settings - Fork 817
Don't gain experience at level 100
At level 100, Pokémon can't usefully gain experience. But until Gen 5, they did so anyway, taking a share from other battle participants who would actually benefit (and wasting time with messages about their gains).
This tutorial shows how to disable experience gain at level 100. It does not affect stat experience (the Gen 1 and 2 precursor to EVs), so you can still use the box trick to raise stats at level 100.
- Skip awarding EXP to level 100 Pokémon
- Don't count level 100 Pokémon in the divisor when dividing experience
- Discard level 100 Pokémon when counting Exp. Share holders
The first step is to skip level 100 Pokémon when the game is giving experience to battle participants and Exp. Share holders. For this, let's edit engine/battle/core.asm:
GiveExperiencePoints:
; Give experience.
; Don't give experience if linked or in the Battle Tower.
...
.stat_exp_awarded
inc de
inc de
dec c
jr nz, .stat_exp_loop
+ pop bc
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ cp MAX_LEVEL
+ jp nc, .next_mon
+ push bc
xor a
ldh [hMultiplicand + 0], a
ldh [hMultiplicand + 1], a
ld a, [wEnemyMonBaseExp]
ldh [hMultiplicand + 2], a
ld a, [wEnemyMonLevel]
ldh [hMultiplier], a
call Multiply
ld a, 7
ldh [hDivisor], a
ld b, 4
call Divide
...
Notice how, even though we're stopping max level Pokémon from getting experience, they're still being awarded stat experience (which happens before giving experience to Pokémon).
Even though level 100 Pokémon won't get experience, they're still accounted for when evenly dividing it among battle participants, which will make the resulting experience smaller for the other Pokémon under level 100. For this, let's edit engine/battle/core.asm again, modifying the function responsible of evenly dividing the experience:
GiveExperiencePoints:
...
.EvenlyDivideExpAmongParticipants:
; count number of battle participants
ld a, [wBattleParticipantsNotFainted]
ld b, a
ld c, PARTY_LENGTH
- ld d, 0
+ ld de, 0
.count_loop
+ push bc
+ push de
+ ld a, e
+ ld hl, wPartyMon1Level
+ call GetPartyLocation
+ ld a, [hl]
+ cp MAX_LEVEL
+ pop de
+ pop bc
+ jr c, .gains_exp
+ srl b
+ ld a, d
+ jr .no_exp
+.gains_exp
xor a
srl b
adc d
ld d, a
+.no_exp
+ inc e
dec c
jr nz, .count_loop
cp 2
ret c
...
Now when counting each battle participant, it'll first check their levels as a requirement to be counted in the divisor, so all the experience points will be evenly divided among participants that can actually benefit from it.
Our level 100 Pokémon are no longer awarded experience and don't affect the experience distribution among battle participants... but what happens when they're holding an Exp. Share? Normally when at least one Pokémon is holding an Exp. Share both the total experience and the stat experience are halved: the first half is evenly distributed among battle participants and the other half among Exp. Share holders; this also applies when level 100 Pokémon are holding the item. This is problematic if all Exp. Share holders are level 100, since we're basically losing 50% of the total experience and stat experience.
The best approach is to discard them while counting how many Pokémon are holding the item. For this, let's go to engine/battle/core.asm again and edit the function which handles counting Exp. Share holders:
IsAnyMonHoldingExpShare:
ld a, [wPartyCount]
ld b, a
ld hl, wPartyMon1
ld c, 1
ld d, 0
.loop
push hl
push bc
ld bc, MON_HP
add hl, bc
ld a, [hli]
or [hl]
pop bc
pop hl
jr z, .next
+ push hl
+ push bc
+ ld bc, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ cp MAX_LEVEL
+ pop bc
+ pop hl
+ jr nc, .next
push hl
push bc
ld bc, MON_ITEM
add hl, bc
pop bc
ld a, [hl]
pop hl
...
The original function had the condition where a Pokémon must be alive before being considered an Exp. Share holder; with our change we added another condition where its level must also be under the maximum.
The only downside of this step is that level 100 Pokémon won't get stat experience from only holding an Exp. Share, so make sure to make them participate in battle!
And with these changes, the tutorial is finally complete! Your fully-trained level 100 Pokémon won't steal precious experience and Stat Exp. anymore!