Skip to content

Don't gain experience at level 100

i0brendan0 edited this page Feb 5, 2019 · 6 revisions

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.

Anyway, just edit one file, engine/battle/core.asm:

 GiveExperiencePoints:
 ; Give experience.
 ; Don't give experience if linked or in the Battle Tower.
 	ld a, [wLinkMode]
 	and a
 	ret nz
 
 	ld a, [wInBattleTowerBattle]
 	bit 0, a
 	ret nz
 
 	call .EvenlyDivideExpAmongParticipants
 	xor a
 	ld [wCurPartyMon], a
 	ld bc, wPartyMon1Species
 
 .loop
 	ld hl, MON_HP
 	add hl, bc
 	ld a, [hli]
 	or [hl]
 	jp z, .skip_stats ; fainted
 
 	...

 .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

 	...

 .next_mon
 	ld a, [wPartyCount]
 	ld b, a
 	ld a, [wCurPartyMon]
 	inc a
 	cp b
 	jr z, .done
 	ld [wCurPartyMon], a
 	ld a, MON_SPECIES
 	call GetPartyParamLocation
 	ld b, h
 	ld c, l
 	jp .loop

 .done
 	jp ResetBattleParticipants

 .EvenlyDivideExpAmongParticipants:
 ; count number of battle participants
 	ld a, [wBattleParticipantsNotFainted]
 	ld b, a
 	ld c, PARTY_LENGTH
 	ld d, 0
 .count_loop
+	push bc
+	push de
+	ld a, [wPartyCount]
+	cp c
+	jr c, .no_mon
+	ld a, c
+	dec a
+	ld hl, wPartyMon1Level
+	call GetPartyLocation
+	ld a, [hl]
+.no_mon
+	cp MAX_LEVEL
+	pop de
+	pop bc
+	jr nz, .gains_exp
+	srl b
+	ld a, d
+	jr .no_exp
+.gains_exp
 	xor a
 	srl b
 	adc d
 	ld d, a
+.no_exp
 	dec c
 	jr nz, .count_loop
 	cp 2
 	ret c

The first edit there skips experience gain for level 100 Pokémon. The second edit skips counting those Pokémon toward the divisor, just as if they were fainted, so all the experience points will be evenly divided among participants that can actually benefit.

(If you're studying how it works, notice that the logic around jr c, .no_mon relies on PARTY_LENGTH < MAX_LEVEL, i.e. 6 < 100. This is a safe assumption that allows for more efficient code.)

Clone this wiki locally