Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/battle/animations.asm
2019 views
1
; Draws a "frame block". Frame blocks are blocks of tiles that are put
2
; together to form frames in battle animations.
3
DrawFrameBlock:
4
ld l, c
5
ld h, b
6
ld a, [hli]
7
ld [wNumFBTiles], a
8
ld a, [wFBDestAddr + 1]
9
ld e, a
10
ld a, [wFBDestAddr]
11
ld d, a
12
xor a
13
ld [wFBTileCounter], a ; loop counter
14
.loop
15
ld a, [wFBTileCounter]
16
inc a
17
ld [wFBTileCounter], a
18
ld a, [wSubAnimTransform]
19
dec a
20
jr z, .flipHorizontalAndVertical ; SUBANIMTYPE_HVFLIP
21
dec a
22
jp z, .flipHorizontalTranslateDown ; SUBANIMTYPE_HFLIP
23
dec a
24
jr z, .flipBaseCoords ; SUBANIMTYPE_COORDFLIP
25
; no transformation
26
ld a, [wBaseCoordY]
27
add [hl]
28
ld [de], a ; store Y
29
inc hl
30
inc de
31
ld a, [wBaseCoordX]
32
jr .finishCopying
33
.flipBaseCoords
34
ld a, [wBaseCoordY]
35
ld b, a
36
ld a, 136
37
sub b ; flip Y base coordinate
38
add [hl] ; Y offset
39
ld [de], a ; store Y
40
inc hl
41
inc de
42
ld a, [wBaseCoordX]
43
ld b, a
44
ld a, 168
45
sub b ; flip X base coordinate
46
.finishCopying ; finish copying values to OAM (when subanimation not transformed)
47
add [hl] ; X offset
48
ld [de], a ; store X
49
inc hl
50
inc de
51
ld a, [hli]
52
add $31 ; base tile ID for battle animations
53
ld [de], a ; store tile ID
54
inc de
55
ld a, [hli]
56
ld [de], a ; store flags
57
inc de
58
jp .nextTile
59
.flipHorizontalAndVertical
60
ld a, [wBaseCoordY]
61
add [hl] ; Y offset
62
ld b, a
63
ld a, 136
64
sub b ; flip Y coordinate
65
ld [de], a ; store Y
66
inc hl
67
inc de
68
ld a, [wBaseCoordX]
69
add [hl] ; X offset
70
ld b, a
71
ld a, 168
72
sub b ; flip X coordinate
73
ld [de], a ; store X
74
inc hl
75
inc de
76
ld a, [hli]
77
add $31 ; base tile ID for battle animations
78
ld [de], a ; store tile ID
79
inc de
80
; toggle horizontal and vertical flip
81
ld a, [hli] ; flags
82
and a
83
ld b, OAM_YFLIP | OAM_XFLIP
84
jr z, .storeFlags1
85
cp OAM_XFLIP
86
ld b, OAM_YFLIP
87
jr z, .storeFlags1
88
cp OAM_YFLIP
89
ld b, OAM_XFLIP
90
jr z, .storeFlags1
91
ld b, 0
92
.storeFlags1
93
ld a, b
94
ld [de], a
95
inc de
96
jp .nextTile
97
.flipHorizontalTranslateDown
98
ld a, [wBaseCoordY]
99
add [hl]
100
add 40 ; translate Y coordinate downwards
101
ld [de], a ; store Y
102
inc hl
103
inc de
104
ld a, [wBaseCoordX]
105
add [hl]
106
ld b, a
107
ld a, 168
108
sub b ; flip X coordinate
109
ld [de], a ; store X
110
inc hl
111
inc de
112
ld a, [hli]
113
add $31 ; base tile ID for battle animations
114
ld [de], a ; store tile ID
115
inc de
116
ld a, [hli]
117
bit B_OAM_XFLIP, a
118
jr nz, .disableHorizontalFlip
119
.enableHorizontalFlip
120
set B_OAM_XFLIP, a
121
jr .storeFlags2
122
.disableHorizontalFlip
123
res B_OAM_XFLIP, a
124
.storeFlags2
125
ld [de], a
126
inc de
127
.nextTile
128
ld a, [wFBTileCounter]
129
ld c, a
130
ld a, [wNumFBTiles]
131
cp c
132
jp nz, .loop ; go back up if there are more tiles to draw
133
; after drawing tiles
134
ld a, [wFBMode]
135
cp FRAMEBLOCKMODE_02
136
jr z, .advanceFrameBlockDestAddr ; skip delay and don't clean OAM buffer
137
ld a, [wSubAnimFrameDelay]
138
ld c, a
139
call DelayFrames
140
ld a, [wFBMode]
141
cp FRAMEBLOCKMODE_03
142
jr z, .advanceFrameBlockDestAddr ; skip cleaning OAM buffer
143
cp FRAMEBLOCKMODE_04
144
jr z, .done ; skip cleaning OAM buffer and don't advance the frame block destination address
145
ld a, [wAnimationID]
146
cp GROWL
147
jr z, .resetFrameBlockDestAddr
148
call AnimationCleanOAM
149
.resetFrameBlockDestAddr
150
ld hl, wShadowOAM
151
ld a, l
152
ld [wFBDestAddr + 1], a
153
ld a, h
154
ld [wFBDestAddr], a ; set destination address to beginning of OAM buffer
155
ret
156
.advanceFrameBlockDestAddr
157
ld a, e
158
ld [wFBDestAddr + 1], a
159
ld a, d
160
ld [wFBDestAddr], a
161
.done
162
ret
163
164
PlayAnimation:
165
xor a
166
ldh [hROMBankTemp], a ; it looks like nothing reads this
167
ld [wSubAnimTransform], a
168
ld a, [wAnimationID] ; get animation number
169
dec a
170
ld l, a
171
ld h, 0
172
add hl, hl
173
ld de, AttackAnimationPointers ; animation command stream pointers
174
add hl, de
175
ld a, [hli]
176
ld h, [hl]
177
ld l, a
178
.animationLoop
179
vc_hook Stop_reducing_move_anim_flashing_Thunderbolt
180
ld a, [hli]
181
vc_hook_red Stop_reducing_move_anim_flashing_Reflect
182
vc_hook_blue Stop_reducing_move_anim_flashing_Self_Destruct
183
cp -1
184
vc_hook_blue Stop_reducing_move_anim_flashing_Reflect
185
jr z, .AnimationOver
186
cp FIRST_SE_ID ; is this subanimation or a special effect?
187
jr c, .playSubanimation
188
; do Special Effect
189
ld c, a
190
ld de, SpecialEffectPointers
191
.searchSpecialEffectTableLoop
192
ld a, [de]
193
cp c
194
jr z, .foundMatch
195
inc de
196
inc de
197
inc de
198
jr .searchSpecialEffectTableLoop
199
.foundMatch
200
ld a, [hli]
201
cp NO_MOVE - 1 ; is there a sound to play?
202
jr z, .skipPlayingSound
203
ld [wAnimSoundID], a ; store sound
204
push hl
205
push de
206
call GetMoveSound
207
call PlaySound
208
pop de
209
pop hl
210
.skipPlayingSound
211
push hl
212
inc de
213
ld a, [de]
214
ld l, a
215
inc de
216
ld a, [de]
217
ld h, a
218
ld de, .nextAnimationCommand
219
push de
220
jp hl ; jump to special effect function
221
.playSubanimation
222
ld c, a
223
and %00111111
224
ld [wSubAnimFrameDelay], a
225
xor a
226
sla c
227
rla
228
sla c
229
rla
230
ld [wWhichBattleAnimTileset], a
231
ld a, [hli] ; sound
232
ld [wAnimSoundID], a ; store sound
233
ld a, [hli] ; subanimation ID
234
ld c, l
235
ld b, h
236
ld l, a
237
ld h, 0
238
add hl, hl
239
ld de, SubanimationPointers
240
add hl, de
241
ld a, l
242
ld [wSubAnimAddrPtr], a
243
ld a, h
244
ld [wSubAnimAddrPtr + 1], a
245
ld l, c
246
ld h, b
247
push hl
248
ldh a, [rOBP0]
249
push af
250
ld a, [wAnimPalette]
251
ldh [rOBP0], a
252
call LoadMoveAnimationTiles
253
vc_hook Reduce_move_anim_flashing_Mega_Punch_Self_Destruct_Explosion
254
call LoadSubanimation
255
call PlaySubanimation
256
vc_hook_red Stop_reducing_move_anim_flashing_Mega_Punch
257
vc_hook_blue Stop_reducing_move_anim_flashing_Mega_Punch_Explosion
258
pop af
259
vc_hook_red Stop_reducing_move_anim_flashing_Blizzard
260
ldh [rOBP0], a
261
.nextAnimationCommand
262
vc_hook_red Stop_reducing_move_anim_flashing_Hyper_Beam
263
vc_hook_blue Stop_reducing_move_anim_flashing_Bubblebeam_Hyper_Beam_Blizzard
264
pop hl
265
vc_hook Stop_reducing_move_anim_flashing_Guillotine
266
jr .animationLoop
267
.AnimationOver
268
ret
269
270
LoadSubanimation:
271
vc_hook Reduce_move_anim_flashing_Guillotine
272
ld a, [wSubAnimAddrPtr + 1]
273
vc_hook Reduce_move_anim_flashing_Mega_Kick
274
ld h, a
275
vc_hook_red Reduce_move_anim_flashing_Blizzard
276
ld a, [wSubAnimAddrPtr]
277
vc_hook_red Reduce_move_anim_flashing_Self_Destruct
278
ld l, a
279
ld a, [hli]
280
ld e, a
281
vc_hook Reduce_move_anim_flashing_Explosion
282
ld a, [hl]
283
vc_hook Reduce_move_anim_flashing_Thunderbolt
284
ld d, a ; de = address of subanimation
285
ld a, [de]
286
vc_hook_blue Reduce_move_anim_flashing_Rock_Slide
287
ld b, a
288
vc_hook Reduce_move_anim_flashing_Spore
289
and %00011111
290
vc_hook Reduce_move_anim_flashing_Bubblebeam
291
ld [wSubAnimCounter], a ; number of frame blocks
292
vc_hook_red Reduce_move_anim_flashing_Rock_Slide
293
vc_hook_blue Reduce_move_anim_flashing_Self_Destruct
294
ld a, b
295
and %11100000
296
cp SUBANIMTYPE_ENEMY << 5
297
vc_hook_blue Reduce_move_anim_flashing_Blizzard
298
jr nz, .isNotTypeEnemy
299
; subanim type enemy
300
call GetSubanimationTransform2
301
jr .saveTransformation
302
.isNotTypeEnemy
303
vc_hook Reduce_move_anim_flashing_Hyper_Beam
304
call GetSubanimationTransform1
305
.saveTransformation
306
; place the upper 3 bits of a into bits 0-2 of a before storing
307
srl a
308
swap a
309
ld [wSubAnimTransform], a
310
cp SUBANIMTYPE_REVERSE
311
ld hl, 0
312
jr nz, .storeSubentryAddr
313
; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
314
ld a, [wSubAnimCounter]
315
dec a
316
ld bc, 3
317
.loop
318
add hl, bc
319
dec a
320
jr nz, .loop
321
.storeSubentryAddr
322
inc de
323
add hl, de
324
ld a, l
325
ld [wSubAnimSubEntryAddr], a
326
ld a, h
327
ld [wSubAnimSubEntryAddr + 1], a
328
ret
329
330
; called if the subanimation type is not SUBANIMTYPE_ENEMY
331
; sets the transform to SUBANIMTYPE_NORMAL if it's the player's turn
332
; sets the transform to the subanimation type if it's the enemy's turn
333
GetSubanimationTransform1:
334
vc_hook Reduce_move_anim_flashing_Reflect
335
ld b, a
336
ldh a, [hWhoseTurn]
337
and a
338
ld a, b
339
ret nz
340
xor a ; SUBANIMTYPE_NORMAL << 5
341
ret
342
343
; called if the subanimation type is SUBANIMTYPE_ENEMY
344
; sets the transform to SUBANIMTYPE_HFLIP if it's the player's turn
345
; sets the transform to SUBANIMTYPE_NORMAL if it's the enemy's turn
346
GetSubanimationTransform2:
347
ldh a, [hWhoseTurn]
348
and a
349
ld a, SUBANIMTYPE_HFLIP << 5
350
ret z
351
xor a ; SUBANIMTYPE_NORMAL << 5
352
ret
353
354
; loads tile patterns for battle animations
355
LoadMoveAnimationTiles:
356
ld a, [wWhichBattleAnimTileset]
357
add a
358
add a
359
ld hl, MoveAnimationTilesPointers
360
ld e, a
361
ld d, 0
362
add hl, de
363
ld a, [hli]
364
ld [wTempTilesetNumTiles], a ; number of tiles
365
ld a, [hli]
366
ld e, a
367
ld a, [hl]
368
ld d, a ; de = address of tileset
369
ld hl, vSprites tile $31
370
ld b, BANK(MoveAnimationTiles0) ; ROM bank
371
ld a, [wTempTilesetNumTiles]
372
ld c, a ; number of tiles
373
jp CopyVideoData ; load tileset
374
375
MACRO anim_tileset
376
db \1
377
dw \2
378
db -1 ; padding
379
ENDM
380
381
MoveAnimationTilesPointers:
382
; number of tiles, gfx pointer
383
anim_tileset 79, MoveAnimationTiles0
384
anim_tileset 79, MoveAnimationTiles1
385
anim_tileset 64, MoveAnimationTiles2
386
387
MoveAnimationTiles0:
388
MoveAnimationTiles2:
389
INCBIN "gfx/battle/move_anim_0.2bpp"
390
391
MoveAnimationTiles1:
392
INCBIN "gfx/battle/move_anim_1.2bpp"
393
394
SlotMachineTiles2:
395
IF DEF(_RED)
396
INCBIN "gfx/slots/red_slots_2.2bpp"
397
ENDC
398
IF DEF(_BLUE)
399
INCBIN "gfx/slots/blue_slots_2.2bpp"
400
ENDC
401
SlotMachineTiles2End:
402
403
MoveAnimation:
404
push hl
405
push de
406
push bc
407
push af
408
call WaitForSoundToFinish
409
call SetAnimationPalette
410
ld a, [wAnimationID]
411
and a
412
jr z, .animationFinished
413
414
; if throwing a Poké Ball, skip the regular animation code
415
cp TOSS_ANIM
416
jr nz, .moveAnimation
417
ld de, .animationFinished
418
push de
419
jp TossBallAnimation
420
421
.moveAnimation
422
; check if battle animations are disabled in the options
423
ld a, [wOptions]
424
bit BIT_BATTLE_ANIMATION, a
425
jr nz, .animationsDisabled
426
call ShareMoveAnimations
427
call PlayAnimation
428
vc_hook_red Stop_reducing_move_anim_flashing_Bubblebeam_Mega_Kick
429
vc_hook_blue Stop_reducing_move_anim_flashing_Spore
430
jr .next
431
.animationsDisabled
432
ld c, 30
433
call DelayFrames
434
.next
435
vc_hook_red Stop_reducing_move_anim_flashing
436
vc_hook_blue Stop_reducing_move_anim_flashing_Rock_Slide_Dream_Eater
437
call PlayApplyingAttackAnimation ; shake the screen or flash the pic in and out (to show damage)
438
.animationFinished
439
call WaitForSoundToFinish
440
xor a
441
ld [wSubAnimSubEntryAddr], a
442
ld [wUnusedMoveAnimByte], a
443
ld [wSubAnimTransform], a
444
dec a ; NO_MOVE - 1
445
ld [wAnimSoundID], a
446
pop af
447
pop bc
448
pop de
449
pop hl
450
ret
451
452
ShareMoveAnimations:
453
; some moves just reuse animations from status conditions
454
ldh a, [hWhoseTurn]
455
and a
456
ret z
457
458
; opponent's turn
459
460
ld a, [wAnimationID]
461
462
cp AMNESIA
463
ld b, CONF_ANIM
464
jr z, .replaceAnim
465
466
cp REST
467
ld b, SLP_ANIM
468
ret nz
469
470
.replaceAnim
471
ld a, b
472
ld [wAnimationID], a
473
ret
474
475
PlayApplyingAttackAnimation:
476
; Generic animation that shows after the move's individual animation
477
; Different animation depending on whether the move has an additional effect and on whose turn it is
478
ld a, [wAnimationType]
479
and a
480
ret z
481
dec a
482
add a
483
ld c, a
484
ld b, 0
485
ld hl, AnimationTypePointerTable
486
add hl, bc
487
ld a, [hli]
488
ld h, [hl]
489
ld l, a
490
jp hl
491
492
AnimationTypePointerTable:
493
dw ShakeScreenVertically ; enemy mon has used a damaging move without a side effect
494
dw ShakeScreenHorizontallyHeavy ; enemy mon has used a damaging move with a side effect
495
dw ShakeScreenHorizontallySlow ; enemy mon has used a non-damaging move
496
dw BlinkEnemyMonSprite ; player mon has used a damaging move without a side effect
497
dw ShakeScreenHorizontallyLight ; player mon has used a damaging move with a side effect
498
dw ShakeScreenHorizontallySlow2 ; player mon has used a non-damaging move
499
500
ShakeScreenVertically:
501
call PlayApplyingAttackSound
502
ld b, 8
503
jp AnimationShakeScreenVertically
504
505
ShakeScreenHorizontallyHeavy:
506
call PlayApplyingAttackSound
507
ld b, 8
508
jp AnimationShakeScreenHorizontallyFast
509
510
ShakeScreenHorizontallySlow:
511
lb bc, 6, 2
512
jr AnimationShakeScreenHorizontallySlow
513
514
BlinkEnemyMonSprite:
515
call PlayApplyingAttackSound
516
jp AnimationBlinkEnemyMon
517
518
ShakeScreenHorizontallyLight:
519
call PlayApplyingAttackSound
520
ld b, 2
521
jp AnimationShakeScreenHorizontallyFast
522
523
ShakeScreenHorizontallySlow2:
524
lb bc, 3, 2
525
526
AnimationShakeScreenHorizontallySlow:
527
push bc
528
push bc
529
.loop1
530
ldh a, [rWX]
531
inc a
532
ldh [rWX], a
533
ld c, 2
534
call DelayFrames
535
dec b
536
jr nz, .loop1
537
pop bc
538
.loop2
539
ldh a, [rWX]
540
dec a
541
ldh [rWX], a
542
ld c, 2
543
call DelayFrames
544
dec b
545
jr nz, .loop2
546
pop bc
547
dec c
548
jr nz, AnimationShakeScreenHorizontallySlow
549
ret
550
551
SetAnimationPalette:
552
ld a, [wOnSGB]
553
and a
554
ld a, $e4
555
jr z, .notSGB
556
ld a, $f0
557
ld [wAnimPalette], a
558
ld b, $e4
559
ld a, [wAnimationID]
560
cp TRADE_BALL_DROP_ANIM
561
jr c, .next
562
cp TRADE_BALL_POOF_ANIM + 1
563
jr nc, .next
564
ld b, $f0
565
.next
566
ld a, b
567
ldh [rOBP0], a
568
ld a, $6c
569
ldh [rOBP1], a
570
ret
571
.notSGB
572
ld a, $e4
573
ld [wAnimPalette], a
574
vc_hook Reduce_move_anim_flashing_Dream_Eater
575
ldh [rOBP0], a
576
ld a, $6c
577
ldh [rOBP1], a
578
ret
579
580
PlaySubanimation:
581
ld a, [wAnimSoundID]
582
cp NO_MOVE - 1
583
jr z, .skipPlayingSound
584
call GetMoveSound
585
call PlaySound
586
.skipPlayingSound
587
ld hl, wShadowOAM
588
ld a, l
589
ld [wFBDestAddr + 1], a
590
ld a, h
591
ld [wFBDestAddr], a
592
ld a, [wSubAnimSubEntryAddr + 1]
593
ld h, a
594
ld a, [wSubAnimSubEntryAddr]
595
ld l, a
596
.loop
597
push hl
598
ld c, [hl] ; frame block ID
599
ld b, 0
600
ld hl, FrameBlockPointers
601
add hl, bc
602
add hl, bc
603
ld a, [hli]
604
ld c, a
605
ld a, [hli]
606
ld b, a
607
pop hl
608
inc hl
609
push hl
610
ld e, [hl] ; base coordinate ID
611
ld d, 0
612
ld hl, FrameBlockBaseCoords ; base coordinate table
613
add hl, de
614
add hl, de
615
ld a, [hli]
616
ld [wBaseCoordY], a
617
ld a, [hl]
618
ld [wBaseCoordX], a
619
pop hl
620
inc hl
621
ld a, [hl] ; frame block mode
622
ld [wFBMode], a
623
call DrawFrameBlock
624
call DoSpecialEffectByAnimationId ; run animation-specific function (if there is one)
625
ld a, [wSubAnimCounter]
626
dec a
627
ld [wSubAnimCounter], a
628
ret z
629
ld a, [wSubAnimSubEntryAddr + 1]
630
ld h, a
631
ld a, [wSubAnimSubEntryAddr]
632
ld l, a
633
ld a, [wSubAnimTransform]
634
cp SUBANIMTYPE_REVERSE
635
ld bc, 3
636
jr nz, .nextSubanimationSubentry
637
ld bc, -3
638
.nextSubanimationSubentry
639
add hl, bc
640
ld a, h
641
ld [wSubAnimSubEntryAddr + 1], a
642
ld a, l
643
ld [wSubAnimSubEntryAddr], a
644
jp .loop
645
646
AnimationCleanOAM:
647
push hl
648
push de
649
push bc
650
push af
651
call DelayFrame
652
call ClearSprites
653
pop af
654
pop bc
655
pop de
656
pop hl
657
ret
658
659
; this runs after each frame block is drawn in a subanimation
660
; it runs a particular special effect based on the animation ID
661
DoSpecialEffectByAnimationId:
662
push hl
663
push de
664
push bc
665
ld a, [wAnimationID]
666
ld hl, AnimationIdSpecialEffects
667
ld de, 3
668
call IsInArray
669
jr nc, .done
670
inc hl
671
ld a, [hli]
672
ld h, [hl]
673
ld l, a
674
ld de, .done
675
push de
676
jp hl
677
.done
678
pop bc
679
pop de
680
pop hl
681
ret
682
683
INCLUDE "data/battle_anims/special_effects.asm"
684
685
DoBallTossSpecialEffects:
686
ld a, [wCurItem]
687
cp ULTRA_BALL + 1 ; is it a Master Ball or Ultra Ball?
688
jr nc, .skipFlashingEffect
689
.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
690
ldh a, [rOBP0]
691
xor %00111100 ; complement colors 1 and 2
692
ldh [rOBP0], a
693
.skipFlashingEffect
694
ld a, [wSubAnimCounter]
695
cp 11 ; is it the beginning of the subanimation?
696
jr nz, .skipPlayingSound
697
; if it is the beginning of the subanimation, play a sound
698
ld a, SFX_BALL_TOSS
699
call PlaySound
700
.skipPlayingSound
701
ld a, [wIsInBattle]
702
cp 2 ; is it a trainer battle?
703
jr z, .isTrainerBattle
704
ld a, [wPokeBallAnimData]
705
cp $10 ; is the enemy pokemon the Ghost Marowak?
706
ret nz
707
; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
708
ld a, [wSubAnimCounter]
709
cp 3
710
jr z, .moveGhostMarowakLeft
711
cp 2
712
jr z, .moveGhostMarowakLeft
713
cp 1
714
ret nz
715
.moveGhostMarowakLeft
716
hlcoord 17, 0
717
ld de, 20
718
lb bc, 7, 7
719
.loop
720
push hl
721
push bc
722
call AnimCopyRowRight ; move row of tiles left
723
pop bc
724
pop hl
725
add hl, de
726
dec b
727
jr nz, .loop
728
ld a, %00001000
729
ldh [rAUD1SWEEP], a ; Channel 1 sweep register
730
ret
731
.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
732
ld a, [wSubAnimCounter]
733
cp 3
734
ret nz
735
dec a
736
ld [wSubAnimCounter], a
737
ret
738
739
DoBallShakeSpecialEffects:
740
ld a, [wSubAnimCounter]
741
cp 4 ; is it the beginning of a shake?
742
jr nz, .skipPlayingSound
743
; if it is the beginning of a shake, play a sound and wait 2/3 of a second
744
ld a, SFX_TINK
745
call PlaySound
746
ld c, 40
747
call DelayFrames
748
.skipPlayingSound
749
ld a, [wSubAnimCounter]
750
dec a
751
ret nz
752
; if it's the end of the ball shaking subanimation, check if more shakes are left and restart the subanimation
753
ld a, [wNumShakes] ; number of shakes
754
dec a ; decrement number of shakes
755
ld [wNumShakes], a
756
ret z
757
; if there are shakes left, restart the subanimation
758
ld a, [wSubAnimSubEntryAddr]
759
ld l, a
760
ld a, [wSubAnimSubEntryAddr + 1]
761
ld h, a
762
ld de, -(4 * 3) ; 4 subentries and 3 bytes per subentry
763
add hl, de
764
ld a, l
765
ld [wSubAnimSubEntryAddr], a
766
ld a, h
767
ld [wSubAnimSubEntryAddr + 1], a
768
ld a, 5 ; number of subentries in the ball shaking subanimation plus one
769
ld [wSubAnimCounter], a
770
ret
771
772
; plays a sound after the second frame of the poof animation
773
DoPoofSpecialEffects:
774
ld a, [wSubAnimCounter]
775
cp 5
776
ret nz
777
ld a, SFX_BALL_POOF
778
jp PlaySound
779
780
DoRockSlideSpecialEffects:
781
ld a, [wSubAnimCounter]
782
cp 12
783
ret nc
784
cp 8
785
jr nc, .shakeScreen
786
cp 1
787
jp z, AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
788
ret
789
; if the subanimation counter is between 8 and 11, shake the screen horizontally and vertically
790
.shakeScreen
791
ld b, 1
792
predef PredefShakeScreenHorizontally ; shake horizontally
793
ld b, 1
794
predef_jump PredefShakeScreenVertically ; shake vertically
795
796
FlashScreenEveryEightFrameBlocks:
797
ld a, [wSubAnimCounter]
798
and 7 ; is the subanimation counter exactly 8?
799
call z, AnimationFlashScreen ; if so, flash the screen
800
ret
801
802
; flashes the screen if the subanimation counter is divisible by 4
803
FlashScreenEveryFourFrameBlocks:
804
ld a, [wSubAnimCounter]
805
and 3
806
call z, AnimationFlashScreen
807
ret
808
809
; used for Explosion and Selfdestruct
810
DoExplodeSpecialEffects:
811
ld a, [wSubAnimCounter]
812
cp 1 ; is it the end of the subanimation?
813
jr nz, FlashScreenEveryFourFrameBlocks
814
; if it's the end of the subanimation, make the attacking pokemon disappear
815
hlcoord 1, 5
816
jp AnimationHideMonPic ; make pokemon disappear
817
818
; flashes the screen when subanimation counter is 1 modulo 4
819
DoBlizzardSpecialEffects:
820
ld a, [wSubAnimCounter]
821
cp 13
822
jp z, AnimationFlashScreen
823
cp 9
824
jp z, AnimationFlashScreen
825
cp 5
826
jp z, AnimationFlashScreen
827
cp 1
828
jp z, AnimationFlashScreen
829
ret
830
831
; flashes the screen at 3 points in the subanimation
832
; unused
833
FlashScreenUnused:
834
ld a, [wSubAnimCounter]
835
cp 14
836
jp z, AnimationFlashScreen
837
cp 9
838
jp z, AnimationFlashScreen
839
cp 2
840
jp z, AnimationFlashScreen
841
ret
842
843
; function to make the pokemon disappear at the beginning of the animation
844
TradeHidePokemon:
845
ld a, [wSubAnimCounter]
846
cp 6
847
ret nz
848
ld a, 2 * SCREEN_WIDTH + 7
849
jp ClearMonPicFromTileMap ; make pokemon disappear
850
851
; function to make a shaking pokeball jump up at the end of the animation
852
TradeShakePokeball:
853
ld a, [wSubAnimCounter]
854
cp 1
855
ret nz
856
; if it's the end of the animation, make the ball jump up
857
ld de, BallMoveDistances1
858
.loop
859
ld hl, wShadowOAM
860
ld bc, 4
861
.innerLoop
862
ld a, [de]
863
cp $ff
864
jr z, .done
865
add [hl] ; add to Y value of OAM entry
866
ld [hl], a
867
add hl, bc
868
ld a, l
869
cp 4 * 4 ; there are 4 entries, each 4 bytes
870
jr nz, .innerLoop
871
inc de
872
push bc
873
call Delay3
874
pop bc
875
jr .loop
876
.done
877
call AnimationCleanOAM
878
ld a, SFX_TRADE_MACHINE
879
jp PlaySound
880
881
BallMoveDistances1:
882
db -12, -12, -8
883
db -1 ; end
884
885
; function to make the pokeball jump up
886
TradeJumpPokeball:
887
ld de, BallMoveDistances2
888
.loop
889
ld hl, wShadowOAM
890
ld bc, 4
891
.innerLoop
892
ld a, [de]
893
cp $ff
894
jp z, ClearScreen
895
add [hl]
896
ld [hl], a
897
add hl, bc
898
ld a, l
899
cp 4 * 4 ; there are 4 entries, each 4 bytes
900
jr nz, .innerLoop
901
inc de
902
push de
903
ld a, [de]
904
cp 12
905
jr z, .playSound
906
cp $ff
907
jr nz, .skipPlayingSound
908
.playSound ; play sound if next move distance is 12 or this is the last one
909
ld a, SFX_SWAP
910
call PlaySound
911
.skipPlayingSound
912
push bc
913
ld c, 5
914
call DelayFrames
915
pop bc
916
ldh a, [hSCX] ; background scroll X
917
sub 8 ; scroll to the left
918
ldh [hSCX], a
919
pop de
920
jr .loop
921
922
BallMoveDistances2:
923
db 11, 12, -12, -7, 7, 12, -8, 8
924
db -1 ; end
925
926
; this function copies the current musical note graphic
927
; so that there are two musical notes flying towards the defending pokemon
928
DoGrowlSpecialEffects:
929
ld hl, wShadowOAM
930
ld de, wShadowOAMSprite04
931
ld bc, OBJ_SIZE * 4
932
call CopyData ; copy the musical note graphic
933
ld a, [wSubAnimCounter]
934
dec a
935
call z, AnimationCleanOAM ; clean up at the end of the subanimation
936
ret
937
938
; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
939
TailWhipAnimationUnused:
940
ld a, 1
941
ld [wSubAnimCounter], a
942
ld c, 20
943
jp DelayFrames
944
945
INCLUDE "data/battle_anims/special_effect_pointers.asm"
946
947
AnimationDelay10:
948
ld c, 10
949
jp DelayFrames
950
951
; calls a function with the turn flipped from player to enemy or vice versa
952
; input - hl - address of function to call
953
CallWithTurnFlipped:
954
ldh a, [hWhoseTurn]
955
push af
956
xor 1
957
ldh [hWhoseTurn], a
958
ld de, .returnAddress
959
push de
960
jp hl
961
.returnAddress
962
pop af
963
ldh [hWhoseTurn], a
964
ret
965
966
; flashes the screen for an extended period (48 frames)
967
AnimationFlashScreenLong:
968
ld a, 3 ; cycle through the palettes 3 times
969
ld [wFlashScreenLongCounter], a
970
ld a, [wOnSGB] ; running on SGB?
971
and a
972
ld hl, FlashScreenLongMonochrome
973
jr z, .loop
974
ld hl, FlashScreenLongSGB
975
.loop
976
push hl
977
.innerLoop
978
ld a, [hli]
979
cp 1
980
jr z, .endOfPalettes
981
ldh [rBGP], a
982
call FlashScreenLongDelay
983
jr .innerLoop
984
.endOfPalettes
985
ld a, [wFlashScreenLongCounter]
986
dec a
987
ld [wFlashScreenLongCounter], a
988
pop hl
989
jr nz, .loop
990
vc_hook_red Stop_reducing_move_anim_flashing_Psychic
991
ret
992
993
; BG palettes
994
FlashScreenLongMonochrome:
995
dc 3, 3, 2, 1
996
dc 3, 3, 3, 2
997
dc 3, 3, 3, 3
998
dc 3, 3, 3, 2
999
dc 3, 3, 2, 1
1000
dc 3, 2, 1, 0
1001
dc 2, 1, 0, 0
1002
dc 1, 0, 0, 0
1003
dc 0, 0, 0, 0
1004
dc 1, 0, 0, 0
1005
dc 2, 1, 0, 0
1006
dc 3, 2, 1, 0
1007
db 1 ; end
1008
1009
; BG palettes
1010
FlashScreenLongSGB:
1011
dc 3, 3, 2, 0
1012
dc 3, 3, 3, 0
1013
dc 3, 3, 3, 3
1014
dc 3, 3, 3, 0
1015
dc 3, 3, 2, 0
1016
dc 3, 2, 1, 0
1017
dc 2, 1, 0, 0
1018
dc 1, 0, 0, 0
1019
dc 0, 0, 0, 0
1020
dc 1, 0, 0, 0
1021
dc 2, 1, 0, 0
1022
dc 3, 2, 1, 0
1023
db 1 ; end
1024
1025
; causes a delay of 2 frames for the first cycle
1026
; causes a delay of 1 frame for the second and third cycles
1027
FlashScreenLongDelay:
1028
ld a, [wFlashScreenLongCounter]
1029
cp 4 ; never true since [wFlashScreenLongCounter] starts at 3
1030
ld c, 4
1031
jr z, .delayFrames
1032
cp 3
1033
ld c, 2
1034
jr z, .delayFrames
1035
cp 2 ; nothing is done with this
1036
ld c, 1
1037
.delayFrames
1038
jp DelayFrames
1039
1040
AnimationFlashScreen:
1041
ldh a, [rBGP]
1042
push af ; save initial palette
1043
ld a, %00011011 ; 0, 1, 2, 3 (inverted colors)
1044
ldh [rBGP], a
1045
ld c, 2
1046
call DelayFrames
1047
xor a ; white out background
1048
ldh [rBGP], a
1049
ld c, 2
1050
call DelayFrames
1051
pop af
1052
ldh [rBGP], a ; restore initial palette
1053
ret
1054
1055
AnimationDarkScreenPalette:
1056
; Changes the screen's palette to a dark palette.
1057
lb bc, $6f, $6f
1058
jr SetAnimationBGPalette
1059
1060
AnimationDarkenMonPalette:
1061
; Darkens the mon sprite's palette.
1062
lb bc, $f9, $f4
1063
jr SetAnimationBGPalette
1064
1065
AnimationUnusedPalette1:
1066
lb bc, $fe, $f8
1067
jr SetAnimationBGPalette
1068
1069
AnimationUnusedPalette2:
1070
lb bc, $ff, $ff
1071
jr SetAnimationBGPalette
1072
1073
AnimationResetScreenPalette:
1074
; Restores the screen's palette to the normal palette.
1075
lb bc, $e4, $e4
1076
jr SetAnimationBGPalette
1077
1078
AnimationUnusedPalette3:
1079
lb bc, $00, $00
1080
jr SetAnimationBGPalette
1081
1082
AnimationLightScreenPalette:
1083
; Changes the screen to use a palette with light colors.
1084
lb bc, $90, $90
1085
jr SetAnimationBGPalette
1086
1087
AnimationUnusedPalette4:
1088
lb bc, $40, $40
1089
1090
SetAnimationBGPalette:
1091
ld a, [wOnSGB]
1092
and a
1093
ld a, b
1094
jr z, .next
1095
ld a, c
1096
.next
1097
ldh [rBGP], a
1098
ret
1099
1100
AnimationUnusedShakeScreen: ; unreferenced
1101
; Shakes the screen for a while.
1102
ld b, $5
1103
1104
AnimationShakeScreenVertically:
1105
predef_jump PredefShakeScreenVertically
1106
1107
AnimationShakeScreen:
1108
; Shakes the screen for a while. Used in Earthquake/Fissure/etc. animations.
1109
ld b, $8
1110
1111
AnimationShakeScreenHorizontallyFast:
1112
predef_jump PredefShakeScreenHorizontally
1113
1114
AnimationWaterDropletsEverywhere:
1115
; Draws water droplets all over the screen and makes them
1116
; scroll. It's hard to describe, but it's the main animation
1117
; in Surf/Mist/Toxic.
1118
xor a
1119
ld [wWhichBattleAnimTileset], a
1120
call LoadMoveAnimationTiles
1121
ld d, 32
1122
ld a, -16
1123
ld [wBaseCoordX], a
1124
ld a, $71
1125
ld [wDropletTile], a
1126
.loop
1127
ld a, 16
1128
ld [wBaseCoordY], a
1129
ld a, 0
1130
ld [wUnusedWaterDropletsByte], a
1131
call _AnimationWaterDroplets
1132
ld a, 24
1133
ld [wBaseCoordY], a
1134
ld a, 32
1135
ld [wUnusedWaterDropletsByte], a
1136
call _AnimationWaterDroplets
1137
dec d
1138
jr nz, .loop
1139
ret
1140
1141
_AnimationWaterDroplets:
1142
ld hl, wShadowOAM
1143
.loop
1144
ld a, [wBaseCoordY]
1145
ld [hli], a ; Y
1146
ld a, [wBaseCoordX]
1147
add 27
1148
ld [wBaseCoordX], a
1149
ld [hli], a ; X
1150
ld a, [wDropletTile]
1151
ld [hli], a ; tile
1152
xor a
1153
ld [hli], a ; attribute
1154
ld a, [wBaseCoordX]
1155
cp 144
1156
jr c, .loop
1157
sub 168
1158
ld [wBaseCoordX], a
1159
ld a, [wBaseCoordY]
1160
add 16
1161
ld [wBaseCoordY], a
1162
cp 112
1163
jr c, .loop
1164
call AnimationCleanOAM
1165
jp DelayFrame
1166
1167
AnimationSlideMonUp:
1168
; Slides the mon's sprite upwards.
1169
ld c, 7
1170
ldh a, [hWhoseTurn]
1171
and a
1172
hlcoord 1, 6
1173
decoord 1, 5
1174
ld a, $30
1175
jr z, .next
1176
hlcoord 12, 1
1177
decoord 12, 0
1178
ld a, $ff
1179
.next
1180
ld [wSlideMonUpBottomRowLeftTile], a
1181
jp _AnimationSlideMonUp
1182
1183
AnimationSlideMonDown:
1184
; Slides the mon's sprite down out of the screen.
1185
xor a ; TILEMAP_MON_PIC
1186
call GetTileIDList
1187
.loop
1188
call GetMonSpriteTileMapPointerFromRowCount
1189
push bc
1190
push de
1191
call CopyPicTiles
1192
call Delay3
1193
call AnimationHideMonPic
1194
pop de
1195
pop bc
1196
dec b
1197
jr nz, .loop
1198
ret
1199
1200
AnimationSlideMonOff:
1201
; Slides the mon's sprite off the screen horizontally.
1202
ld e, 8
1203
ld a, 3
1204
ld [wSlideMonDelay], a
1205
jp _AnimationSlideMonOff
1206
1207
AnimationSlideEnemyMonOff:
1208
; Slides the enemy mon off the screen horizontally.
1209
ld hl, AnimationSlideMonOff
1210
jp CallWithTurnFlipped
1211
1212
_AnimationSlideMonUp:
1213
push de
1214
push hl
1215
push bc
1216
1217
; In each iteration, slide up all rows but the top one (which is overwritten).
1218
ld b, PIC_HEIGHT - 1
1219
.slideLoop
1220
push bc
1221
push de
1222
push hl
1223
ld bc, PIC_WIDTH
1224
call CopyData
1225
; Note that de and hl are popped in the same order they are pushed, swapping
1226
; their values. When CopyData is called, hl points to a tile 1 row below
1227
; the one de points to. To maintain this relationship, after swapping, we add 2
1228
; rows to hl so that it is 1 row below again.
1229
pop de
1230
pop hl
1231
ld bc, SCREEN_WIDTH * 2
1232
add hl, bc
1233
pop bc
1234
dec b
1235
jr nz, .slideLoop
1236
1237
; Fill in the bottom row of the mon pic with the next row's tile IDs.
1238
ldh a, [hWhoseTurn]
1239
and a
1240
hlcoord 1, 11
1241
jr z, .next
1242
hlcoord 12, 6
1243
.next
1244
ld a, [wSlideMonUpBottomRowLeftTile]
1245
inc a
1246
ld [wSlideMonUpBottomRowLeftTile], a
1247
ld c, PIC_WIDTH
1248
.fillBottomRowLoop
1249
ld [hli], a
1250
add PIC_WIDTH
1251
dec c
1252
jr nz, .fillBottomRowLoop
1253
1254
ld c, 2
1255
call DelayFrames
1256
pop bc
1257
pop hl
1258
pop de
1259
dec c
1260
jr nz, _AnimationSlideMonUp
1261
ret
1262
1263
ShakeEnemyHUD_WritePlayerMonPicOAM:
1264
; Writes the OAM entries for a copy of the player mon's pic in OAM.
1265
; The top 5 rows are reproduced in OAM, although only 2 are actually needed.
1266
ld a, $10
1267
ld [wBaseCoordX], a
1268
ld a, $30
1269
ld [wBaseCoordY], a
1270
ld hl, wShadowOAM
1271
ld d, 0
1272
ld c, 7
1273
.loop
1274
ld a, [wBaseCoordY]
1275
ld e, a
1276
ld b, 5
1277
.innerLoop
1278
call BattleAnimWriteOAMEntry
1279
inc d
1280
dec b
1281
jr nz, .innerLoop
1282
dec c
1283
ret z
1284
inc d
1285
inc d
1286
ld a, [wBaseCoordX]
1287
add 8
1288
ld [wBaseCoordX], a
1289
jr .loop
1290
1291
BattleAnimWriteOAMEntry:
1292
; Y coordinate = e (increased by 8 each call, before the write to OAM)
1293
; X coordinate = [wBaseCoordX]
1294
; tile = d
1295
; attributes = 0
1296
ld a, e
1297
add 8
1298
ld e, a
1299
ld [hli], a
1300
ld a, [wBaseCoordX]
1301
ld [hli], a
1302
ld a, d
1303
ld [hli], a
1304
xor a
1305
ld [hli], a
1306
ret
1307
1308
AdjustOAMBlockXPos:
1309
ld l, e
1310
ld h, d
1311
1312
AdjustOAMBlockXPos2:
1313
ld de, OBJ_SIZE
1314
.loop
1315
ld a, [wCoordAdjustmentAmount]
1316
ld b, a
1317
ld a, [hl]
1318
add b
1319
cp 168
1320
jr c, .skipPuttingEntryOffScreen
1321
; put off-screen if X >= 168
1322
dec hl
1323
ld a, SCREEN_HEIGHT_PX + OAM_Y_OFS
1324
ld [hli], a
1325
.skipPuttingEntryOffScreen
1326
ld [hl], a
1327
add hl, de
1328
dec c
1329
jr nz, .loop
1330
ret
1331
1332
AdjustOAMBlockYPos:
1333
ld l, e
1334
ld h, d
1335
1336
AdjustOAMBlockYPos2:
1337
ld de, OBJ_SIZE
1338
.loop
1339
ld a, [wCoordAdjustmentAmount]
1340
ld b, a
1341
ld a, [hl]
1342
add b
1343
cp 112
1344
jr c, .skipSettingPreviousEntrysAttribute
1345
dec hl
1346
ld a, 160 ; bug, sets previous OAM entry's attribute
1347
ld [hli], a
1348
.skipSettingPreviousEntrysAttribute
1349
ld [hl], a
1350
add hl, de
1351
dec c
1352
jr nz, .loop
1353
ret
1354
1355
AnimationBlinkEnemyMon:
1356
; Make the enemy mon's sprite blink on and off for a second or two
1357
ld hl, AnimationBlinkMon
1358
jp CallWithTurnFlipped
1359
1360
AnimationBlinkMon:
1361
; Make the mon's sprite blink on and off for a second or two.
1362
push af
1363
ld c, 6
1364
.loop
1365
push bc
1366
call AnimationHideMonPic
1367
ld c, 5
1368
call DelayFrames
1369
call AnimationShowMonPic
1370
ld c, 5
1371
call DelayFrames
1372
pop bc
1373
dec c
1374
jr nz, .loop
1375
pop af
1376
ret
1377
1378
AnimationFlashMonPic:
1379
; Flashes the mon's sprite on and off
1380
ld a, [wBattleMonSpecies]
1381
ld [wChangeMonPicPlayerTurnSpecies], a
1382
ld a, [wEnemyMonSpecies]
1383
ld [wChangeMonPicEnemyTurnSpecies], a
1384
jp ChangeMonPic
1385
1386
AnimationFlashEnemyMonPic:
1387
; Flashes the enemy mon's sprite on and off
1388
ld hl, AnimationFlashMonPic
1389
jp CallWithTurnFlipped
1390
1391
AnimationShowMonPic:
1392
xor a ; TILEMAP_MON_PIC
1393
call GetTileIDList
1394
call GetMonSpriteTileMapPointerFromRowCount
1395
call CopyPicTiles
1396
jp Delay3
1397
1398
AnimationShowEnemyMonPic:
1399
; Shows the enemy mon's front sprite. Used in animations like Seismic Toss
1400
; to make the mon's sprite reappear after disappears offscreen.
1401
ld hl, AnimationShowMonPic
1402
jp CallWithTurnFlipped
1403
1404
AnimationShakeBackAndForth:
1405
; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
1406
; The mon's sprite disappears after this animation.
1407
ldh a, [hWhoseTurn]
1408
and a
1409
hlcoord 0, 5
1410
decoord 2, 5
1411
jr z, .next
1412
hlcoord 11, 0
1413
decoord 13, 0
1414
1415
.next
1416
xor a ; TILEMAP_MON_PIC
1417
ld c, $10
1418
.loop
1419
push af
1420
push bc
1421
push de
1422
push hl
1423
push hl
1424
push de
1425
push af
1426
push hl
1427
push hl
1428
call GetTileIDList
1429
pop hl
1430
call CopyPicTiles
1431
call Delay3
1432
pop hl
1433
lb bc, 7, 9
1434
call ClearScreenArea
1435
pop af
1436
call GetTileIDList
1437
pop hl
1438
call CopyPicTiles
1439
call Delay3
1440
pop hl
1441
lb bc, 7, 9
1442
call ClearScreenArea
1443
pop hl
1444
pop de
1445
pop bc
1446
pop af
1447
dec c
1448
jr nz, .loop
1449
ret
1450
1451
AnimationMoveMonHorizontally:
1452
; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
1453
; animations like Tackle/Body Slam.
1454
call AnimationHideMonPic
1455
ldh a, [hWhoseTurn]
1456
and a
1457
hlcoord 2, 5
1458
jr z, .next
1459
hlcoord 11, 0
1460
.next
1461
xor a ; TILEMAP_MON_PIC
1462
push hl
1463
call GetTileIDList
1464
pop hl
1465
call CopyPicTiles
1466
ld c, 3
1467
jp DelayFrames
1468
1469
AnimationResetMonPosition:
1470
; Resets the mon's sprites to be located at the normal coordinates.
1471
ldh a, [hWhoseTurn]
1472
and a
1473
ld a, 5 * SCREEN_WIDTH + 2
1474
jr z, .next
1475
ld a, 11
1476
.next
1477
call ClearMonPicFromTileMap
1478
jp AnimationShowMonPic
1479
1480
AnimationSpiralBallsInward:
1481
; Creates an effect that looks like energy balls spiralling into the
1482
; player mon's sprite. Used in Focus Energy, for example.
1483
ldh a, [hWhoseTurn]
1484
and a
1485
jr z, .playerTurn
1486
ld a, -40
1487
ld [wSpiralBallsBaseY], a
1488
ld a, 80
1489
ld [wSpiralBallsBaseX], a
1490
jr .next
1491
.playerTurn
1492
xor a
1493
ld [wSpiralBallsBaseY], a
1494
ld [wSpiralBallsBaseX], a
1495
.next
1496
ld d, $7a ; ball tile
1497
ld c, 3 ; number of balls
1498
xor a
1499
call InitMultipleObjectsOAM
1500
ld hl, SpiralBallAnimationCoordinates
1501
.loop
1502
push hl
1503
ld c, 3
1504
ld de, wShadowOAM
1505
.innerLoop
1506
ld a, [hl]
1507
cp $ff
1508
jr z, .done
1509
ld a, [wSpiralBallsBaseY]
1510
add [hl]
1511
ld [de], a ; Y
1512
inc de
1513
inc hl
1514
ld a, [wSpiralBallsBaseX]
1515
add [hl]
1516
ld [de], a ; X
1517
inc hl
1518
inc de
1519
inc de
1520
inc de
1521
dec c
1522
jr nz, .innerLoop
1523
ld c, 5
1524
call DelayFrames
1525
pop hl
1526
inc hl
1527
inc hl
1528
jr .loop
1529
.done
1530
pop hl
1531
call AnimationCleanOAM
1532
jp AnimationFlashScreen
1533
1534
SpiralBallAnimationCoordinates:
1535
; y, x pairs
1536
; This is the sequence of screen coordinates that the spiralling
1537
; balls are positioned at.
1538
db $38, $28
1539
db $40, $18
1540
db $50, $10
1541
db $60, $18
1542
db $68, $28
1543
db $60, $38
1544
db $50, $40
1545
db $40, $38
1546
db $40, $28
1547
db $46, $1E
1548
db $50, $18
1549
db $5B, $1E
1550
db $60, $28
1551
db $5B, $32
1552
db $50, $38
1553
db $46, $32
1554
db $48, $28
1555
db $50, $20
1556
db $58, $28
1557
db $50, $30
1558
db $50, $28
1559
db -1 ; end
1560
1561
AnimationSquishMonPic:
1562
; Squishes the mon's sprite horizontally making it
1563
; disappear. Used by Teleport/Sky Attack animations.
1564
ld c, 4
1565
.loop
1566
push bc
1567
ldh a, [hWhoseTurn]
1568
and a
1569
jr z, .playerTurn
1570
hlcoord 16, 0
1571
decoord 14, 0
1572
jr .next
1573
.playerTurn
1574
hlcoord 5, 5
1575
decoord 3, 5
1576
.next
1577
push de
1578
xor a ; left
1579
ld [wSquishMonCurrentDirection], a
1580
call _AnimationSquishMonPic
1581
pop hl
1582
ld a, 1 ; right
1583
ld [wSquishMonCurrentDirection], a
1584
call _AnimationSquishMonPic
1585
pop bc
1586
dec c
1587
jr nz, .loop
1588
call AnimationHideMonPic
1589
ld c, 2
1590
jp DelayFrame
1591
1592
_AnimationSquishMonPic:
1593
ld c, 7
1594
.loop
1595
push bc
1596
push hl
1597
ld c, 3
1598
ld a, [wSquishMonCurrentDirection]
1599
cp 0
1600
jr nz, .right
1601
call AnimCopyRowLeft
1602
dec hl
1603
jr .next
1604
.right
1605
call AnimCopyRowRight
1606
inc hl
1607
.next
1608
ld [hl], ' '
1609
pop hl
1610
ld de, SCREEN_WIDTH
1611
add hl, de
1612
pop bc
1613
dec c
1614
jr nz, .loop
1615
jp Delay3
1616
1617
AnimationShootBallsUpward:
1618
; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
1619
; animations.
1620
ldh a, [hWhoseTurn]
1621
and a
1622
jr z, .playerTurn
1623
lb bc, 0, 16 * 8
1624
jr .next
1625
.playerTurn
1626
lb bc, 6 * 8, 5 * 8
1627
.next
1628
ld a, b
1629
ld [wBaseCoordY], a
1630
ld a, c
1631
ld [wBaseCoordX], a
1632
lb bc, 5, 1
1633
call _AnimationShootBallsUpward
1634
jp AnimationCleanOAM
1635
1636
_AnimationShootBallsUpward:
1637
push bc
1638
xor a
1639
ld [wWhichBattleAnimTileset], a
1640
call LoadMoveAnimationTiles
1641
pop bc
1642
ld d, $7a ; ball tile
1643
ld hl, wShadowOAM
1644
push bc
1645
ld a, [wBaseCoordY]
1646
ld e, a
1647
.initOAMLoop
1648
call BattleAnimWriteOAMEntry
1649
dec b
1650
jr nz, .initOAMLoop
1651
call DelayFrame
1652
pop bc
1653
ld a, b
1654
ld [wNumShootingBalls], a
1655
.loop
1656
push bc
1657
ld hl, wShadowOAM
1658
.innerLoop
1659
ld a, [wBaseCoordY]
1660
add 8
1661
ld e, a
1662
ld a, [hl]
1663
cp e ; has the ball reached the top?
1664
jr z, .reachedTop
1665
add -4 ; ball hasn't reached the top. move it up 4 pixels
1666
ld [hl], a
1667
jr .next
1668
.reachedTop
1669
; remove the ball once it has reached the top
1670
ld [hl], 0 ; put it off-screen
1671
ld a, [wNumShootingBalls]
1672
dec a
1673
ld [wNumShootingBalls], a
1674
.next
1675
ld de, OBJ_SIZE
1676
add hl, de ; next OAM entry
1677
dec b
1678
jr nz, .innerLoop
1679
call DelayFrames
1680
pop bc
1681
ld a, [wNumShootingBalls]
1682
and a
1683
jr nz, .loop
1684
ret
1685
1686
AnimationShootManyBallsUpward:
1687
; Shoots several pillars of "energy" balls upward.
1688
ldh a, [hWhoseTurn]
1689
and a
1690
ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
1691
ld a, $50 ; y coordinate for "energy" ball pillar
1692
jr z, .player
1693
ld hl, UpwardBallsAnimXCoordinatesEnemyTurn
1694
ld a, $28 ; y coordinate for "energy" ball pillar
1695
.player
1696
ld [wSavedY], a
1697
.loop
1698
ld a, [wSavedY]
1699
ld [wBaseCoordY], a
1700
ld a, [hli]
1701
cp $ff
1702
jp z, AnimationCleanOAM
1703
ld [wBaseCoordX], a
1704
lb bc, 4, 1
1705
push hl
1706
call _AnimationShootBallsUpward
1707
pop hl
1708
jr .loop
1709
1710
UpwardBallsAnimXCoordinatesPlayerTurn:
1711
; List of x coordinates for each pillar of "energy" balls in the
1712
; AnimationShootManyBallsUpward animation. It's unused in the game.
1713
db $10, $40, $28, $18, $38, $30
1714
db -1 ; end
1715
1716
UpwardBallsAnimXCoordinatesEnemyTurn:
1717
; List of x coordinates for each pillar of "energy" balls in the
1718
; AnimationShootManyBallsUpward animation. It's unused in the game.
1719
db $60, $90, $78, $68, $88, $80
1720
db -1 ; end
1721
1722
AnimationMinimizeMon:
1723
; Changes the mon's sprite to a mini black sprite. Used by the
1724
; Minimize animation.
1725
ld hl, wTempPic
1726
push hl
1727
xor a
1728
ld bc, PIC_SIZE tiles
1729
call FillMemory
1730
pop hl
1731
ld de, (PIC_WIDTH * 3 + 4) tiles + TILE_SIZE / 4
1732
add hl, de
1733
ld de, MinimizedMonSprite
1734
ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
1735
.loop
1736
ld a, [de]
1737
ld [hli], a
1738
ld [hli], a
1739
inc de
1740
dec c
1741
jr nz, .loop
1742
call CopyTempPicToMonPic
1743
call Delay3
1744
jp AnimationShowMonPic
1745
1746
MinimizedMonSprite:
1747
; 8x5 partial tile graphic
1748
pusho b.X ; . = 0, X = 1
1749
db %...XX...
1750
db %..XXXX..
1751
db %.XXXXXX.
1752
db %..XXXX..
1753
db %..X..X..
1754
popo
1755
MinimizedMonSpriteEnd:
1756
1757
AnimationSlideMonDownAndHide:
1758
; Slides the mon's sprite down and disappears. Used in Acid Armor.
1759
ld a, TILEMAP_SLIDE_DOWN_MON_PIC_7X5
1760
ld c, 2
1761
.loop
1762
push bc
1763
push af
1764
call AnimationHideMonPic
1765
pop af
1766
push af
1767
call GetTileIDList
1768
call GetMonSpriteTileMapPointerFromRowCount
1769
call CopyPicTiles
1770
ld c, 8
1771
call DelayFrames
1772
pop af
1773
inc a
1774
pop bc
1775
dec c
1776
jr nz, .loop
1777
call AnimationHideMonPic
1778
ld hl, wTempPic
1779
ld bc, PIC_SIZE tiles
1780
xor a
1781
call FillMemory
1782
jp CopyTempPicToMonPic
1783
1784
_AnimationSlideMonOff:
1785
; Slides the mon's sprite off the screen horizontally by e tiles and waits
1786
; [wSlideMonDelay] V-blanks each time the pic is slid by one tile.
1787
ldh a, [hWhoseTurn]
1788
and a
1789
jr z, .playerTurn
1790
hlcoord 12, 0
1791
jr .next
1792
.playerTurn
1793
hlcoord 0, 5
1794
.next
1795
ld d, 8 ; d's value is unused
1796
.slideLoop ; iterates once for each time the pic slides by one tile
1797
push hl
1798
ld b, 7
1799
.rowLoop ; iterates once for each row
1800
ld c, 8
1801
.tileLoop ; iterates once for each tile in the row
1802
ldh a, [hWhoseTurn]
1803
and a
1804
jr z, .playerTurn2
1805
call .EnemyNextTile
1806
jr .next2
1807
.playerTurn2
1808
call .PlayerNextTile
1809
.next2
1810
ld [hli], a
1811
dec c
1812
jr nz, .tileLoop
1813
push de
1814
ld de, SCREEN_WIDTH - 8
1815
add hl, de
1816
pop de
1817
dec b
1818
jr nz, .rowLoop
1819
ld a, [wSlideMonDelay]
1820
ld c, a
1821
call DelayFrames
1822
pop hl
1823
dec d
1824
dec e
1825
jr nz, .slideLoop
1826
ret
1827
1828
; Since mon pic tile numbers go from top to bottom, left to right in order,
1829
; adding the height of the mon pic in tiles to a tile number gives the tile
1830
; number of the tile one column to the right (and thus subtracting the height
1831
; gives the reverse). If the next tile would be past the edge of the pic, the 2
1832
; functions below catch it by checking if the tile number is within the valid
1833
; range and if not, replacing it with a blank tile.
1834
1835
.PlayerNextTile
1836
ld a, [hl]
1837
add 7
1838
; This is a bug. The lower right corner tile of the mon back pic is blanked
1839
; while the mon is sliding off the screen. It should compare with the max tile
1840
; plus one instead.
1841
cp $61
1842
ret c
1843
ld a, ' '
1844
ret
1845
1846
.EnemyNextTile
1847
ld a, [hl]
1848
sub 7
1849
; This has the same problem as above, but it has no visible effect because
1850
; the lower right tile is in the first column to slide off the screen.
1851
cp $30
1852
ret c
1853
ld a, ' '
1854
ret
1855
1856
AnimationSlideMonHalfOff:
1857
; Slides the mon's sprite halfway off the screen. It's used in Softboiled.
1858
ld e, 4
1859
ld a, 4
1860
ld [wSlideMonDelay], a
1861
call _AnimationSlideMonOff
1862
jp Delay3
1863
1864
CopyTempPicToMonPic:
1865
ldh a, [hWhoseTurn]
1866
and a
1867
ld hl, vBackPic ; player turn
1868
jr z, .next
1869
ld hl, vFrontPic ; enemy turn
1870
.next
1871
ld de, wTempPic
1872
ld bc, PIC_SIZE
1873
jp CopyVideoData
1874
1875
AnimationWavyScreen:
1876
; used in Psywave/Psychic etc.
1877
ld hl, vBGMap0
1878
call BattleAnimCopyTileMapToVRAM
1879
call Delay3
1880
xor a
1881
ldh [hAutoBGTransferEnabled], a
1882
ld a, SCREEN_HEIGHT_PX
1883
ldh [hWY], a
1884
ld d, $80 ; terminator
1885
ld e, SCREEN_HEIGHT_PX - 1
1886
ld c, $ff
1887
ld hl, WavyScreenLineOffsets
1888
.loop
1889
push hl
1890
.innerLoop
1891
call WavyScreen_SetSCX
1892
ldh a, [rLY]
1893
cp e ; is it the last visible line in the frame?
1894
jr nz, .innerLoop ; keep going if not
1895
pop hl
1896
inc hl
1897
ld a, [hl]
1898
cp d ; have we reached the end?
1899
jr nz, .next
1900
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
1901
.next
1902
dec c
1903
jr nz, .loop
1904
xor a
1905
ldh [hWY], a
1906
call SaveScreenTilesToBuffer2
1907
call ClearScreen
1908
ld a, 1
1909
ldh [hAutoBGTransferEnabled], a
1910
call Delay3
1911
call LoadScreenTilesFromBuffer2
1912
ld hl, vBGMap1
1913
call BattleAnimCopyTileMapToVRAM
1914
ret
1915
1916
WavyScreen_SetSCX:
1917
ldh a, [rSTAT]
1918
and $3 ; is it H-blank?
1919
jr nz, WavyScreen_SetSCX ; wait until it's H-blank
1920
ld a, [hl]
1921
ldh [rSCX], a
1922
inc hl
1923
ld a, [hl]
1924
cp d ; have we reached the end?
1925
ret nz
1926
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
1927
ret
1928
1929
WavyScreenLineOffsets:
1930
; Sequence of horizontal line pixel offsets for the wavy screen animation.
1931
; This sequence vaguely resembles a sine wave.
1932
db 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1
1933
db 0, 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, -1
1934
db $80 ; terminator
1935
1936
AnimationSubstitute:
1937
; Changes the pokemon's sprite to the mini sprite
1938
ld hl, wTempPic
1939
xor a
1940
ld bc, PIC_SIZE tiles
1941
call FillMemory
1942
ldh a, [hWhoseTurn]
1943
and a
1944
jr z, .playerTurn
1945
ld hl, MonsterSprite tile 0 ; facing down sprite
1946
ld de, wTempPic + $120
1947
call CopyMonsterSpriteData
1948
ld hl, MonsterSprite tile 1
1949
ld de, wTempPic + $120 + $70
1950
call CopyMonsterSpriteData
1951
ld hl, MonsterSprite tile 2
1952
ld de, wTempPic + $120 + $10
1953
call CopyMonsterSpriteData
1954
ld hl, MonsterSprite tile 3
1955
ld de, wTempPic + $120 + $10 + $70
1956
call CopyMonsterSpriteData
1957
jr .next
1958
.playerTurn
1959
ld hl, MonsterSprite tile 4 ; facing up sprite
1960
ld de, wTempPic + $120 + $70
1961
call CopyMonsterSpriteData
1962
ld hl, MonsterSprite tile 5
1963
ld de, wTempPic + $120 + $e0
1964
call CopyMonsterSpriteData
1965
ld hl, MonsterSprite tile 6
1966
ld de, wTempPic + $120 + $80
1967
call CopyMonsterSpriteData
1968
ld hl, MonsterSprite tile 7
1969
ld de, wTempPic + $120 + $f0
1970
call CopyMonsterSpriteData
1971
.next
1972
call CopyTempPicToMonPic
1973
jp AnimationShowMonPic
1974
1975
CopyMonsterSpriteData:
1976
ld bc, TILE_SIZE
1977
ld a, BANK(MonsterSprite)
1978
jp FarCopyData2
1979
1980
HideSubstituteShowMonAnim:
1981
ldh a, [hWhoseTurn]
1982
and a
1983
ld hl, wPlayerMonMinimized
1984
ld a, [wPlayerBattleStatus2]
1985
jr z, .next1
1986
ld hl, wEnemyMonMinimized
1987
ld a, [wEnemyBattleStatus2]
1988
.next1
1989
push hl
1990
; if the substitute broke, slide it down, else slide it offscreen horizontally
1991
bit HAS_SUBSTITUTE_UP, a
1992
jr nz, .substituteStillUp
1993
call AnimationSlideMonDown
1994
jr .next2
1995
.substituteStillUp
1996
call AnimationSlideMonOff
1997
.next2
1998
pop hl
1999
ld a, [hl]
2000
and a
2001
jp nz, AnimationMinimizeMon
2002
call AnimationFlashMonPic
2003
jp AnimationShowMonPic
2004
2005
ReshowSubstituteAnim:
2006
call AnimationSlideMonOff
2007
call AnimationSubstitute
2008
jp AnimationShowMonPic
2009
2010
AnimationBoundUpAndDown:
2011
; Bounces the mon's sprite up and down several times. It is used
2012
; by Splash's animation.
2013
ld c, 5
2014
.loop
2015
push bc
2016
call AnimationSlideMonDown
2017
pop bc
2018
dec c
2019
jr nz, .loop
2020
jp AnimationShowMonPic
2021
2022
AnimationTransformMon:
2023
; Redraws this mon's sprite as the back/front sprite of the opposing mon.
2024
; Used in Transform.
2025
ld a, [wEnemyMonSpecies]
2026
ld [wChangeMonPicPlayerTurnSpecies], a
2027
ld a, [wBattleMonSpecies]
2028
ld [wChangeMonPicEnemyTurnSpecies], a
2029
2030
ChangeMonPic:
2031
ldh a, [hWhoseTurn]
2032
and a
2033
jr z, .playerTurn
2034
ld a, [wChangeMonPicEnemyTurnSpecies]
2035
ld [wCurPartySpecies], a
2036
ld [wCurSpecies], a
2037
xor a
2038
ld [wSpriteFlipped], a
2039
call GetMonHeader
2040
hlcoord 12, 0
2041
call LoadFrontSpriteByMonIndex
2042
jr .done
2043
.playerTurn
2044
ld a, [wBattleMonSpecies2]
2045
push af
2046
ld a, [wChangeMonPicPlayerTurnSpecies]
2047
ld [wBattleMonSpecies2], a
2048
ld [wCurSpecies], a
2049
call GetMonHeader
2050
predef LoadMonBackPic
2051
xor a ; TILEMAP_MON_PIC
2052
call GetTileIDList
2053
call GetMonSpriteTileMapPointerFromRowCount
2054
call CopyPicTiles
2055
pop af
2056
ld [wBattleMonSpecies2], a
2057
.done
2058
ld b, SET_PAL_BATTLE
2059
jp RunPaletteCommand
2060
2061
AnimationHideEnemyMonPic:
2062
; Hides the enemy mon's sprite
2063
xor a
2064
ldh [hAutoBGTransferEnabled], a
2065
ld hl, AnimationHideMonPic
2066
call CallWithTurnFlipped
2067
ld a, $1
2068
ldh [hAutoBGTransferEnabled], a
2069
jp Delay3
2070
2071
InitMultipleObjectsOAM:
2072
; Writes c OAM entries with tile d.
2073
; Sets their Y coordinates to sequential multiples of 8, starting from 0.
2074
; Sets their X coordinates to 0.
2075
; Loads animation tileset a.
2076
push bc
2077
push de
2078
ld [wWhichBattleAnimTileset], a
2079
call LoadMoveAnimationTiles
2080
pop de
2081
pop bc
2082
xor a
2083
ld e, a
2084
ld [wBaseCoordX], a
2085
ld hl, wShadowOAM
2086
.loop
2087
call BattleAnimWriteOAMEntry
2088
dec c
2089
jr nz, .loop
2090
ret
2091
2092
AnimationHideMonPic:
2093
; Hides the mon's sprite.
2094
ldh a, [hWhoseTurn]
2095
and a
2096
jr z, .playerTurn
2097
ld a, 12
2098
jr ClearMonPicFromTileMap
2099
.playerTurn
2100
ld a, 5 * SCREEN_WIDTH + 1
2101
2102
ClearMonPicFromTileMap:
2103
push hl
2104
push de
2105
push bc
2106
ld e, a
2107
ld d, 0
2108
hlcoord 0, 0
2109
add hl, de
2110
lb bc, 7, 7
2111
call ClearScreenArea
2112
pop bc
2113
pop de
2114
pop hl
2115
ret
2116
2117
; puts the tile map destination address of a mon sprite in hl, given the row count in b
2118
; The usual row count is 7, but it may be smaller when sliding a mon sprite in/out,
2119
; in order to show only a portion of the mon sprite.
2120
GetMonSpriteTileMapPointerFromRowCount:
2121
push de
2122
ldh a, [hWhoseTurn]
2123
and a
2124
jr nz, .enemyTurn
2125
ld a, 5 * SCREEN_WIDTH + 1
2126
jr .next
2127
.enemyTurn
2128
ld a, 12
2129
.next
2130
hlcoord 0, 0
2131
ld e, a
2132
ld d, 0
2133
add hl, de
2134
ld a, 7
2135
sub b
2136
and a
2137
jr z, .done
2138
ld de, SCREEN_WIDTH
2139
.loop
2140
add hl, de
2141
dec a
2142
jr nz, .loop
2143
.done
2144
pop de
2145
ret
2146
2147
; Input:
2148
; a = tile ID list index
2149
; Output:
2150
; de = tile ID list pointer
2151
; b = number of rows
2152
; c = number of columns
2153
GetTileIDList:
2154
ld hl, TileIDListPointerTable
2155
ld e, a
2156
ld d, 0
2157
add hl, de
2158
add hl, de
2159
add hl, de
2160
ld a, [hli]
2161
ld e, a
2162
ld a, [hli]
2163
ld d, a
2164
ld a, [hli]
2165
ld b, a
2166
and $f
2167
ld c, a
2168
ld a, b
2169
swap a
2170
and $f
2171
ld b, a
2172
ret
2173
2174
AnimCopyRowLeft:
2175
; copy a row of c tiles 1 tile left
2176
ld a, [hld]
2177
ld [hli], a
2178
inc hl
2179
dec c
2180
jr nz, AnimCopyRowLeft
2181
ret
2182
2183
AnimCopyRowRight:
2184
; copy a row of c tiles 1 tile right
2185
ld a, [hli]
2186
ld [hld], a
2187
dec hl
2188
dec c
2189
jr nz, AnimCopyRowRight
2190
ret
2191
2192
; only used by the unreferenced PlayIntroMoveSound
2193
GetIntroMoveSound:
2194
ld a, b
2195
call GetMoveSound
2196
ld b, a
2197
ret
2198
2199
GetMoveSound:
2200
ld hl, MoveSoundTable
2201
ld e, a
2202
ld d, 0
2203
add hl, de
2204
add hl, de
2205
add hl, de
2206
ld a, [hli]
2207
ld b, a
2208
call IsCryMove
2209
jr nc, .NotCryMove
2210
ldh a, [hWhoseTurn]
2211
and a
2212
jr nz, .next
2213
ld a, [wBattleMonSpecies] ; get number of current monster
2214
jr .Continue
2215
.next
2216
ld a, [wEnemyMonSpecies]
2217
.Continue
2218
push hl
2219
call GetCryData
2220
ld b, a
2221
pop hl
2222
ld a, [wFrequencyModifier]
2223
add [hl]
2224
ld [wFrequencyModifier], a
2225
inc hl
2226
ld a, [wTempoModifier]
2227
add [hl]
2228
ld [wTempoModifier], a
2229
jr .done
2230
.NotCryMove
2231
ld a, [hli]
2232
ld [wFrequencyModifier], a
2233
ld a, [hli]
2234
ld [wTempoModifier], a
2235
.done
2236
ld a, b
2237
ret
2238
2239
IsCryMove:
2240
; set carry if the move animation involves playing a monster cry
2241
ld a, [wAnimationID]
2242
cp GROWL
2243
jr z, .CryMove
2244
cp ROAR
2245
jr z, .CryMove
2246
and a ; clear carry
2247
ret
2248
.CryMove
2249
scf
2250
ret
2251
2252
INCLUDE "data/moves/sfx.asm"
2253
2254
CopyPicTiles:
2255
ldh a, [hWhoseTurn]
2256
and a
2257
ld a, $31 ; base tile ID of player mon sprite
2258
jr z, .next
2259
; enemy turn
2260
xor a ; base tile ID of enemy mon sprite
2261
.next
2262
ldh [hBaseTileID], a
2263
jr CopyTileIDs_NoBGTransfer
2264
2265
; copy the tiles used when a mon is being sent out of or into a pokeball
2266
CopyDownscaledMonTiles:
2267
call GetPredefRegisters
2268
ld a, [wDownscaledMonSize]
2269
and a
2270
jr nz, .smallerSize
2271
ld de, DownscaledMonTiles_5x5
2272
jr CopyTileIDs_NoBGTransfer
2273
.smallerSize
2274
ld de, DownscaledMonTiles_3x3
2275
; fall through
2276
2277
CopyTileIDs_NoBGTransfer:
2278
xor a
2279
ldh [hAutoBGTransferEnabled], a
2280
; fall through
2281
2282
; b = number of rows
2283
; c = number of columns
2284
CopyTileIDs:
2285
push hl
2286
.rowLoop
2287
push bc
2288
push hl
2289
ldh a, [hBaseTileID]
2290
ld b, a
2291
.columnLoop
2292
ld a, [de]
2293
add b
2294
inc de
2295
ld [hli], a
2296
dec c
2297
jr nz, .columnLoop
2298
pop hl
2299
ld bc, SCREEN_WIDTH
2300
add hl, bc
2301
pop bc
2302
dec b
2303
jr nz, .rowLoop
2304
ld a, $1
2305
ldh [hAutoBGTransferEnabled], a
2306
pop hl
2307
ret
2308
2309
INCLUDE "data/tilemaps.asm"
2310
2311
AnimationLeavesFalling:
2312
; Makes leaves float down from the top of the screen. This is used
2313
; in Razor Leaf's animation.
2314
ldh a, [rOBP0]
2315
push af
2316
ld a, [wAnimPalette]
2317
ldh [rOBP0], a
2318
ld d, $37 ; leaf tile
2319
ld a, 3 ; number of leaves
2320
ld [wNumFallingObjects], a
2321
call AnimationFallingObjects
2322
pop af
2323
ldh [rOBP0], a
2324
ret
2325
2326
AnimationPetalsFalling:
2327
; Makes lots of petals fall down from the top of the screen. It's used in
2328
; the animation for Petal Dance.
2329
ld d, $71 ; petal tile
2330
ld a, 20 ; number of petals
2331
ld [wNumFallingObjects], a
2332
call AnimationFallingObjects
2333
jp ClearSprites
2334
2335
AnimationFallingObjects:
2336
ld c, a
2337
ld a, 1
2338
call InitMultipleObjectsOAM
2339
call FallingObjects_InitXCoords
2340
call FallingObjects_InitMovementData
2341
ld hl, wShadowOAM
2342
ld [hl], 0
2343
.loop
2344
ld hl, wFallingObjectsMovementData
2345
ld de, 0
2346
ld a, [wNumFallingObjects]
2347
ld c, a
2348
.innerLoop
2349
push bc
2350
push hl
2351
push de
2352
ld a, [hl]
2353
ld [wFallingObjectMovementByte], a
2354
call FallingObjects_UpdateMovementByte
2355
call FallingObjects_UpdateOAMEntry
2356
pop de
2357
ld hl, 4
2358
add hl, de
2359
ld e, l
2360
ld d, h
2361
pop hl
2362
ld a, [wFallingObjectMovementByte]
2363
ld [hli], a
2364
pop bc
2365
dec c
2366
jr nz, .innerLoop
2367
call Delay3
2368
ld hl, wShadowOAM
2369
ld a, [hl] ; Y
2370
cp 104 ; has the top falling object reached 104 yet?
2371
jr nz, .loop ; keep moving the falling objects down until it does
2372
ret
2373
2374
FallingObjects_UpdateOAMEntry:
2375
; Increases Y by 2 pixels and adjusts X and X flip based on the falling object's
2376
; movement byte.
2377
ld hl, wShadowOAM
2378
add hl, de
2379
ld a, [hl]
2380
inc a
2381
inc a
2382
cp 112
2383
jr c, .next
2384
ld a, SCREEN_HEIGHT_PX + OAM_Y_OFS ; if Y >= 112, put it off-screen
2385
.next
2386
ld [hli], a ; Y
2387
ld a, [wFallingObjectMovementByte]
2388
ld b, a
2389
ld de, FallingObjects_DeltaXs
2390
and $7f
2391
add e
2392
jr nc, .noCarry
2393
inc d
2394
.noCarry
2395
ld e, a
2396
ld a, b
2397
and $80
2398
jr nz, .movingLeft
2399
; moving right
2400
ld a, [de]
2401
add [hl]
2402
ld [hli], a ; X
2403
inc hl
2404
xor a ; no horizontal flip
2405
jr .next2
2406
.movingLeft
2407
ld a, [de]
2408
ld b, a
2409
ld a, [hl]
2410
sub b
2411
ld [hli], a ; X
2412
inc hl
2413
ld a, OAM_XFLIP
2414
.next2
2415
ld [hl], a ; attribute
2416
ret
2417
2418
FallingObjects_DeltaXs:
2419
db 0, 1, 3, 5, 7, 9, 11, 13, 15
2420
2421
FallingObjects_UpdateMovementByte:
2422
ld a, [wFallingObjectMovementByte]
2423
inc a
2424
ld b, a
2425
and $7f
2426
cp 9 ; have we reached the end of the delta-Xs?
2427
ld a, b
2428
jr nz, .next
2429
; We've reached the end of the delta-Xs, so wrap to the start and change
2430
; direction from right to left or vice versa.
2431
and $80
2432
xor $80
2433
.next
2434
ld [wFallingObjectMovementByte], a
2435
ret
2436
2437
FallingObjects_InitXCoords:
2438
ld hl, wShadowOAMSprite00XCoord
2439
ld de, FallingObjects_InitialXCoords
2440
ld a, [wNumFallingObjects]
2441
ld c, a
2442
.loop
2443
ld a, [de]
2444
ld [hli], a
2445
inc hl
2446
inc hl
2447
inc hl
2448
inc de
2449
dec c
2450
jr nz, .loop
2451
ret
2452
2453
FallingObjects_InitialXCoords:
2454
db $38, $40, $50, $60, $70, $88, $90, $56, $67, $4A, $77, $84, $98, $32, $22, $5C, $6C, $7D, $8E, $99
2455
2456
FallingObjects_InitMovementData:
2457
ld hl, wFallingObjectsMovementData
2458
ld de, FallingObjects_InitialMovementData
2459
ld a, [wNumFallingObjects]
2460
ld c, a
2461
.loop
2462
ld a, [de]
2463
ld [hli], a
2464
inc de
2465
dec c
2466
jr nz, .loop
2467
ret
2468
2469
FallingObjects_InitialMovementData:
2470
db $00, $84, $06, $81, $02, $88, $01, $83, $05, $89, $09, $80, $07, $87, $03, $82, $04, $85, $08, $86
2471
2472
AnimationShakeEnemyHUD:
2473
; Shakes the enemy HUD.
2474
2475
; Make a copy of the back pic's tile patterns in sprite tile pattern VRAM.
2476
ld de, vBackPic
2477
ld hl, vSprites
2478
ld bc, PIC_SIZE
2479
call CopyVideoData
2480
2481
xor a
2482
ldh [hSCX], a
2483
2484
; Copy wTileMap to BG map 0. The regular BG (not the window) is set to use
2485
; map 0 and can be scrolled with SCX, which allows a shaking effect.
2486
ld hl, vBGMap0
2487
call BattleAnimCopyTileMapToVRAM
2488
2489
; Now that the regular BG is showing the same thing the window was, move the
2490
; window off the screen so that we can modify its contents below.
2491
ld a, SCREEN_HEIGHT_PX
2492
ldh [hWY], a
2493
2494
; Copy wTileMap to VRAM such that the row below the enemy HUD (in wTileMap) is
2495
; lined up with row 0 of the window.
2496
ld hl, vBGMap1 - $20 * 7
2497
call BattleAnimCopyTileMapToVRAM
2498
2499
; Move the window so that the row below the enemy HUD (in BG map 0) lines up
2500
; with the top row of the window on the screen. This makes it so that the window
2501
; covers everything below the enemy HD with a copy that looks just like what
2502
; was there before.
2503
ld a, 7 * 8
2504
ldh [hWY], a
2505
2506
; Write OAM entries so that the copy of the back pic from the top of this
2507
; function shows up on screen. We need this because the back pic's Y coordinates
2508
; range overlaps with that of the enemy HUD and we don't want to shake the top
2509
; of the back pic when we shake the enemy HUD. The OAM copy won't be affected
2510
; by SCX.
2511
call ShakeEnemyHUD_WritePlayerMonPicOAM
2512
2513
ld hl, vBGMap0
2514
call BattleAnimCopyTileMapToVRAM
2515
2516
; Remove the back pic from the BG map.
2517
call AnimationHideMonPic
2518
call Delay3
2519
2520
; Use SCX to shake the regular BG. The window and the back pic OAM copy are
2521
; not affected.
2522
lb de, 2, 8
2523
call ShakeEnemyHUD_ShakeBG
2524
2525
; Restore the original graphics.
2526
call AnimationShowMonPic
2527
call ClearSprites
2528
ld a, SCREEN_HEIGHT_PX
2529
ldh [hWY], a
2530
ld hl, vBGMap1
2531
call BattleAnimCopyTileMapToVRAM
2532
xor a
2533
ldh [hWY], a
2534
call SaveScreenTilesToBuffer1
2535
ld hl, vBGMap0
2536
call BattleAnimCopyTileMapToVRAM
2537
call ClearScreen
2538
call Delay3
2539
call LoadScreenTilesFromBuffer1
2540
ld hl, vBGMap1
2541
jp BattleAnimCopyTileMapToVRAM
2542
2543
; b = tile ID list index
2544
; c = base tile ID
2545
CopyTileIDsFromList:
2546
call GetPredefRegisters
2547
ld a, c
2548
ldh [hBaseTileID], a
2549
ld a, b
2550
push hl
2551
call GetTileIDList
2552
pop hl
2553
jp CopyTileIDs
2554
2555
ShakeEnemyHUD_ShakeBG:
2556
ldh a, [hSCX]
2557
ld [wTempSCX], a
2558
.loop
2559
ld a, [wTempSCX]
2560
add d
2561
ldh [hSCX], a
2562
ld c, 2
2563
call DelayFrames
2564
ld a, [wTempSCX]
2565
sub d
2566
ldh [hSCX], a
2567
ld c, 2
2568
call DelayFrames
2569
dec e
2570
jr nz, .loop
2571
ld a, [wTempSCX]
2572
ldh [hSCX], a
2573
ret
2574
2575
BattleAnimCopyTileMapToVRAM:
2576
ld a, h
2577
ldh [hAutoBGTransferDest + 1], a
2578
ld a, l
2579
ldh [hAutoBGTransferDest], a
2580
jp Delay3
2581
2582
TossBallAnimation:
2583
ld a, [wIsInBattle]
2584
cp 2
2585
jr z, .BlockBall ; if in trainer battle, play different animation
2586
ld a, [wPokeBallAnimData]
2587
ld b, a
2588
2589
; upper nybble: how many animations (from PokeBallAnimations) to play
2590
; this will be 4 for successful capture, 6 for breakout
2591
and $F0
2592
swap a
2593
ld c, a
2594
2595
; lower nybble: number of shakes
2596
; store these for later
2597
ld a, b
2598
and $F
2599
ld [wNumShakes], a
2600
2601
ld hl, .PokeBallAnimations
2602
; choose which toss animation to use
2603
ld a, [wCurItem]
2604
cp POKE_BALL
2605
ld b, TOSS_ANIM
2606
jr z, .done
2607
cp GREAT_BALL
2608
ld b, GREATTOSS_ANIM
2609
jr z, .done
2610
ld b, ULTRATOSS_ANIM
2611
.done
2612
ld a, b
2613
.PlayNextAnimation
2614
ld [wAnimationID], a
2615
push bc
2616
push hl
2617
call PlayAnimation
2618
pop hl
2619
ld a, [hli]
2620
pop bc
2621
dec c
2622
jr nz, .PlayNextAnimation
2623
ret
2624
2625
.PokeBallAnimations:
2626
; sequence of animations that make up the Poké Ball toss
2627
db POOF_ANIM, HIDEPIC_ANIM, SHAKE_ANIM, POOF_ANIM, SHOWPIC_ANIM
2628
2629
.BlockBall
2630
ld a, TOSS_ANIM
2631
ld [wAnimationID], a
2632
call PlayAnimation
2633
ld a, SFX_FAINT_THUD
2634
call PlaySound
2635
ld a, BLOCKBALL_ANIM
2636
ld [wAnimationID], a
2637
jp PlayAnimation
2638
2639
PlayApplyingAttackSound:
2640
; play a different sound depending if move is not very effective, neutral, or super-effective
2641
; don't play any sound at all if move is ineffective
2642
call WaitForSoundToFinish
2643
ld a, [wDamageMultipliers]
2644
and $7f
2645
ret z
2646
cp 10
2647
ld a, $20
2648
ld b, $30
2649
ld c, SFX_DAMAGE
2650
jr z, .playSound
2651
ld a, $e0
2652
ld b, $ff
2653
ld c, SFX_SUPER_EFFECTIVE
2654
jr nc, .playSound
2655
ld a, $50
2656
ld b, $1
2657
ld c, SFX_NOT_VERY_EFFECTIVE
2658
.playSound
2659
ld [wFrequencyModifier], a
2660
ld a, b
2661
ld [wTempoModifier], a
2662
ld a, c
2663
jp PlaySound
2664
2665