diff options
Diffstat (limited to 'Level-cap.md')
-rw-r--r-- | Level-cap.md | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/Level-cap.md b/Level-cap.md new file mode 100644 index 0000000..fbe21ff --- /dev/null +++ b/Level-cap.md @@ -0,0 +1,218 @@ +This tutorial guides you through changing the max level. You will add a new variable, modify level cap logic, and optionally remove gaining exp. once a pokemon is the max level. + +**TODO**: +Investigate wether one is able to set the level cap by modifying `MAX_LEVEL EQU [0-255]` in `constants/battle_constants.asm`. + +## 1. Add Level Cap variable +First, we want to add a `wLevelCap` variable to `wram.asm` in the root folder. +In `wram.asm`, go to line 2668, `wBeverlyFightCount:: db ; unused`. +Since this byte is unused, you can replace it. +Replace this line with `wLevelCap:: db`. +This is the value we'll be checking for the level cap + +```diff +; fight counts +wJackFightCount:: db ; d9f2 +- wBeverlyFightCount:: db ; unused ++ wLevelCap:: db +wHueyFightCount:: db +wGavenFightCount:: db +``` + +To set the level cap, write this in a script: +`loadmem wLevelCap, [0-255] ; number from 0 to 255 representing what your level cap should be` + +## 2. Replace first level cap check + +In `engine/pokemon/experience.asm`, go to line 9: `cp LOW(MAX_LEVEL + 1)`. +This is what we first need to change. +Before the `ld a, d` on the line before it, add code to load the new level cap into register `b`. + +```diff +.next_level + inc d ++ ld a, [wLevelCap] ++ inc a ++ push bc ++ ld b, a + ld a, d ++ cp b ++ pop bc + cp LOW(MAX_LEVEL + 1) + jr z, .got_level + call CalcExpAtLevel +``` + +## 3. Replace the rest of the cap checks + +There are now five more instances of `MAX_LEVEL` that you'll need to change. +First, go to the `.no_exp_overflow` label located in `engine/battle/core.asm`. +Instead of storing the `MAX_LEVEL` value, we load our custom max level. + +```diff +.no_exp_overflow + ld a, [wCurPartyMon] + ld e, a + ld d, 0 + ld hl, wPartySpecies + add hl, de + ld a, [hl] + ld [wCurSpecies], a + call GetBaseData + push bc +- ld d, MAX_LEVEL ++ push af ++ ld a, [wLevelCap] ++ ld d, a ++ pop af + callfar CalcExpAtLevel +``` + +Next, `ctrl + f` for the next instance of `MAX_LEVEL`, located in the `.not_max_exp` label. You'll notice that the line before this reads `ld a, [hl]` Before this line, load the level cap into register b. Then, after `ld a, [hl]`, add a comparison and restore the `bc` register. Here we use the comparison to control the jump. + +```diff +.not_max_exp +; Check if the mon leveled up + xor a ; PARTYMON + ld [wMonType], a + predef CopyMonToTempMon + callfar CalcLevel + pop bc + ld hl, MON_LEVEL + add hl, bc ++ ld a, [wLevelCap] ++ push bc ++ ld b, a + ld a, [hl] ++ cp b ++ pop bc +- cp MAX_LEVEL + jp nc, .next_mon +``` + +Third, ctrl + f for the next instance of MAX_LEVEL, located in the `AnimateExpBar` label. You'll notice there's a `ld a, [wBattleMonLevel]` before it. Before this, add + +```diff +AnimateExpBar: + push bc + + ld hl, wCurPartyMon + ld a, [wCurBattleMon] + cp [hl] + jp nz, .finish + ++ ld a, [wLevelCap] ++ push bc ++ ld b, a + ld a, [wBattleMonLevel] ++ cp b ++ pop bc +- cp MAX_LEVEL + jp nc, .finish +``` + +Fourth, ctrl + f for the next instance of MAX_LEVEL. Replace `ld d, MAX_LEVEL` with loading the custom max level. + +```diff + ld [hli], a + ld [hl], a + +.NoOverflow: ++ push af ++ ld a, [wLevelCap] ++ ld d, a ++ pop af + callfar CalcExpAtLevel + ldh a, [hProduct + 1] + ld b, a +``` + +Fifth, ctrl + f for the final instance of MAX_LEVEL. You'll notice before it reads `ld a, e`. Before this, lod the level cap into b, then do the comparison on that. + +```diff + ld a, e + ld d, a + +.LoopLevels: ++ ld a, [wLevelCap] ++ push bc ++ ld b, a + ld a, e +- cp MAX_LEVEL ++ cp b ++ pop bc + jr nc, .FinishExpBar + cp d + jr z, .FinishExpBar + inc a +``` + +Now you're done with replacing the max level checks with the level cap checks. + +## 4. Optional: Remove exp. gain text at max level + +You'll notice that the exp. gain text still displays when you reach the level cap. +To remove this, go to line 7059 in `engine/battle/core.asm`, which should be about the lines of + +```diff +.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, [wLevelCap] ++ push bc ++ ld b, a ++ ld a, [hl] ++ cp b ++ pop bc ++ jp nc, .next_mon ++ push bc + xor a + ldh [hMultiplicand + 0], a + ldh [hMultiplicand + 1], a + ld a, [wEnemyMonBaseExp] +``` + +Next, go to + +```diff +.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, [wLevelCap] ++ ld b, a ++ 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 b ++ 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 +``` |