Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/home/pokemon.asm
1270 views
1
DrawHPBar::
2
; Draw an HP bar d tiles long, and fill it to e pixels.
3
; If c is nonzero, show at least a sliver regardless.
4
; The right end of the bar changes with [wHPBarType].
5
6
push hl
7
push de
8
push bc
9
10
; Left
11
ld a, $71 ; "HP:"
12
ld [hli], a
13
ld a, $62
14
ld [hli], a
15
16
push hl
17
18
; Middle
19
ld a, $63 ; empty
20
.draw
21
ld [hli], a
22
dec d
23
jr nz, .draw
24
25
; Right
26
ld a, [wHPBarType]
27
dec a
28
ld a, $6d ; status screen and battle
29
jr z, .ok
30
dec a ; pokemon menu
31
.ok
32
ld [hl], a
33
34
pop hl
35
36
ld a, e
37
and a
38
jr nz, .fill
39
40
; If c is nonzero, draw a pixel anyway.
41
ld a, c
42
and a
43
jr z, .done
44
ld e, 1
45
46
.fill
47
ld a, e
48
sub 8
49
jr c, .partial
50
ld e, a
51
ld a, $6b ; full
52
ld [hli], a
53
ld a, e
54
and a
55
jr z, .done
56
jr .fill
57
58
.partial
59
; Fill remaining pixels at the end if necessary.
60
ld a, $63 ; empty
61
add e
62
ld [hl], a
63
.done
64
pop bc
65
pop de
66
pop hl
67
ret
68
69
70
; loads pokemon data from one of multiple sources to wLoadedMon
71
; loads base stats to wMonHeader
72
; INPUT:
73
; [wWhichPokemon] = index of pokemon within party/box
74
; [wMonDataLocation] = source
75
; 00: player's party
76
; 01: enemy's party
77
; 02: current box
78
; 03: daycare
79
; OUTPUT:
80
; [wCurPartySpecies] = pokemon ID
81
; wLoadedMon = base address of pokemon data
82
; wMonHeader = base address of base stats
83
LoadMonData::
84
jpfar LoadMonData_
85
86
OverwritewMoves::
87
; Write c to [wMoves + b]. Unused.
88
ld hl, wMoves
89
ld e, b
90
ld d, 0
91
add hl, de
92
ld a, c
93
ld [hl], a
94
ret
95
96
LoadFlippedFrontSpriteByMonIndex::
97
ld a, 1
98
ld [wSpriteFlipped], a
99
100
LoadFrontSpriteByMonIndex::
101
push hl
102
ld a, [wPokedexNum]
103
push af
104
ld a, [wCurPartySpecies]
105
ld [wPokedexNum], a
106
predef IndexToPokedex
107
ld hl, wPokedexNum
108
ld a, [hl]
109
pop bc
110
ld [hl], b
111
and a
112
pop hl
113
jr z, .invalidDexNumber ; dex #0 invalid
114
cp NUM_POKEMON + 1
115
jr c, .validDexNumber ; dex >#151 invalid
116
.invalidDexNumber
117
; This is the so-called "Rhydon trap" or "Rhydon glitch"
118
; to fail-safe invalid dex numbers
119
; (see https://glitchcity.wiki/wiki/Rhydon_trap
120
; or https://bulbapedia.bulbagarden.net/wiki/Rhydon_glitch)
121
ld a, RHYDON
122
ld [wCurPartySpecies], a
123
ret
124
.validDexNumber
125
push hl
126
ld de, vFrontPic
127
call LoadMonFrontSprite
128
pop hl
129
ldh a, [hLoadedROMBank]
130
push af
131
ld a, BANK(CopyUncompressedPicToHL)
132
ldh [hLoadedROMBank], a
133
ld [rROMB], a
134
xor a
135
ldh [hStartTileID], a
136
call CopyUncompressedPicToHL
137
xor a
138
ld [wSpriteFlipped], a
139
pop af
140
ldh [hLoadedROMBank], a
141
ld [rROMB], a
142
ret
143
144
145
PlayCry::
146
; Play monster a's cry.
147
call GetCryData
148
call PlaySound
149
jp WaitForSoundToFinish
150
151
GetCryData::
152
; Load cry data for monster a.
153
dec a
154
ld c, a
155
ld b, 0
156
ld hl, CryData
157
add hl, bc
158
add hl, bc
159
add hl, bc
160
161
ld a, BANK(CryData)
162
call BankswitchHome
163
ld a, [hli]
164
ld b, a ; cry id
165
ld a, [hli]
166
ld [wFrequencyModifier], a
167
ld a, [hl]
168
ld [wTempoModifier], a
169
call BankswitchBack
170
171
; Cry headers have 3 channels,
172
; and start from index CRY_SFX_START,
173
; so add 3 times the cry id.
174
ld a, b
175
ld c, CRY_SFX_START
176
rlca ; * 2
177
add b
178
add c
179
ret
180
181
DisplayPartyMenu::
182
ldh a, [hTileAnimations]
183
push af
184
xor a
185
ldh [hTileAnimations], a
186
call GBPalWhiteOutWithDelay3
187
call ClearSprites
188
call PartyMenuInit
189
call DrawPartyMenu
190
jp HandlePartyMenuInput
191
192
GoBackToPartyMenu::
193
ldh a, [hTileAnimations]
194
push af
195
xor a
196
ldh [hTileAnimations], a
197
call PartyMenuInit
198
call RedrawPartyMenu
199
jp HandlePartyMenuInput
200
201
PartyMenuInit::
202
ld a, 1 ; hardcoded bank
203
call BankswitchHome
204
call LoadHpBarAndStatusTilePatterns
205
ld hl, wStatusFlags5
206
set BIT_NO_TEXT_DELAY, [hl]
207
xor a ; PLAYER_PARTY_DATA
208
ld [wMonDataLocation], a
209
ld [wMenuWatchMovingOutOfBounds], a
210
ld hl, wTopMenuItemY
211
inc a
212
ld [hli], a ; top menu item Y
213
xor a
214
ld [hli], a ; top menu item X
215
ld a, [wPartyAndBillsPCSavedMenuItem]
216
push af
217
ld [hli], a ; current menu item ID
218
inc hl
219
ld a, [wPartyCount]
220
and a ; are there more than 0 pokemon in the party?
221
jr z, .storeMaxMenuItemID
222
dec a
223
; if party is not empty, the max menu item ID is ([wPartyCount] - 1)
224
; otherwise, it is 0
225
.storeMaxMenuItemID
226
ld [hli], a ; max menu item ID
227
ld a, [wForcePlayerToChooseMon]
228
and a
229
ld a, PAD_A | PAD_B
230
jr z, .next
231
xor a
232
ld [wForcePlayerToChooseMon], a
233
inc a ; a = PAD_A
234
.next
235
ld [hli], a ; menu watched keys
236
pop af
237
ld [hl], a ; old menu item ID
238
ret
239
240
HandlePartyMenuInput::
241
ld a, 1
242
ld [wMenuWrappingEnabled], a
243
ld a, $40
244
ld [wPartyMenuAnimMonEnabled], a
245
call HandleMenuInput_
246
call PlaceUnfilledArrowMenuCursor
247
ld b, a
248
xor a
249
ld [wPartyMenuAnimMonEnabled], a
250
ld a, [wCurrentMenuItem]
251
ld [wPartyAndBillsPCSavedMenuItem], a
252
ld hl, wStatusFlags5
253
res BIT_NO_TEXT_DELAY, [hl]
254
ld a, [wMenuItemToSwap]
255
and a
256
jp nz, .swappingPokemon
257
pop af
258
ldh [hTileAnimations], a
259
bit B_PAD_B, b
260
jr nz, .noPokemonChosen
261
ld a, [wPartyCount]
262
and a
263
jr z, .noPokemonChosen
264
ld a, [wCurrentMenuItem]
265
ld [wWhichPokemon], a
266
ld hl, wPartySpecies
267
ld b, 0
268
ld c, a
269
add hl, bc
270
ld a, [hl]
271
ld [wCurPartySpecies], a
272
ld [wBattleMonSpecies2], a
273
call BankswitchBack
274
and a
275
ret
276
.noPokemonChosen
277
call BankswitchBack
278
scf
279
ret
280
.swappingPokemon
281
bit B_PAD_B, b
282
jr z, .handleSwap ; if not, handle swapping the pokemon
283
.cancelSwap ; if the B button was pressed
284
farcall ErasePartyMenuCursors
285
xor a
286
ld [wMenuItemToSwap], a
287
ld [wPartyMenuTypeOrMessageID], a
288
call RedrawPartyMenu
289
jr HandlePartyMenuInput
290
.handleSwap
291
ld a, [wCurrentMenuItem]
292
ld [wWhichPokemon], a
293
farcall SwitchPartyMon
294
jr HandlePartyMenuInput
295
296
DrawPartyMenu::
297
ld hl, DrawPartyMenu_
298
jr DrawPartyMenuCommon
299
300
RedrawPartyMenu::
301
ld hl, RedrawPartyMenu_
302
303
DrawPartyMenuCommon::
304
ld b, BANK(RedrawPartyMenu_)
305
jp Bankswitch
306
307
; prints a pokemon's status condition
308
; INPUT:
309
; de = address of status condition
310
; hl = destination address
311
PrintStatusCondition::
312
push de
313
dec de
314
dec de ; de = address of current HP
315
ld a, [de]
316
ld b, a
317
dec de
318
ld a, [de]
319
or b ; is the pokemon's HP zero?
320
pop de
321
jr nz, PrintStatusConditionNotFainted
322
; if the pokemon's HP is 0, print "FNT"
323
ld a, "F"
324
ld [hli], a
325
ld a, "N"
326
ld [hli], a
327
ld [hl], "T"
328
and a
329
ret
330
331
PrintStatusConditionNotFainted::
332
homecall_sf PrintStatusAilment
333
ret
334
335
; function to print pokemon level, leaving off the ":L" if the level is at least 100
336
; INPUT:
337
; hl = destination address
338
; [wLoadedMonLevel] = level
339
PrintLevel::
340
ld a, "<LV>" ; ":L" tile ID
341
ld [hli], a
342
ld c, 2 ; number of digits
343
ld a, [wLoadedMonLevel] ; level
344
cp 100
345
jr c, PrintLevelCommon
346
; if level at least 100, write over the ":L" tile
347
dec hl
348
inc c ; increment number of digits to 3
349
jr PrintLevelCommon
350
351
; prints the level without leaving off ":L" regardless of level
352
; INPUT:
353
; hl = destination address
354
; [wLoadedMonLevel] = level
355
PrintLevelFull::
356
ld a, "<LV>" ; ":L" tile ID
357
ld [hli], a
358
ld c, 3 ; number of digits
359
ld a, [wLoadedMonLevel] ; level
360
361
PrintLevelCommon::
362
ld [wTempByteValue], a
363
ld de, wTempByteValue
364
ld b, LEFT_ALIGN | 1 ; 1 byte
365
jp PrintNumber
366
367
GetwMoves::
368
; Unused. Returns the move at index a from wMoves in a
369
ld hl, wMoves
370
ld c, a
371
ld b, 0
372
add hl, bc
373
ld a, [hl]
374
ret
375
376
; copies the base stat data of a pokemon to wMonHeader
377
; INPUT:
378
; [wCurSpecies] = pokemon ID
379
GetMonHeader::
380
ldh a, [hLoadedROMBank]
381
push af
382
ld a, BANK(BaseStats)
383
ldh [hLoadedROMBank], a
384
ld [rROMB], a
385
push bc
386
push de
387
push hl
388
ld a, [wPokedexNum]
389
push af
390
ld a, [wCurSpecies]
391
ld [wPokedexNum], a
392
ld de, FossilKabutopsPic
393
ld b, $66 ; size of Kabutops fossil and Ghost sprites
394
cp FOSSIL_KABUTOPS ; Kabutops fossil
395
jr z, .specialID
396
ld de, GhostPic
397
cp MON_GHOST ; Ghost
398
jr z, .specialID
399
ld de, FossilAerodactylPic
400
ld b, $77 ; size of Aerodactyl fossil sprite
401
cp FOSSIL_AERODACTYL ; Aerodactyl fossil
402
jr z, .specialID
403
cp MEW
404
jr z, .mew
405
predef IndexToPokedex
406
ld a, [wPokedexNum]
407
dec a
408
ld bc, BASE_DATA_SIZE
409
ld hl, BaseStats
410
call AddNTimes
411
ld de, wMonHeader
412
ld bc, BASE_DATA_SIZE
413
call CopyData
414
jr .done
415
.specialID
416
ld hl, wMonHSpriteDim
417
ld [hl], b ; write sprite dimensions
418
inc hl
419
ld [hl], e ; write front sprite pointer
420
inc hl
421
ld [hl], d
422
jr .done
423
.mew
424
ld hl, MewBaseStats
425
ld de, wMonHeader
426
ld bc, BASE_DATA_SIZE
427
ld a, BANK(MewBaseStats)
428
call FarCopyData
429
.done
430
ld a, [wCurSpecies]
431
ld [wMonHIndex], a
432
pop af
433
ld [wPokedexNum], a
434
pop hl
435
pop de
436
pop bc
437
pop af
438
ldh [hLoadedROMBank], a
439
ld [rROMB], a
440
ret
441
442
; copy party pokemon's name to wNameBuffer
443
GetPartyMonName2::
444
ld a, [wWhichPokemon] ; index within party
445
ld hl, wPartyMonNicks
446
447
; this is called more often
448
GetPartyMonName::
449
push hl
450
push bc
451
call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times
452
ld de, wNameBuffer
453
push de
454
ld bc, NAME_LENGTH
455
call CopyData
456
pop de
457
pop bc
458
pop hl
459
ret
460
461