Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/battle/experience.asm
1271 views
1
GainExperience:
2
ld a, [wLinkState]
3
cp LINK_STATE_BATTLING
4
ret z ; return if link battle
5
call DivideExpDataByNumMonsGainingExp
6
ld hl, wPartyMon1
7
xor a
8
ld [wWhichPokemon], a
9
.partyMonLoop ; loop over each mon and add gained exp
10
inc hl
11
ld a, [hli]
12
or [hl] ; is mon's HP 0?
13
jp z, .nextMon ; if so, go to next mon
14
push hl
15
ld hl, wPartyGainExpFlags
16
ld a, [wWhichPokemon]
17
ld c, a
18
ld b, FLAG_TEST
19
predef FlagActionPredef
20
ld a, c
21
and a ; is mon's gain exp flag set?
22
pop hl
23
jp z, .nextMon ; if mon's gain exp flag not set, go to next mon
24
ld de, (wPartyMon1HPExp + 1) - (wPartyMon1HP + 1)
25
add hl, de
26
ld d, h
27
ld e, l
28
ld hl, wEnemyMonBaseStats
29
ld c, NUM_STATS
30
.gainStatExpLoop
31
ld a, [hli]
32
ld b, a ; enemy mon base stat
33
ld a, [de] ; stat exp
34
add b ; add enemy mon base state to stat exp
35
ld [de], a
36
jr nc, .nextBaseStat
37
; if there was a carry, increment the upper byte
38
dec de
39
ld a, [de]
40
inc a
41
jr z, .maxStatExp ; jump if the value overflowed
42
ld [de], a
43
inc de
44
jr .nextBaseStat
45
.maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
46
ld a, $ff
47
ld [de], a
48
inc de
49
ld [de], a
50
.nextBaseStat
51
dec c
52
jr z, .statExpDone
53
inc de
54
inc de
55
jr .gainStatExpLoop
56
.statExpDone
57
xor a
58
ldh [hMultiplicand], a
59
ldh [hMultiplicand + 1], a
60
ld a, [wEnemyMonBaseExp]
61
ldh [hMultiplicand + 2], a
62
ld a, [wEnemyMonLevel]
63
ldh [hMultiplier], a
64
call Multiply
65
ld a, 7
66
ldh [hDivisor], a
67
ld b, 4
68
call Divide
69
ld hl, wPartyMon1OTID - (wPartyMon1DVs - 1)
70
add hl, de
71
ld b, [hl] ; party mon OTID
72
inc hl
73
ld a, [wPlayerID]
74
cp b
75
jr nz, .tradedMon
76
ld b, [hl]
77
ld a, [wPlayerID + 1]
78
cp b
79
ld a, 0
80
jr z, .next
81
.tradedMon
82
call BoostExp ; traded mon exp boost
83
ld a, 1
84
.next
85
ld [wGainBoostedExp], a
86
ld a, [wIsInBattle]
87
dec a ; is it a trainer battle?
88
call nz, BoostExp ; if so, boost exp
89
inc hl
90
inc hl
91
inc hl
92
; add the gained exp to the party mon's exp
93
ld b, [hl]
94
ldh a, [hQuotient + 3]
95
ld [wExpAmountGained + 1], a
96
add b
97
ld [hld], a
98
ld b, [hl]
99
ldh a, [hQuotient + 2]
100
ld [wExpAmountGained], a
101
adc b
102
ld [hl], a
103
jr nc, .noCarry
104
dec hl
105
inc [hl]
106
inc hl
107
.noCarry
108
; calculate exp for the mon at max level, and cap the exp at that value
109
inc hl
110
push hl
111
ld a, [wWhichPokemon]
112
ld c, a
113
ld b, 0
114
ld hl, wPartySpecies
115
add hl, bc
116
ld a, [hl]
117
ld [wCurSpecies], a
118
call GetMonHeader
119
ld d, MAX_LEVEL
120
callfar CalcExperience ; get max exp
121
; compare max exp with current exp
122
ldh a, [hExperience]
123
ld b, a
124
ldh a, [hExperience + 1]
125
ld c, a
126
ldh a, [hExperience + 2]
127
ld d, a
128
pop hl
129
ld a, [hld]
130
sub d
131
ld a, [hld]
132
sbc c
133
ld a, [hl]
134
sbc b
135
jr c, .next2
136
; the mon's exp is greater than the max exp, so overwrite it with the max exp
137
ld a, b
138
ld [hli], a
139
ld a, c
140
ld [hli], a
141
ld a, d
142
ld [hld], a
143
dec hl
144
.next2
145
push hl
146
ld a, [wWhichPokemon]
147
ld hl, wPartyMonNicks
148
call GetPartyMonName
149
ld hl, GainedText
150
call PrintText
151
xor a ; PLAYER_PARTY_DATA
152
ld [wMonDataLocation], a
153
call LoadMonData
154
pop hl
155
ld bc, wPartyMon1Level - wPartyMon1Exp
156
add hl, bc
157
push hl
158
farcall CalcLevelFromExperience
159
pop hl
160
ld a, [hl] ; current level
161
cp d
162
jp z, .nextMon ; if level didn't change, go to next mon
163
ld a, [wCurEnemyLevel]
164
push af
165
push hl
166
ld a, d
167
ld [wCurEnemyLevel], a
168
ld [hl], a
169
ld bc, wPartyMon1Species - wPartyMon1Level
170
add hl, bc
171
ld a, [hl]
172
ld [wCurSpecies], a
173
ld [wPokedexNum], a
174
call GetMonHeader
175
ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1Species
176
add hl, bc
177
push hl
178
ld a, [hld]
179
ld c, a
180
ld b, [hl]
181
push bc ; push max HP (from before levelling up)
182
ld d, h
183
ld e, l
184
ld bc, (wPartyMon1HPExp - 1) - wPartyMon1MaxHP
185
add hl, bc
186
ld b, $1 ; consider stat exp when calculating stats
187
call CalcStats
188
pop bc ; pop max HP (from before levelling up)
189
pop hl
190
ld a, [hld]
191
sub c
192
ld c, a
193
ld a, [hl]
194
sbc b
195
ld b, a ; bc = difference between old max HP and new max HP after levelling
196
ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
197
add hl, de
198
; add to the current HP the amount of max HP gained when levelling
199
ld a, [hl] ; wPartyMon1HP + 1
200
add c
201
ld [hld], a
202
ld a, [hl] ; wPartyMon1HP + 1
203
adc b
204
ld [hl], a ; wPartyMon1HP
205
ld a, [wPlayerMonNumber]
206
ld b, a
207
ld a, [wWhichPokemon]
208
cp b ; is the current mon in battle?
209
jr nz, .printGrewLevelText
210
; current mon is in battle
211
ld de, wBattleMonHP
212
; copy party mon HP to battle mon HP
213
ld a, [hli]
214
ld [de], a
215
inc de
216
ld a, [hl]
217
ld [de], a
218
; copy other stats from party mon to battle mon
219
ld bc, wPartyMon1Level - (wPartyMon1HP + 1)
220
add hl, bc
221
push hl
222
ld de, wBattleMonLevel
223
ld bc, 1 + NUM_STATS * 2 ; size of stats
224
call CopyData
225
pop hl
226
ld a, [wPlayerBattleStatus3]
227
bit TRANSFORMED, a
228
jr nz, .recalcStatChanges
229
; the mon is not transformed, so update the unmodified stats
230
ld de, wPlayerMonUnmodifiedLevel
231
ld bc, 1 + NUM_STATS * 2
232
call CopyData
233
.recalcStatChanges
234
xor a ; battle mon
235
ld [wCalculateWhoseStats], a
236
callfar CalculateModifiedStats
237
callfar ApplyBurnAndParalysisPenaltiesToPlayer
238
callfar ApplyBadgeStatBoosts
239
callfar DrawPlayerHUDAndHPBar
240
callfar PrintEmptyString
241
call SaveScreenTilesToBuffer1
242
.printGrewLevelText
243
ld hl, GrewLevelText
244
call PrintText
245
xor a ; PLAYER_PARTY_DATA
246
ld [wMonDataLocation], a
247
call LoadMonData
248
ld d, $1
249
callfar PrintStatsBox
250
call WaitForTextScrollButtonPress
251
call LoadScreenTilesFromBuffer1
252
xor a ; PLAYER_PARTY_DATA
253
ld [wMonDataLocation], a
254
ld a, [wCurSpecies]
255
ld [wPokedexNum], a
256
predef LearnMoveFromLevelUp
257
ld hl, wCanEvolveFlags
258
ld a, [wWhichPokemon]
259
ld c, a
260
ld b, FLAG_SET
261
predef FlagActionPredef
262
pop hl
263
pop af
264
ld [wCurEnemyLevel], a
265
266
.nextMon
267
ld a, [wPartyCount]
268
ld b, a
269
ld a, [wWhichPokemon]
270
inc a
271
cp b
272
jr z, .done
273
ld [wWhichPokemon], a
274
ld bc, wPartyMon2 - wPartyMon1
275
ld hl, wPartyMon1
276
call AddNTimes
277
jp .partyMonLoop
278
.done
279
ld hl, wPartyGainExpFlags
280
xor a
281
ld [hl], a ; clear gain exp flags
282
ld a, [wPlayerMonNumber]
283
ld c, a
284
ld b, FLAG_SET
285
push bc
286
predef FlagActionPredef ; set the gain exp flag for the mon that is currently out
287
ld hl, wPartyFoughtCurrentEnemyFlags
288
xor a
289
ld [hl], a
290
pop bc
291
predef_jump FlagActionPredef ; set the fought current enemy flag for the mon that is currently out
292
293
; divide enemy base stats, catch rate, and base exp by the number of mons gaining exp
294
DivideExpDataByNumMonsGainingExp:
295
ld a, [wPartyGainExpFlags]
296
ld b, a
297
xor a
298
ld c, $8
299
ld d, $0
300
.countSetBitsLoop ; loop to count set bits in wPartyGainExpFlags
301
xor a
302
srl b
303
adc d
304
ld d, a
305
dec c
306
jr nz, .countSetBitsLoop
307
cp $2
308
ret c ; return if only one mon is gaining exp
309
ld [wTempByteValue], a ; store number of mons gaining exp
310
ld hl, wEnemyMonBaseStats
311
ld c, wEnemyMonBaseExp + 1 - wEnemyMonBaseStats
312
.divideLoop
313
xor a
314
ldh [hDividend], a
315
ld a, [hl]
316
ldh [hDividend + 1], a
317
ld a, [wTempByteValue]
318
ldh [hDivisor], a
319
ld b, $2
320
call Divide ; divide value by number of mons gaining exp
321
ldh a, [hQuotient + 3]
322
ld [hli], a
323
dec c
324
jr nz, .divideLoop
325
ret
326
327
; multiplies exp by 1.5
328
BoostExp:
329
ldh a, [hQuotient + 2]
330
ld b, a
331
ldh a, [hQuotient + 3]
332
ld c, a
333
srl b
334
rr c
335
add c
336
ldh [hQuotient + 3], a
337
ldh a, [hQuotient + 2]
338
adc b
339
ldh [hQuotient + 2], a
340
ret
341
342
GainedText:
343
text_far _GainedText
344
text_asm
345
ld a, [wBoostExpByExpAll]
346
ld hl, WithExpAllText
347
and a
348
ret nz
349
ld hl, ExpPointsText
350
ld a, [wGainBoostedExp]
351
and a
352
ret z
353
ld hl, BoostedText
354
ret
355
356
WithExpAllText:
357
text_far _WithExpAllText
358
text_asm
359
ld hl, ExpPointsText
360
ret
361
362
BoostedText:
363
text_far _BoostedText
364
365
ExpPointsText:
366
text_far _ExpPointsText
367
text_end
368
369
GrewLevelText:
370
text_far _GrewLevelText
371
sound_level_up
372
text_end
373
374