Evolve while holding an item - pret/pokecrystal GitHub Wiki
This tutorial will show how to make a Pokémon evolve by level up while holding an item at certain level. Then I'll show how to evolve without the need for the level requirement.
Contents
- Create the constant that will call the evolution method
- Read the method from the Pokémon
- Create the conditions
- Held item parameter
- Add the evolution method to a Pokémon
- Extra: Removing the level requirement
1. Create the constant that will call the evolution method
Create the constant that will call the evolution method.
Edit: constants/pokemon_data_constants.asm
; evolution types (used in data/pokemon/evos_attacks.asm)
const_def 1
const EVOLVE_LEVEL
const EVOLVE_ITEM
const EVOLVE_TRADE
const EVOLVE_HAPPINESS
const EVOLVE_STAT
+ const EVOLVE_HELD
2. Read the method from the Pokémon
Edit: engine/pokemon/evolve.asm
EvolveAfterBattle_MasterLoop:
(...)
cp EVOLVE_HAPPINESS
jr z, .happiness
+ cp EVOLVE_HELD
+ jp z, .held
This will call the evolution method. Just change the jr to jp in .got_tyrogue_evo to link properly.
EvolveAfterBattle_MasterLoop:
(...)
.got_tyrogue_evo
pop hl
inc hl
cp [hl]
jp nz, .dont_evolve_2
inc hl
- jr .proceed
+ jp .proceed
3. Create the conditions
Keep editing evolve.asm. Create a .held which will contain the verification which will tell if the conditions are met. The first part will get the Pokémon held item, then will check if the item is the one required.
Putting the .held before the .level will make the evolution require both methods, the held item and the level.
EvolveAfterBattle_MasterLoop:
(...)
+.held
+ push hl
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1Item
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hl]
+ ld b, a
+ pop hl
+ ld a, [hli]
+ cp b
+ jp nz, .dont_evolve_2
.level
ld a, [hli]
...
4. Held item parameter
This evolution type needs an extra parameter because we are looking for the held item. This is still in evolve.asm.
GetPreEvolution:
(...)
.loop2 ; For each evolution...
ld a, [hli]
and a
jr z, .no_evolve ; If we jump, this Pokemon does not evolve into wCurPartySpecies.
+ cp EVOLVE_HELD
+ jr z, .held_param
cp EVOLVE_STAT ; This evolution type has the extra parameter of stat comparison.
jr nz, .not_tyrogue
inc hl
+.held_param
+ inc hl
.not_tyrogue
inc hl
ld a, [wCurPartySpecies]
5. Add the evolution method to a Pokémon
Edit: data/pokemon/evos_attacks.asm
Lastly, just make the Pokémon evolve into whatever Pokémon you want by adding the following to the Pokémon in the evos_attacks.asm:
db <evolution method>, <item required>, <level required>, <evolved form>
Example:
CaterpieEvosAttacks:
+ db EVOLVE_HELD, BERRY, 6, KINGDRA
db EVOLVE_LEVEL, 7, METAPOD
db 0 ; no more evolutions
db 1, TACKLE
db 1, STRING_SHOT
...
Extra: Removing the level requirement
If you don't want the level requirement on top of the held item, edit .held to jump directly to .proceed instead of falling through to .level. Also, since you won't need the extra parameter for the level, you'll want to change jp nz, .dont_evolve_2 to jp nz, .dont_evolve_3, and get rid of the extra code in GetPreEvolution.
Edit: engine/pokemon/evolve.asm
.held
push hl
ld a, [wCurPartyMon]
ld hl, wPartyMon1Item
ld bc, PARTYMON_STRUCT_LENGTH
call AddNTimes
ld a, [hl]
ld b, a
pop hl
ld a, [hli]
cp b
- jp nz, .dont_evolve_2
+ jp nz, .dont_evolve_3
+ jp .proceed
(...)
.loop2 ; For each evolution...
ld a, [hli]
and a
jr z, .no_evolve ; If we jump, this Pokemon does not evolve into wCurPartySpecies.
- cp EVOLVE_HELD
- jr z, .held_param
cp EVOLVE_STAT ; This evolution type has the extra parameter of stat comparison.
jr nz, .not_tyrogue
inc hl
-.held_param
- inc hl
.not_tyrogue
inc hl
ld a, [wCurPartySpecies]
Then don't give a level requirement to the Pokémon. The evolution in evos_attacks.asm will be called with:
db <evolution method>, <item required>, <evolved form>
Example:
CaterpieEvosAttacks:
- db EVOLVE_HELD, BERRY, 6, KINGDRA
+ db EVOLVE_HELD, BERRY, KINGDRA
db EVOLVE_LEVEL, 7, METAPOD
db 0 ; no more evolutions
db 1, TACKLE
db 1, STRING_SHOT
...