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 need the level requirement.

Contents

  1. Create the constant that will call the evolution method
  2. Read the method from the pokémon
  3. Create the conditions
  4. Held item parameter
  5. Add the evolution method to a pokémon
  6. 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.

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

For last just make the pokémon evolve to 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 want to remove the level requirement, go back and edit .held from evolve.asm and add jp .proceed to evolve without checking for the level.

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 .proceed

Then don't give a level requirement to the pokémon. The evolution in evos_attacks.asm will be call 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
	...