summaryrefslogtreecommitdiff
path: root/Gain-experience-from-catching-Pokémon.md
blob: 3547b32da79b2313a2f46778b7c18445e3301fdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
This tutorial is for how to make it so that your party Pokémon get experience points from capturing wild Pokémon, as in generation VI onwards. As you'll soon see, it's a pretty easy addition.


## Contents

1. [Add a new function](#1-add-a-new-function)
2. [Call the function](#2-call-the-function)


## 1. Add a new function

Luckily for us, the UpdateBattleStateAndExperienceAfterEnemyFaint function in the core.asm already does what we want, with a few tweaks. This routine is called when your Pokémon knocks out an opposing Pokémon (either wild or a Trainer's). So we'll make use of it!

Edit [engine/battle/core.asm](../blob/master/engine/battle/core.asm):

```diff
UpdateBattleStateAndExperienceAfterEnemyFaint:
	call UpdateBattleMonInParty
 	...
 	ld [wBattleParticipantsNotFainted], a
	ret

+ApplyExperienceAfterEnemyCaught:
+	call IsAnyMonHoldingExpShare
+	jr z, .skip_exp
+	ld hl, wEnemyMonBaseStats
+	ld b, wEnemyMonEnd - wEnemyMonBaseStats
+.loop
+	srl [hl]
+	inc hl
+	dec b
+	jr nz, .loop
+
+.skip_exp
+	ld hl, wEnemyMonBaseStats
+	ld de, wBackupEnemyMonBaseStats
+	ld bc, wEnemyMonEnd - wEnemyMonBaseStats
+	call CopyBytes
+	xor a
+	ld [wGivingExperienceToExpShareHolders], a
+	call GiveExperiencePoints
+	call IsAnyMonHoldingExpShare
+	ret z
+
+	ld a, [wBattleParticipantsNotFainted]
+	push af
+	ld a, d
+	ld [wBattleParticipantsNotFainted], a
+	ld hl, wBackupEnemyMonBaseStats
+	ld de, wEnemyMonBaseStats
+	ld bc, wEnemyMonEnd - wEnemyMonBaseStats
+	call CopyBytes
+	ld a, $1
+	ld [wGivingExperienceToExpShareHolders], a
+	call GiveExperiencePoints
+	pop af
+	ld [wBattleParticipantsNotFainted], a
+	ret

IsAnyMonHoldingExpShare:
	ld a, [wPartyCount]
```

Here we made a new function called ApplyExperienceAfterEnemyCaught. Basically, everything is copied except anything related to Trainers, since you wouldn't capture a Trainer's Pokémon ever (you don't want to be a thief), and also the check to see if you have a fit Pokémon (it's already a precondition to throw a ball in the first place). Moreover, there's no need to update the battle scene or change the music to the victory jingle since the game already does this for us once the wild Pokémon is successfully captured. Everything else, including calculating boosts and Exp. Share divisions, is done in the function GiveExperiencePoints.


## 2. Call the function

We have a new function but we need to call it at the appropriate place. This is done in the file that dictates how a ball operates. Since these are (in Vanilla Crystal) in different banks, a farcall needs to be made instead of a regular call. But is that enough? Not really, we need to be a bit more careful with it.

Edit [engine/items/item_effects.asm](../blob/master/engine/items/item_effects.asm):

```diff
.Transformed:
	ld a, [wEnemyMonSpecies]
 	...
	ld hl, Text_GotchaMonWasCaught
	call PrintText

+	ld a, [wTempSpecies]
+	ld l, a
+	ld a, [wCurPartyLevel]
+	ld h, a
+	push hl
+	farcall ApplyExperienceAfterEnemyCaught
+	pop hl
+	ld a, l
+	ld [wCurPartySpecies], a
+	ld [wTempSpecies], a
+	ld a, h
+	ld [wCurPartyLevel], a

	call ClearSprites

```

Here we placed the code right after the game determines that the foe is captured, and is about to switch to the Pokédex/naming screen. Turns out just doing the farcall isn't enough. Indeed, if your Pokémon happens to level up, wCurPartyLevel gets overwritten. Even worse, wCurPartySpecies also gets overwritten which would cause you to capture the wrong species at a wrong level! To get the intended result, we need to store the values the game needs to add the proper Pokémon to your collection, and then retrieve them after the experience routine is over with. 

And just like that, you're ready to catch 'em all and raise your Pokémon in one fell swoop. 

![Screenshot](screenshots/catch-exp.png)