-
Notifications
You must be signed in to change notification settings - Fork 993
/
player_animations.asm
525 lines (490 loc) · 12 KB
/
player_animations.asm
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
EnterMapAnim::
call InitFacingDirectionList
ld a, $ec
ld [wSpritePlayerStateData1YPixels], a
call Delay3
push hl
call GBFadeInFromWhite
ld hl, wStatusFlags7
bit BIT_USED_FLY, [hl]
res BIT_USED_FLY, [hl]
jr nz, .flyAnimation
ld a, SFX_TELEPORT_ENTER_1
call PlaySound
ld hl, wStatusFlags6
bit BIT_DUNGEON_WARP, [hl]
res BIT_DUNGEON_WARP, [hl]
pop hl
jr nz, .dungeonWarpAnimation
call PlayerSpinWhileMovingDown
ld a, SFX_TELEPORT_ENTER_2
call PlaySound
call IsPlayerStandingOnWarpPadOrHole
ld a, b
and a
jr nz, .done
; if the player is not standing on a warp pad or hole
ld hl, wPlayerSpinInPlaceAnimFrameDelay
xor a
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelay
inc a
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayDelta
ld a, $8
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayEndValue
ld [hl], $ff ; wPlayerSpinInPlaceAnimSoundID
ld hl, wFacingDirectionList
call PlayerSpinInPlace
.restoreDefaultMusic
call PlayDefaultMusic
.done
jp RestoreFacingDirectionAndYScreenPos
.dungeonWarpAnimation
ld c, 50
call DelayFrames
call PlayerSpinWhileMovingDown
jr .done
.flyAnimation
pop hl
ld de, BirdSprite
ld hl, vNPCSprites
lb bc, BANK(BirdSprite), $0c
call CopyVideoData
call LoadBirdSpriteGraphics
ld a, SFX_FLY
call PlaySound
ld hl, wFlyAnimUsingCoordList
xor a ; is using coord list
ld [hli], a ; wFlyAnimUsingCoordList
ld a, 12
ld [hli], a ; wFlyAnimCounter
ld [hl], $8 ; wFlyAnimBirdSpriteImageIndex (facing right)
ld de, FlyAnimationEnterScreenCoords
call DoFlyAnimation
call LoadPlayerSpriteGraphics
jr .restoreDefaultMusic
FlyAnimationEnterScreenCoords:
; y, x pairs
; This is the sequence of screen coordinates used by the overworld
; Fly animation when the player is entering a map.
db $05, $98
db $0F, $90
db $18, $88
db $20, $80
db $27, $78
db $2D, $70
db $32, $68
db $36, $60
db $39, $58
db $3B, $50
db $3C, $48
db $3C, $40
PlayerSpinWhileMovingDown:
ld hl, wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $10
ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $3c
ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimMaxY
call GetPlayerTeleportAnimFrameDelay
ld [hl], a ; wPlayerSpinWhileMovingUpOrDownAnimFrameDelay
jp PlayerSpinWhileMovingUpOrDown
_LeaveMapAnim::
call InitFacingDirectionList
call IsPlayerStandingOnWarpPadOrHole
ld a, b
and a
jr z, .playerNotStandingOnWarpPadOrHole
dec a
jp nz, LeaveMapThroughHoleAnim
.spinWhileMovingUp
ld a, SFX_TELEPORT_EXIT_1
call PlaySound
ld hl, wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, -$10
ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimDeltaY
ld a, $ec
ld [hli], a ; wPlayerSpinWhileMovingUpOrDownAnimMaxY
call GetPlayerTeleportAnimFrameDelay
ld [hl], a ; wPlayerSpinWhileMovingUpOrDownAnimFrameDelay
call PlayerSpinWhileMovingUpOrDown
call IsPlayerStandingOnWarpPadOrHole
ld a, b
dec a
jr z, .playerStandingOnWarpPad
; if not standing on a warp pad, there is an extra delay
ld c, 10
call DelayFrames
.playerStandingOnWarpPad
call GBFadeOutToWhite
jp RestoreFacingDirectionAndYScreenPos
.playerNotStandingOnWarpPadOrHole
ld a, $4
call StopMusic
ld a, [wStatusFlags6]
bit BIT_ESCAPE_WARP, a
jr z, .flyAnimation
; if going to the last used pokemon center
ld hl, wPlayerSpinInPlaceAnimFrameDelay
ld a, 16
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelay
ld a, -1
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayDelta
xor a
ld [hli], a ; wPlayerSpinInPlaceAnimFrameDelayEndValue
ld [hl], SFX_TELEPORT_EXIT_2 ; wPlayerSpinInPlaceAnimSoundID
ld hl, wFacingDirectionList
call PlayerSpinInPlace
jr .spinWhileMovingUp
.flyAnimation
call LoadBirdSpriteGraphics
ld hl, wFlyAnimUsingCoordList
ld a, $ff ; is not using coord list (flap in place)
ld [hli], a ; wFlyAnimUsingCoordList
ld a, 8
ld [hli], a ; wFlyAnimCounter
ld [hl], $c ; wFlyAnimBirdSpriteImageIndex
call DoFlyAnimation
ld a, SFX_FLY
call PlaySound
ld hl, wFlyAnimUsingCoordList
xor a ; is using coord list
ld [hli], a ; wFlyAnimUsingCoordList
ld a, $c
ld [hli], a ; wFlyAnimCounter
ld [hl], $c ; wFlyAnimBirdSpriteImageIndex (facing right)
ld de, FlyAnimationScreenCoords1
call DoFlyAnimation
ld c, 40
call DelayFrames
ld hl, wFlyAnimCounter
ld a, 11
ld [hli], a ; wFlyAnimCounter
ld [hl], $8 ; wFlyAnimBirdSpriteImageIndex (facing left)
ld de, FlyAnimationScreenCoords2
call DoFlyAnimation
call GBFadeOutToWhite
jp RestoreFacingDirectionAndYScreenPos
FlyAnimationScreenCoords1:
; y, x pairs
; This is the sequence of screen coordinates used by the first part
; of the Fly overworld animation.
db $3C, $48
db $3C, $50
db $3B, $58
db $3A, $60
db $39, $68
db $37, $70
db $37, $78
db $33, $80
db $30, $88
db $2D, $90
db $2A, $98
db $27, $A0
FlyAnimationScreenCoords2:
; y, x pairs
; This is the sequence of screen coordinates used by the second part
; of the Fly overworld animation.
db $1A, $90
db $19, $80
db $17, $70
db $15, $60
db $12, $50
db $0F, $40
db $0C, $30
db $09, $20
db $05, $10
db $00, $00
db $F0, $00
LeaveMapThroughHoleAnim:
ld a, $ff
ld [wUpdateSpritesEnabled], a ; disable UpdateSprites
; shift upper half of player's sprite down 8 pixels and hide lower half
ld a, [wShadowOAMSprite00TileID]
ld [wShadowOAMSprite02TileID], a
ld a, [wShadowOAMSprite01TileID]
ld [wShadowOAMSprite03TileID], a
ld a, $a0
ld [wShadowOAMSprite00YCoord], a
ld [wShadowOAMSprite01YCoord], a
ld c, 2
call DelayFrames
; hide upper half of player's sprite
ld a, $a0
ld [wShadowOAMSprite02YCoord], a
ld [wShadowOAMSprite03YCoord], a
call GBFadeOutToWhite
ld a, $1
ld [wUpdateSpritesEnabled], a ; enable UpdateSprites
jp RestoreFacingDirectionAndYScreenPos
DoFlyAnimation:
ld a, [wFlyAnimBirdSpriteImageIndex]
xor $1 ; make the bird flap its wings
ld [wFlyAnimBirdSpriteImageIndex], a
ld [wSpritePlayerStateData1ImageIndex], a
call Delay3
ld a, [wFlyAnimUsingCoordList]
cp $ff
jr z, .skipCopyingCoords ; if the bird is flapping its wings in place
ld hl, wSpritePlayerStateData1YPixels
ld a, [de]
inc de
ld [hli], a ; y
inc hl
ld a, [de]
inc de
ld [hl], a ; x
.skipCopyingCoords
ld a, [wFlyAnimCounter]
dec a
ld [wFlyAnimCounter], a
jr nz, DoFlyAnimation
ret
LoadBirdSpriteGraphics:
ld de, BirdSprite
ld hl, vNPCSprites
lb bc, BANK(BirdSprite), 12
call CopyVideoData
ld de, BirdSprite tile 12 ; moving animation sprite
ld hl, vNPCSprites2
lb bc, BANK(BirdSprite), 12
jp CopyVideoData
InitFacingDirectionList:
ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
ld [wSavedPlayerFacingDirection], a
ld a, [wSpritePlayerStateData1YPixels]
ld [wSavedPlayerScreenY], a
ld hl, PlayerSpinningFacingOrder
ld de, wFacingDirectionList
ld bc, 4
call CopyData
ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
ld hl, wFacingDirectionList
; find the place in the list that matches the current facing direction
.loop
cp [hl]
inc hl
jr nz, .loop
dec hl
ret
PlayerSpinningFacingOrder:
; The order of the direction the player's sprite is facing when teleporting
; away. Creates a spinning effect.
db SPRITE_FACING_DOWN, SPRITE_FACING_LEFT, SPRITE_FACING_UP, SPRITE_FACING_RIGHT
SpinPlayerSprite:
; copy the current value from the list into the sprite data and rotate the list
ld a, [hl]
ld [wSpritePlayerStateData1ImageIndex], a ; (image index is locked to standing images)
push hl
ld hl, wFacingDirectionList
ld de, wFacingDirectionList - 1
ld bc, 4
call CopyData
ld a, [wFacingDirectionList - 1]
ld [wFacingDirectionList + 3], a
pop hl
ret
PlayerSpinInPlace:
call SpinPlayerSprite
ld a, [wPlayerSpinInPlaceAnimFrameDelay]
ld c, a
and $3
jr nz, .skipPlayingSound
; when the last delay was a multiple of 4, play a sound if there is one
ld a, [wPlayerSpinInPlaceAnimSoundID]
cp $ff
call nz, PlaySound
.skipPlayingSound
ld a, [wPlayerSpinInPlaceAnimFrameDelayDelta]
add c
ld [wPlayerSpinInPlaceAnimFrameDelay], a
ld c, a
ld a, [wPlayerSpinInPlaceAnimFrameDelayEndValue]
cp c
ret z
call DelayFrames
jr PlayerSpinInPlace
PlayerSpinWhileMovingUpOrDown:
call SpinPlayerSprite
ld a, [wPlayerSpinWhileMovingUpOrDownAnimDeltaY]
ld c, a
ld a, [wSpritePlayerStateData1YPixels]
add c
ld [wSpritePlayerStateData1YPixels], a
ld c, a
ld a, [wPlayerSpinWhileMovingUpOrDownAnimMaxY]
cp c
ret z
ld a, [wPlayerSpinWhileMovingUpOrDownAnimFrameDelay]
ld c, a
call DelayFrames
jr PlayerSpinWhileMovingUpOrDown
RestoreFacingDirectionAndYScreenPos:
ld a, [wSavedPlayerScreenY]
ld [wSpritePlayerStateData1YPixels], a
ld a, [wSavedPlayerFacingDirection]
ld [wSpritePlayerStateData1ImageIndex], a ; (image index is locked to standing images)
ret
; if SGB, 2 frames, else 3 frames
GetPlayerTeleportAnimFrameDelay:
ld a, [wOnSGB]
xor $1
inc a
inc a
ret
IsPlayerStandingOnWarpPadOrHole::
ld b, 0
ld hl, WarpPadAndHoleData
ld a, [wCurMapTileset]
ld c, a
.loop
ld a, [hli]
cp $ff
jr z, .done
cp c
jr nz, .nextEntry
lda_coord 8, 9
cp [hl]
jr z, .foundMatch
.nextEntry
inc hl
inc hl
jr .loop
.foundMatch
inc hl
ld b, [hl]
.done
ld a, b
ld [wStandingOnWarpPadOrHole], a
ret
INCLUDE "data/tilesets/warp_pad_hole_tile_ids.asm"
FishingAnim:
ld c, 10
call DelayFrames
ld hl, wMovementFlags
set BIT_LEDGE_OR_FISHING, [hl]
ld de, RedSprite
ld hl, vNPCSprites tile $00
lb bc, BANK(RedSprite), 12
call CopyVideoData
ld a, $4
ld hl, RedFishingTiles
call LoadAnimSpriteGfx
ld a, [wSpritePlayerStateData1ImageIndex]
ld c, a
ld b, $0
ld hl, FishingRodOAM
add hl, bc
ld de, wShadowOAMSprite39
ld bc, $4
call CopyData
ld c, 100
call DelayFrames
ld a, [wRodResponse]
and a
ld hl, NoNibbleText
jr z, .done
cp $2
ld hl, NothingHereText
jr z, .done
; there was a bite
; shake the player's sprite vertically
ld b, 10
.loop
ld hl, wSpritePlayerStateData1YPixels
call .ShakePlayerSprite
ld hl, wShadowOAMSprite39
call .ShakePlayerSprite
call Delay3
dec b
jr nz, .loop
; If the player is facing up, hide the fishing rod so it doesn't overlap with
; the exclamation bubble that will be shown next.
ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
cp SPRITE_FACING_UP
jr nz, .skipHidingFishingRod
ld a, $a0
ld [wShadowOAMSprite39YCoord], a
.skipHidingFishingRod
ld hl, wEmotionBubbleSpriteIndex
xor a
ld [hli], a ; player's sprite
ld [hl], a ; EXCLAMATION_BUBBLE
predef EmotionBubble
; If the player is facing up, unhide the fishing rod.
ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
cp SPRITE_FACING_UP
jr nz, .skipUnhidingFishingRod
ld a, $44
ld [wShadowOAMSprite39YCoord], a
.skipUnhidingFishingRod
ld hl, ItsABiteText
.done
call PrintText
ld hl, wMovementFlags
res BIT_LEDGE_OR_FISHING, [hl]
call LoadFontTilePatterns
ret
.ShakePlayerSprite
ld a, [hl]
xor $1
ld [hl], a
ret
NoNibbleText:
text_far _NoNibbleText
text_end
NothingHereText:
text_far _NothingHereText
text_end
ItsABiteText:
text_far _ItsABiteText
text_end
FishingRodOAM:
; specifies how the fishing rod should be drawn on the screen
dbsprite 9, 11, 4, 3, $fd, 0 ; down
dbsprite 9, 8, 4, 4, $fd, 0 ; up
dbsprite 8, 10, 0, 0, $fe, 0 ; left
dbsprite 11, 10, 0, 0, $fe, OAM_HFLIP ; right
MACRO fishing_gfx
dw \1
db \2
db BANK(\1)
dw vNPCSprites tile \3
ENDM
RedFishingTiles:
fishing_gfx RedFishingTilesFront, 2, $02
fishing_gfx RedFishingTilesBack, 2, $06
fishing_gfx RedFishingTilesSide, 2, $0a
fishing_gfx RedFishingRodTiles, 3, $fd
_HandleMidJump::
ld a, [wPlayerJumpingYScreenCoordsIndex]
ld c, a
inc a
cp $10
jr nc, .finishedJump
ld [wPlayerJumpingYScreenCoordsIndex], a
ld b, 0
ld hl, PlayerJumpingYScreenCoords
add hl, bc
ld a, [hl]
ld [wSpritePlayerStateData1YPixels], a
ret
.finishedJump
ld a, [wWalkCounter]
cp 0
ret nz
call UpdateSprites
call Delay3
xor a
ldh [hJoyHeld], a
ldh [hJoyPressed], a
ldh [hJoyReleased], a
ld [wPlayerJumpingYScreenCoordsIndex], a
ld hl, wMovementFlags
res BIT_LEDGE_OR_FISHING, [hl]
ld hl, wStatusFlags5
res BIT_SCRIPTED_MOVEMENT_STATE, [hl]
xor a
ld [wJoyIgnore], a
ret
PlayerJumpingYScreenCoords:
; Sequence of y screen coordinates for player's sprite when jumping over a ledge.
db $38, $36, $34, $32, $31, $30, $30, $30, $31, $32, $33, $34, $36, $38, $3C, $3C