Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pret
GitHub Repository: pret/pokered
Path: blob/master/engine/battle/animations.asm
1271 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
.noTransformation
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
.afterDrawingTiles
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
.doSpecialEffect
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, .isNotType5
299
.isType5
300
call GetSubanimationTransform2
301
jr .saveTransformation
302
.isNotType5
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 .next4
431
.animationsDisabled
432
ld c, 30
433
call DelayFrames
434
.next4
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, $10
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
ld b, $5
1101
1102
AnimationShakeScreenVertically:
1103
predef_jump PredefShakeScreenVertically
1104
1105
AnimationShakeScreen:
1106
; Shakes the screen for a while. Used in Earthquake/Fissure/etc. animations.
1107
ld b, $8
1108
1109
AnimationShakeScreenHorizontallyFast:
1110
predef_jump PredefShakeScreenHorizontally
1111
1112
AnimationWaterDropletsEverywhere:
1113
; Draws water droplets all over the screen and makes them
1114
; scroll. It's hard to describe, but it's the main animation
1115
; in Surf/Mist/Toxic.
1116
xor a
1117
ld [wWhichBattleAnimTileset], a
1118
call LoadMoveAnimationTiles
1119
ld d, 32
1120
ld a, -16
1121
ld [wBaseCoordX], a
1122
ld a, $71
1123
ld [wDropletTile], a
1124
.loop
1125
ld a, 16
1126
ld [wBaseCoordY], a
1127
ld a, 0
1128
ld [wUnusedWaterDropletsByte], a
1129
call _AnimationWaterDroplets
1130
ld a, 24
1131
ld [wBaseCoordY], a
1132
ld a, 32
1133
ld [wUnusedWaterDropletsByte], a
1134
call _AnimationWaterDroplets
1135
dec d
1136
jr nz, .loop
1137
ret
1138
1139
_AnimationWaterDroplets:
1140
ld hl, wShadowOAM
1141
.loop
1142
ld a, [wBaseCoordY]
1143
ld [hli], a ; Y
1144
ld a, [wBaseCoordX]
1145
add 27
1146
ld [wBaseCoordX], a
1147
ld [hli], a ; X
1148
ld a, [wDropletTile]
1149
ld [hli], a ; tile
1150
xor a
1151
ld [hli], a ; attribute
1152
ld a, [wBaseCoordX]
1153
cp 144
1154
jr c, .loop
1155
sub 168
1156
ld [wBaseCoordX], a
1157
ld a, [wBaseCoordY]
1158
add 16
1159
ld [wBaseCoordY], a
1160
cp 112
1161
jr c, .loop
1162
call AnimationCleanOAM
1163
jp DelayFrame
1164
1165
AnimationSlideMonUp:
1166
; Slides the mon's sprite upwards.
1167
ld c, 7
1168
ldh a, [hWhoseTurn]
1169
and a
1170
hlcoord 1, 6
1171
decoord 1, 5
1172
ld a, $30
1173
jr z, .next
1174
hlcoord 12, 1
1175
decoord 12, 0
1176
ld a, $ff
1177
.next
1178
ld [wSlideMonUpBottomRowLeftTile], a
1179
jp _AnimationSlideMonUp
1180
1181
AnimationSlideMonDown:
1182
; Slides the mon's sprite down out of the screen.
1183
xor a ; TILEMAP_MON_PIC
1184
call GetTileIDList
1185
.loop
1186
call GetMonSpriteTileMapPointerFromRowCount
1187
push bc
1188
push de
1189
call CopyPicTiles
1190
call Delay3
1191
call AnimationHideMonPic
1192
pop de
1193
pop bc
1194
dec b
1195
jr nz, .loop
1196
ret
1197
1198
AnimationSlideMonOff:
1199
; Slides the mon's sprite off the screen horizontally.
1200
ld e, 8
1201
ld a, 3
1202
ld [wSlideMonDelay], a
1203
jp _AnimationSlideMonOff
1204
1205
AnimationSlideEnemyMonOff:
1206
; Slides the enemy mon off the screen horizontally.
1207
ld hl, AnimationSlideMonOff
1208
jp CallWithTurnFlipped
1209
1210
_AnimationSlideMonUp:
1211
push de
1212
push hl
1213
push bc
1214
1215
; In each iteration, slide up all rows but the top one (which is overwritten).
1216
ld b, 6
1217
.slideLoop
1218
push bc
1219
push de
1220
push hl
1221
ld bc, 7
1222
call CopyData
1223
; Note that de and hl are popped in the same order they are pushed, swapping
1224
; their values. When CopyData is called, hl points to a tile 1 row below
1225
; the one de points to. To maintain this relationship, after swapping, we add 2
1226
; rows to hl so that it is 1 row below again.
1227
pop de
1228
pop hl
1229
ld bc, SCREEN_WIDTH * 2
1230
add hl, bc
1231
pop bc
1232
dec b
1233
jr nz, .slideLoop
1234
1235
; Fill in the bottom row of the mon pic with the next row's tile IDs.
1236
ldh a, [hWhoseTurn]
1237
and a
1238
hlcoord 1, 11
1239
jr z, .next
1240
hlcoord 12, 6
1241
.next
1242
ld a, [wSlideMonUpBottomRowLeftTile]
1243
inc a
1244
ld [wSlideMonUpBottomRowLeftTile], a
1245
ld c, 7
1246
.fillBottomRowLoop
1247
ld [hli], a
1248
add 7
1249
dec c
1250
jr nz, .fillBottomRowLoop
1251
1252
ld c, 2
1253
call DelayFrames
1254
pop bc
1255
pop hl
1256
pop de
1257
dec c
1258
jr nz, _AnimationSlideMonUp
1259
ret
1260
1261
ShakeEnemyHUD_WritePlayerMonPicOAM:
1262
; Writes the OAM entries for a copy of the player mon's pic in OAM.
1263
; The top 5 rows are reproduced in OAM, although only 2 are actually needed.
1264
ld a, $10
1265
ld [wBaseCoordX], a
1266
ld a, $30
1267
ld [wBaseCoordY], a
1268
ld hl, wShadowOAM
1269
ld d, 0
1270
ld c, 7
1271
.loop
1272
ld a, [wBaseCoordY]
1273
ld e, a
1274
ld b, 5
1275
.innerLoop
1276
call BattleAnimWriteOAMEntry
1277
inc d
1278
dec b
1279
jr nz, .innerLoop
1280
dec c
1281
ret z
1282
inc d
1283
inc d
1284
ld a, [wBaseCoordX]
1285
add 8
1286
ld [wBaseCoordX], a
1287
jr .loop
1288
1289
BattleAnimWriteOAMEntry:
1290
; Y coordinate = e (increased by 8 each call, before the write to OAM)
1291
; X coordinate = [wBaseCoordX]
1292
; tile = d
1293
; attributes = 0
1294
ld a, e
1295
add 8
1296
ld e, a
1297
ld [hli], a
1298
ld a, [wBaseCoordX]
1299
ld [hli], a
1300
ld a, d
1301
ld [hli], a
1302
xor a
1303
ld [hli], a
1304
ret
1305
1306
AdjustOAMBlockXPos:
1307
ld l, e
1308
ld h, d
1309
1310
AdjustOAMBlockXPos2:
1311
ld de, 4
1312
.loop
1313
ld a, [wCoordAdjustmentAmount]
1314
ld b, a
1315
ld a, [hl]
1316
add b
1317
cp 168
1318
jr c, .skipPuttingEntryOffScreen
1319
; put off-screen if X >= 168
1320
dec hl
1321
ld a, 160
1322
ld [hli], a
1323
.skipPuttingEntryOffScreen
1324
ld [hl], a
1325
add hl, de
1326
dec c
1327
jr nz, .loop
1328
ret
1329
1330
AdjustOAMBlockYPos:
1331
ld l, e
1332
ld h, d
1333
1334
AdjustOAMBlockYPos2:
1335
ld de, 4
1336
.loop
1337
ld a, [wCoordAdjustmentAmount]
1338
ld b, a
1339
ld a, [hl]
1340
add b
1341
cp 112
1342
jr c, .skipSettingPreviousEntrysAttribute
1343
dec hl
1344
ld a, 160 ; bug, sets previous OAM entry's attribute
1345
ld [hli], a
1346
.skipSettingPreviousEntrysAttribute
1347
ld [hl], a
1348
add hl, de
1349
dec c
1350
jr nz, .loop
1351
ret
1352
1353
AnimationBlinkEnemyMon:
1354
; Make the enemy mon's sprite blink on and off for a second or two
1355
ld hl, AnimationBlinkMon
1356
jp CallWithTurnFlipped
1357
1358
AnimationBlinkMon:
1359
; Make the mon's sprite blink on and off for a second or two.
1360
push af
1361
ld c, 6
1362
.loop
1363
push bc
1364
call AnimationHideMonPic
1365
ld c, 5
1366
call DelayFrames
1367
call AnimationShowMonPic
1368
ld c, 5
1369
call DelayFrames
1370
pop bc
1371
dec c
1372
jr nz, .loop
1373
pop af
1374
ret
1375
1376
AnimationFlashMonPic:
1377
; Flashes the mon's sprite on and off
1378
ld a, [wBattleMonSpecies]
1379
ld [wChangeMonPicPlayerTurnSpecies], a
1380
ld a, [wEnemyMonSpecies]
1381
ld [wChangeMonPicEnemyTurnSpecies], a
1382
jp ChangeMonPic
1383
1384
AnimationFlashEnemyMonPic:
1385
; Flashes the enemy mon's sprite on and off
1386
ld hl, AnimationFlashMonPic
1387
jp CallWithTurnFlipped
1388
1389
AnimationShowMonPic:
1390
xor a ; TILEMAP_MON_PIC
1391
call GetTileIDList
1392
call GetMonSpriteTileMapPointerFromRowCount
1393
call CopyPicTiles
1394
jp Delay3
1395
1396
AnimationShowEnemyMonPic:
1397
; Shows the enemy mon's front sprite. Used in animations like Seismic Toss
1398
; to make the mon's sprite reappear after disappears offscreen.
1399
ld hl, AnimationShowMonPic
1400
jp CallWithTurnFlipped
1401
1402
AnimationShakeBackAndForth:
1403
; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
1404
; The mon's sprite disappears after this animation.
1405
ldh a, [hWhoseTurn]
1406
and a
1407
hlcoord 0, 5
1408
decoord 2, 5
1409
jr z, .next
1410
hlcoord 11, 0
1411
decoord 13, 0
1412
1413
.next
1414
xor a ; TILEMAP_MON_PIC
1415
ld c, $10
1416
.loop
1417
push af
1418
push bc
1419
push de
1420
push hl
1421
push hl
1422
push de
1423
push af
1424
push hl
1425
push hl
1426
call GetTileIDList
1427
pop hl
1428
call CopyPicTiles
1429
call Delay3
1430
pop hl
1431
lb bc, 7, 9
1432
call ClearScreenArea
1433
pop af
1434
call GetTileIDList
1435
pop hl
1436
call CopyPicTiles
1437
call Delay3
1438
pop hl
1439
lb bc, 7, 9
1440
call ClearScreenArea
1441
pop hl
1442
pop de
1443
pop bc
1444
pop af
1445
dec c
1446
jr nz, .loop
1447
ret
1448
1449
AnimationMoveMonHorizontally:
1450
; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
1451
; animations like Tackle/Body Slam.
1452
call AnimationHideMonPic
1453
ldh a, [hWhoseTurn]
1454
and a
1455
hlcoord 2, 5
1456
jr z, .next
1457
hlcoord 11, 0
1458
.next
1459
xor a ; TILEMAP_MON_PIC
1460
push hl
1461
call GetTileIDList
1462
pop hl
1463
call CopyPicTiles
1464
ld c, 3
1465
jp DelayFrames
1466
1467
AnimationResetMonPosition:
1468
; Resets the mon's sprites to be located at the normal coordinates.
1469
ldh a, [hWhoseTurn]
1470
and a
1471
ld a, 5 * SCREEN_WIDTH + 2
1472
jr z, .next
1473
ld a, 11
1474
.next
1475
call ClearMonPicFromTileMap
1476
jp AnimationShowMonPic
1477
1478
AnimationSpiralBallsInward:
1479
; Creates an effect that looks like energy balls spiralling into the
1480
; player mon's sprite. Used in Focus Energy, for example.
1481
ldh a, [hWhoseTurn]
1482
and a
1483
jr z, .playerTurn
1484
ld a, -40
1485
ld [wSpiralBallsBaseY], a
1486
ld a, 80
1487
ld [wSpiralBallsBaseX], a
1488
jr .next
1489
.playerTurn
1490
xor a
1491
ld [wSpiralBallsBaseY], a
1492
ld [wSpiralBallsBaseX], a
1493
.next
1494
ld d, $7a ; ball tile
1495
ld c, 3 ; number of balls
1496
xor a
1497
call InitMultipleObjectsOAM
1498
ld hl, SpiralBallAnimationCoordinates
1499
.loop
1500
push hl
1501
ld c, 3
1502
ld de, wShadowOAM
1503
.innerLoop
1504
ld a, [hl]
1505
cp $ff
1506
jr z, .done
1507
ld a, [wSpiralBallsBaseY]
1508
add [hl]
1509
ld [de], a ; Y
1510
inc de
1511
inc hl
1512
ld a, [wSpiralBallsBaseX]
1513
add [hl]
1514
ld [de], a ; X
1515
inc hl
1516
inc de
1517
inc de
1518
inc de
1519
dec c
1520
jr nz, .innerLoop
1521
ld c, 5
1522
call DelayFrames
1523
pop hl
1524
inc hl
1525
inc hl
1526
jr .loop
1527
.done
1528
pop hl
1529
call AnimationCleanOAM
1530
jp AnimationFlashScreen
1531
1532
SpiralBallAnimationCoordinates:
1533
; y, x pairs
1534
; This is the sequence of screen coordinates that the spiralling
1535
; balls are positioned at.
1536
db $38, $28
1537
db $40, $18
1538
db $50, $10
1539
db $60, $18
1540
db $68, $28
1541
db $60, $38
1542
db $50, $40
1543
db $40, $38
1544
db $40, $28
1545
db $46, $1E
1546
db $50, $18
1547
db $5B, $1E
1548
db $60, $28
1549
db $5B, $32
1550
db $50, $38
1551
db $46, $32
1552
db $48, $28
1553
db $50, $20
1554
db $58, $28
1555
db $50, $30
1556
db $50, $28
1557
db -1 ; end
1558
1559
AnimationSquishMonPic:
1560
; Squishes the mon's sprite horizontally making it
1561
; disappear. Used by Teleport/Sky Attack animations.
1562
ld c, 4
1563
.loop
1564
push bc
1565
ldh a, [hWhoseTurn]
1566
and a
1567
jr z, .playerTurn
1568
hlcoord 16, 0
1569
decoord 14, 0
1570
jr .next
1571
.playerTurn
1572
hlcoord 5, 5
1573
decoord 3, 5
1574
.next
1575
push de
1576
xor a ; left
1577
ld [wSquishMonCurrentDirection], a
1578
call _AnimationSquishMonPic
1579
pop hl
1580
ld a, 1 ; right
1581
ld [wSquishMonCurrentDirection], a
1582
call _AnimationSquishMonPic
1583
pop bc
1584
dec c
1585
jr nz, .loop
1586
call AnimationHideMonPic
1587
ld c, 2
1588
jp DelayFrame
1589
1590
_AnimationSquishMonPic:
1591
ld c, 7
1592
.loop
1593
push bc
1594
push hl
1595
ld c, 3
1596
ld a, [wSquishMonCurrentDirection]
1597
cp 0
1598
jr nz, .right
1599
call AnimCopyRowLeft
1600
dec hl
1601
jr .next
1602
.right
1603
call AnimCopyRowRight
1604
inc hl
1605
.next
1606
ld [hl], " "
1607
pop hl
1608
ld de, SCREEN_WIDTH
1609
add hl, de
1610
pop bc
1611
dec c
1612
jr nz, .loop
1613
jp Delay3
1614
1615
AnimationShootBallsUpward:
1616
; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
1617
; animations.
1618
ldh a, [hWhoseTurn]
1619
and a
1620
jr z, .playerTurn
1621
lb bc, 0, 16 * 8
1622
jr .next
1623
.playerTurn
1624
lb bc, 6 * 8, 5 * 8
1625
.next
1626
ld a, b
1627
ld [wBaseCoordY], a
1628
ld a, c
1629
ld [wBaseCoordX], a
1630
lb bc, 5, 1
1631
call _AnimationShootBallsUpward
1632
jp AnimationCleanOAM
1633
1634
_AnimationShootBallsUpward:
1635
push bc
1636
xor a
1637
ld [wWhichBattleAnimTileset], a
1638
call LoadMoveAnimationTiles
1639
pop bc
1640
ld d, $7a ; ball tile
1641
ld hl, wShadowOAM
1642
push bc
1643
ld a, [wBaseCoordY]
1644
ld e, a
1645
.initOAMLoop
1646
call BattleAnimWriteOAMEntry
1647
dec b
1648
jr nz, .initOAMLoop
1649
call DelayFrame
1650
pop bc
1651
ld a, b
1652
ld [wNumShootingBalls], a
1653
.loop
1654
push bc
1655
ld hl, wShadowOAM
1656
.innerLoop
1657
ld a, [wBaseCoordY]
1658
add 8
1659
ld e, a
1660
ld a, [hl]
1661
cp e ; has the ball reached the top?
1662
jr z, .reachedTop
1663
add -4 ; ball hasn't reached the top. move it up 4 pixels
1664
ld [hl], a
1665
jr .next
1666
.reachedTop
1667
; remove the ball once it has reached the top
1668
ld [hl], 0 ; put it off-screen
1669
ld a, [wNumShootingBalls]
1670
dec a
1671
ld [wNumShootingBalls], a
1672
.next
1673
ld de, 4
1674
add hl, de ; next OAM entry
1675
dec b
1676
jr nz, .innerLoop
1677
call DelayFrames
1678
pop bc
1679
ld a, [wNumShootingBalls]
1680
and a
1681
jr nz, .loop
1682
ret
1683
1684
AnimationShootManyBallsUpward:
1685
; Shoots several pillars of "energy" balls upward.
1686
ldh a, [hWhoseTurn]
1687
and a
1688
ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
1689
ld a, $50 ; y coordinate for "energy" ball pillar
1690
jr z, .player
1691
ld hl, UpwardBallsAnimXCoordinatesEnemyTurn
1692
ld a, $28 ; y coordinate for "energy" ball pillar
1693
.player
1694
ld [wSavedY], a
1695
.loop
1696
ld a, [wSavedY]
1697
ld [wBaseCoordY], a
1698
ld a, [hli]
1699
cp $ff
1700
jp z, AnimationCleanOAM
1701
ld [wBaseCoordX], a
1702
lb bc, 4, 1
1703
push hl
1704
call _AnimationShootBallsUpward
1705
pop hl
1706
jr .loop
1707
1708
UpwardBallsAnimXCoordinatesPlayerTurn:
1709
; List of x coordinates for each pillar of "energy" balls in the
1710
; AnimationShootManyBallsUpward animation. It's unused in the game.
1711
db $10, $40, $28, $18, $38, $30
1712
db -1 ; end
1713
1714
UpwardBallsAnimXCoordinatesEnemyTurn:
1715
; List of x coordinates for each pillar of "energy" balls in the
1716
; AnimationShootManyBallsUpward animation. It's unused in the game.
1717
db $60, $90, $78, $68, $88, $80
1718
db -1 ; end
1719
1720
AnimationMinimizeMon:
1721
; Changes the mon's sprite to a mini black sprite. Used by the
1722
; Minimize animation.
1723
ld hl, wTempPic
1724
push hl
1725
xor a
1726
ld bc, 7 * 7 * $10
1727
call FillMemory
1728
pop hl
1729
ld de, 7 * 3 * $10 + 4 * $10 + 4
1730
add hl, de
1731
ld de, MinimizedMonSprite
1732
ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
1733
.loop
1734
ld a, [de]
1735
ld [hli], a
1736
ld [hli], a
1737
inc de
1738
dec c
1739
jr nz, .loop
1740
call CopyTempPicToMonPic
1741
call Delay3
1742
jp AnimationShowMonPic
1743
1744
MinimizedMonSprite:
1745
; 8x5 partial tile graphic
1746
pusho b.X ; . = 0, X = 1
1747
db %...XX...
1748
db %..XXXX..
1749
db %.XXXXXX.
1750
db %..XXXX..
1751
db %..X..X..
1752
popo
1753
MinimizedMonSpriteEnd:
1754
1755
AnimationSlideMonDownAndHide:
1756
; Slides the mon's sprite down and disappears. Used in Acid Armor.
1757
ld a, TILEMAP_SLIDE_DOWN_MON_PIC_7X5
1758
ld c, 2
1759
.loop
1760
push bc
1761
push af
1762
call AnimationHideMonPic
1763
pop af
1764
push af
1765
call GetTileIDList
1766
call GetMonSpriteTileMapPointerFromRowCount
1767
call CopyPicTiles
1768
ld c, 8
1769
call DelayFrames
1770
pop af
1771
inc a
1772
pop bc
1773
dec c
1774
jr nz, .loop
1775
call AnimationHideMonPic
1776
ld hl, wTempPic
1777
ld bc, 7 * 7 tiles
1778
xor a
1779
call FillMemory
1780
jp CopyTempPicToMonPic
1781
1782
_AnimationSlideMonOff:
1783
; Slides the mon's sprite off the screen horizontally by e tiles and waits
1784
; [wSlideMonDelay] V-blanks each time the pic is slid by one tile.
1785
ldh a, [hWhoseTurn]
1786
and a
1787
jr z, .playerTurn
1788
hlcoord 12, 0
1789
jr .next
1790
.playerTurn
1791
hlcoord 0, 5
1792
.next
1793
ld d, 8 ; d's value is unused
1794
.slideLoop ; iterates once for each time the pic slides by one tile
1795
push hl
1796
ld b, 7
1797
.rowLoop ; iterates once for each row
1798
ld c, 8
1799
.tileLoop ; iterates once for each tile in the row
1800
ldh a, [hWhoseTurn]
1801
and a
1802
jr z, .playerTurn2
1803
call .EnemyNextTile
1804
jr .next2
1805
.playerTurn2
1806
call .PlayerNextTile
1807
.next2
1808
ld [hli], a
1809
dec c
1810
jr nz, .tileLoop
1811
push de
1812
ld de, SCREEN_WIDTH - 8
1813
add hl, de
1814
pop de
1815
dec b
1816
jr nz, .rowLoop
1817
ld a, [wSlideMonDelay]
1818
ld c, a
1819
call DelayFrames
1820
pop hl
1821
dec d
1822
dec e
1823
jr nz, .slideLoop
1824
ret
1825
1826
; Since mon pic tile numbers go from top to bottom, left to right in order,
1827
; adding the height of the mon pic in tiles to a tile number gives the tile
1828
; number of the tile one column to the right (and thus subtracting the height
1829
; gives the reverse). If the next tile would be past the edge of the pic, the 2
1830
; functions below catch it by checking if the tile number is within the valid
1831
; range and if not, replacing it with a blank tile.
1832
1833
.PlayerNextTile
1834
ld a, [hl]
1835
add 7
1836
; This is a bug. The lower right corner tile of the mon back pic is blanked
1837
; while the mon is sliding off the screen. It should compare with the max tile
1838
; plus one instead.
1839
cp $61
1840
ret c
1841
ld a, " "
1842
ret
1843
1844
.EnemyNextTile
1845
ld a, [hl]
1846
sub 7
1847
; This has the same problem as above, but it has no visible effect because
1848
; the lower right tile is in the first column to slide off the screen.
1849
cp $30
1850
ret c
1851
ld a, " "
1852
ret
1853
1854
AnimationSlideMonHalfOff:
1855
; Slides the mon's sprite halfway off the screen. It's used in Softboiled.
1856
ld e, 4
1857
ld a, 4
1858
ld [wSlideMonDelay], a
1859
call _AnimationSlideMonOff
1860
jp Delay3
1861
1862
CopyTempPicToMonPic:
1863
ldh a, [hWhoseTurn]
1864
and a
1865
ld hl, vBackPic ; player turn
1866
jr z, .next
1867
ld hl, vFrontPic ; enemy turn
1868
.next
1869
ld de, wTempPic
1870
ld bc, 7 * 7
1871
jp CopyVideoData
1872
1873
AnimationWavyScreen:
1874
; used in Psywave/Psychic etc.
1875
ld hl, vBGMap0
1876
call BattleAnimCopyTileMapToVRAM
1877
call Delay3
1878
xor a
1879
ldh [hAutoBGTransferEnabled], a
1880
ld a, SCREEN_HEIGHT_PX
1881
ldh [hWY], a
1882
ld d, $80 ; terminator
1883
ld e, SCREEN_HEIGHT_PX - 1
1884
ld c, $ff
1885
ld hl, WavyScreenLineOffsets
1886
.loop
1887
push hl
1888
.innerLoop
1889
call WavyScreen_SetSCX
1890
ldh a, [rLY]
1891
cp e ; is it the last visible line in the frame?
1892
jr nz, .innerLoop ; keep going if not
1893
pop hl
1894
inc hl
1895
ld a, [hl]
1896
cp d ; have we reached the end?
1897
jr nz, .next
1898
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
1899
.next
1900
dec c
1901
jr nz, .loop
1902
xor a
1903
ldh [hWY], a
1904
call SaveScreenTilesToBuffer2
1905
call ClearScreen
1906
ld a, 1
1907
ldh [hAutoBGTransferEnabled], a
1908
call Delay3
1909
call LoadScreenTilesFromBuffer2
1910
ld hl, vBGMap1
1911
call BattleAnimCopyTileMapToVRAM
1912
ret
1913
1914
WavyScreen_SetSCX:
1915
ldh a, [rSTAT]
1916
and $3 ; is it H-blank?
1917
jr nz, WavyScreen_SetSCX ; wait until it's H-blank
1918
ld a, [hl]
1919
ldh [rSCX], a
1920
inc hl
1921
ld a, [hl]
1922
cp d ; have we reached the end?
1923
ret nz
1924
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
1925
ret
1926
1927
WavyScreenLineOffsets:
1928
; Sequence of horizontal line pixel offsets for the wavy screen animation.
1929
; This sequence vaguely resembles a sine wave.
1930
db 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1
1931
db 0, 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, -1
1932
db $80 ; terminator
1933
1934
AnimationSubstitute:
1935
; Changes the pokemon's sprite to the mini sprite
1936
ld hl, wTempPic
1937
xor a
1938
ld bc, 7 * 7 tiles
1939
call FillMemory
1940
ldh a, [hWhoseTurn]
1941
and a
1942
jr z, .playerTurn
1943
ld hl, MonsterSprite tile 0 ; facing down sprite
1944
ld de, wTempPic + $120
1945
call CopyMonsterSpriteData
1946
ld hl, MonsterSprite tile 1
1947
ld de, wTempPic + $120 + $70
1948
call CopyMonsterSpriteData
1949
ld hl, MonsterSprite tile 2
1950
ld de, wTempPic + $120 + $10
1951
call CopyMonsterSpriteData
1952
ld hl, MonsterSprite tile 3
1953
ld de, wTempPic + $120 + $10 + $70
1954
call CopyMonsterSpriteData
1955
jr .next
1956
.playerTurn
1957
ld hl, MonsterSprite tile 4 ; facing up sprite
1958
ld de, wTempPic + $120 + $70
1959
call CopyMonsterSpriteData
1960
ld hl, MonsterSprite tile 5
1961
ld de, wTempPic + $120 + $e0
1962
call CopyMonsterSpriteData
1963
ld hl, MonsterSprite tile 6
1964
ld de, wTempPic + $120 + $80
1965
call CopyMonsterSpriteData
1966
ld hl, MonsterSprite tile 7
1967
ld de, wTempPic + $120 + $f0
1968
call CopyMonsterSpriteData
1969
.next
1970
call CopyTempPicToMonPic
1971
jp AnimationShowMonPic
1972
1973
CopyMonsterSpriteData:
1974
ld bc, 1 tiles
1975
ld a, BANK(MonsterSprite)
1976
jp FarCopyData2
1977
1978
HideSubstituteShowMonAnim:
1979
ldh a, [hWhoseTurn]
1980
and a
1981
ld hl, wPlayerMonMinimized
1982
ld a, [wPlayerBattleStatus2]
1983
jr z, .next1
1984
ld hl, wEnemyMonMinimized
1985
ld a, [wEnemyBattleStatus2]
1986
.next1
1987
push hl
1988
; if the substitute broke, slide it down, else slide it offscreen horizontally
1989
bit HAS_SUBSTITUTE_UP, a
1990
jr nz, .substituteStillUp
1991
call AnimationSlideMonDown
1992
jr .next2
1993
.substituteStillUp
1994
call AnimationSlideMonOff
1995
.next2
1996
pop hl
1997
ld a, [hl]
1998
and a
1999
jp nz, AnimationMinimizeMon
2000
call AnimationFlashMonPic
2001
jp AnimationShowMonPic
2002
2003
ReshowSubstituteAnim:
2004
call AnimationSlideMonOff
2005
call AnimationSubstitute
2006
jp AnimationShowMonPic
2007
2008
AnimationBoundUpAndDown:
2009
; Bounces the mon's sprite up and down several times. It is used
2010
; by Splash's animation.
2011
ld c, 5
2012
.loop
2013
push bc
2014
call AnimationSlideMonDown
2015
pop bc
2016
dec c
2017
jr nz, .loop
2018
jp AnimationShowMonPic
2019
2020
AnimationTransformMon:
2021
; Redraws this mon's sprite as the back/front sprite of the opposing mon.
2022
; Used in Transform.
2023
ld a, [wEnemyMonSpecies]
2024
ld [wChangeMonPicPlayerTurnSpecies], a
2025
ld a, [wBattleMonSpecies]
2026
ld [wChangeMonPicEnemyTurnSpecies], a
2027
2028
ChangeMonPic:
2029
ldh a, [hWhoseTurn]
2030
and a
2031
jr z, .playerTurn
2032
ld a, [wChangeMonPicEnemyTurnSpecies]
2033
ld [wCurPartySpecies], a
2034
ld [wCurSpecies], a
2035
xor a
2036
ld [wSpriteFlipped], a
2037
call GetMonHeader
2038
hlcoord 12, 0
2039
call LoadFrontSpriteByMonIndex
2040
jr .done
2041
.playerTurn
2042
ld a, [wBattleMonSpecies2]
2043
push af
2044
ld a, [wChangeMonPicPlayerTurnSpecies]
2045
ld [wBattleMonSpecies2], a
2046
ld [wCurSpecies], a
2047
call GetMonHeader
2048
predef LoadMonBackPic
2049
xor a ; TILEMAP_MON_PIC
2050
call GetTileIDList
2051
call GetMonSpriteTileMapPointerFromRowCount
2052
call CopyPicTiles
2053
pop af
2054
ld [wBattleMonSpecies2], a
2055
.done
2056
ld b, SET_PAL_BATTLE
2057
jp RunPaletteCommand
2058
2059
AnimationHideEnemyMonPic:
2060
; Hides the enemy mon's sprite
2061
xor a
2062
ldh [hAutoBGTransferEnabled], a
2063
ld hl, AnimationHideMonPic
2064
call CallWithTurnFlipped
2065
ld a, $1
2066
ldh [hAutoBGTransferEnabled], a
2067
jp Delay3
2068
2069
InitMultipleObjectsOAM:
2070
; Writes c OAM entries with tile d.
2071
; Sets their Y coordinates to sequential multiples of 8, starting from 0.
2072
; Sets their X coordinates to 0.
2073
; Loads animation tileset a.
2074
push bc
2075
push de
2076
ld [wWhichBattleAnimTileset], a
2077
call LoadMoveAnimationTiles
2078
pop de
2079
pop bc
2080
xor a
2081
ld e, a
2082
ld [wBaseCoordX], a
2083
ld hl, wShadowOAM
2084
.loop
2085
call BattleAnimWriteOAMEntry
2086
dec c
2087
jr nz, .loop
2088
ret
2089
2090
AnimationHideMonPic:
2091
; Hides the mon's sprite.
2092
ldh a, [hWhoseTurn]
2093
and a
2094
jr z, .playerTurn
2095
ld a, 12
2096
jr ClearMonPicFromTileMap
2097
.playerTurn
2098
ld a, 5 * SCREEN_WIDTH + 1
2099
2100
ClearMonPicFromTileMap:
2101
push hl
2102
push de
2103
push bc
2104
ld e, a
2105
ld d, 0
2106
hlcoord 0, 0
2107
add hl, de
2108
lb bc, 7, 7
2109
call ClearScreenArea
2110
pop bc
2111
pop de
2112
pop hl
2113
ret
2114
2115
; puts the tile map destination address of a mon sprite in hl, given the row count in b
2116
; The usual row count is 7, but it may be smaller when sliding a mon sprite in/out,
2117
; in order to show only a portion of the mon sprite.
2118
GetMonSpriteTileMapPointerFromRowCount:
2119
push de
2120
ldh a, [hWhoseTurn]
2121
and a
2122
jr nz, .enemyTurn
2123
ld a, 5 * SCREEN_WIDTH + 1
2124
jr .next
2125
.enemyTurn
2126
ld a, 12
2127
.next
2128
hlcoord 0, 0
2129
ld e, a
2130
ld d, 0
2131
add hl, de
2132
ld a, 7
2133
sub b
2134
and a
2135
jr z, .done
2136
ld de, SCREEN_WIDTH
2137
.loop
2138
add hl, de
2139
dec a
2140
jr nz, .loop
2141
.done
2142
pop de
2143
ret
2144
2145
; Input:
2146
; a = tile ID list index
2147
; Output:
2148
; de = tile ID list pointer
2149
; b = number of rows
2150
; c = number of columns
2151
GetTileIDList:
2152
ld hl, TileIDListPointerTable
2153
ld e, a
2154
ld d, 0
2155
add hl, de
2156
add hl, de
2157
add hl, de
2158
ld a, [hli]
2159
ld e, a
2160
ld a, [hli]
2161
ld d, a
2162
ld a, [hli]
2163
ld b, a
2164
and $f
2165
ld c, a
2166
ld a, b
2167
swap a
2168
and $f
2169
ld b, a
2170
ret
2171
2172
AnimCopyRowLeft:
2173
; copy a row of c tiles 1 tile left
2174
ld a, [hld]
2175
ld [hli], a
2176
inc hl
2177
dec c
2178
jr nz, AnimCopyRowLeft
2179
ret
2180
2181
AnimCopyRowRight:
2182
; copy a row of c tiles 1 tile right
2183
ld a, [hli]
2184
ld [hld], a
2185
dec hl
2186
dec c
2187
jr nz, AnimCopyRowRight
2188
ret
2189
2190
; only used by the unreferenced PlayIntroMoveSound
2191
GetIntroMoveSound:
2192
ld a, b
2193
call GetMoveSound
2194
ld b, a
2195
ret
2196
2197
GetMoveSound:
2198
ld hl, MoveSoundTable
2199
ld e, a
2200
ld d, 0
2201
add hl, de
2202
add hl, de
2203
add hl, de
2204
ld a, [hli]
2205
ld b, a
2206
call IsCryMove
2207
jr nc, .NotCryMove
2208
ldh a, [hWhoseTurn]
2209
and a
2210
jr nz, .next
2211
ld a, [wBattleMonSpecies] ; get number of current monster
2212
jr .Continue
2213
.next
2214
ld a, [wEnemyMonSpecies]
2215
.Continue
2216
push hl
2217
call GetCryData
2218
ld b, a
2219
pop hl
2220
ld a, [wFrequencyModifier]
2221
add [hl]
2222
ld [wFrequencyModifier], a
2223
inc hl
2224
ld a, [wTempoModifier]
2225
add [hl]
2226
ld [wTempoModifier], a
2227
jr .done
2228
.NotCryMove
2229
ld a, [hli]
2230
ld [wFrequencyModifier], a
2231
ld a, [hli]
2232
ld [wTempoModifier], a
2233
.done
2234
ld a, b
2235
ret
2236
2237
IsCryMove:
2238
; set carry if the move animation involves playing a monster cry
2239
ld a, [wAnimationID]
2240
cp GROWL
2241
jr z, .CryMove
2242
cp ROAR
2243
jr z, .CryMove
2244
and a ; clear carry
2245
ret
2246
.CryMove
2247
scf
2248
ret
2249
2250
INCLUDE "data/moves/sfx.asm"
2251
2252
CopyPicTiles:
2253
ldh a, [hWhoseTurn]
2254
and a
2255
ld a, $31 ; base tile ID of player mon sprite
2256
jr z, .next
2257
; enemy turn
2258
xor a ; base tile ID of enemy mon sprite
2259
.next
2260
ldh [hBaseTileID], a
2261
jr CopyTileIDs_NoBGTransfer
2262
2263
; copy the tiles used when a mon is being sent out of or into a pokeball
2264
CopyDownscaledMonTiles:
2265
call GetPredefRegisters
2266
ld a, [wDownscaledMonSize]
2267
and a
2268
jr nz, .smallerSize
2269
ld de, DownscaledMonTiles_5x5
2270
jr CopyTileIDs_NoBGTransfer
2271
.smallerSize
2272
ld de, DownscaledMonTiles_3x3
2273
; fall through
2274
2275
CopyTileIDs_NoBGTransfer:
2276
xor a
2277
ldh [hAutoBGTransferEnabled], a
2278
; fall through
2279
2280
; b = number of rows
2281
; c = number of columns
2282
CopyTileIDs:
2283
push hl
2284
.rowLoop
2285
push bc
2286
push hl
2287
ldh a, [hBaseTileID]
2288
ld b, a
2289
.columnLoop
2290
ld a, [de]
2291
add b
2292
inc de
2293
ld [hli], a
2294
dec c
2295
jr nz, .columnLoop
2296
pop hl
2297
ld bc, SCREEN_WIDTH
2298
add hl, bc
2299
pop bc
2300
dec b
2301
jr nz, .rowLoop
2302
ld a, $1
2303
ldh [hAutoBGTransferEnabled], a
2304
pop hl
2305
ret
2306
2307
INCLUDE "data/tilemaps.asm"
2308
2309
AnimationLeavesFalling:
2310
; Makes leaves float down from the top of the screen. This is used
2311
; in Razor Leaf's animation.
2312
ldh a, [rOBP0]
2313
push af
2314
ld a, [wAnimPalette]
2315
ldh [rOBP0], a
2316
ld d, $37 ; leaf tile
2317
ld a, 3 ; number of leaves
2318
ld [wNumFallingObjects], a
2319
call AnimationFallingObjects
2320
pop af
2321
ldh [rOBP0], a
2322
ret
2323
2324
AnimationPetalsFalling:
2325
; Makes lots of petals fall down from the top of the screen. It's used in
2326
; the animation for Petal Dance.
2327
ld d, $71 ; petal tile
2328
ld a, 20 ; number of petals
2329
ld [wNumFallingObjects], a
2330
call AnimationFallingObjects
2331
jp ClearSprites
2332
2333
AnimationFallingObjects:
2334
ld c, a
2335
ld a, 1
2336
call InitMultipleObjectsOAM
2337
call FallingObjects_InitXCoords
2338
call FallingObjects_InitMovementData
2339
ld hl, wShadowOAM
2340
ld [hl], 0
2341
.loop
2342
ld hl, wFallingObjectsMovementData
2343
ld de, 0
2344
ld a, [wNumFallingObjects]
2345
ld c, a
2346
.innerLoop
2347
push bc
2348
push hl
2349
push de
2350
ld a, [hl]
2351
ld [wFallingObjectMovementByte], a
2352
call FallingObjects_UpdateMovementByte
2353
call FallingObjects_UpdateOAMEntry
2354
pop de
2355
ld hl, 4
2356
add hl, de
2357
ld e, l
2358
ld d, h
2359
pop hl
2360
ld a, [wFallingObjectMovementByte]
2361
ld [hli], a
2362
pop bc
2363
dec c
2364
jr nz, .innerLoop
2365
call Delay3
2366
ld hl, wShadowOAM
2367
ld a, [hl] ; Y
2368
cp 104 ; has the top falling object reached 104 yet?
2369
jr nz, .loop ; keep moving the falling objects down until it does
2370
ret
2371
2372
FallingObjects_UpdateOAMEntry:
2373
; Increases Y by 2 pixels and adjusts X and X flip based on the falling object's
2374
; movement byte.
2375
ld hl, wShadowOAM
2376
add hl, de
2377
ld a, [hl]
2378
inc a
2379
inc a
2380
cp 112
2381
jr c, .next
2382
ld a, 160 ; if Y >= 112, put it off-screen
2383
.next
2384
ld [hli], a ; Y
2385
ld a, [wFallingObjectMovementByte]
2386
ld b, a
2387
ld de, FallingObjects_DeltaXs
2388
and $7f
2389
add e
2390
jr nc, .noCarry
2391
inc d
2392
.noCarry
2393
ld e, a
2394
ld a, b
2395
and $80
2396
jr nz, .movingLeft
2397
; moving right
2398
ld a, [de]
2399
add [hl]
2400
ld [hli], a ; X
2401
inc hl
2402
xor a ; no horizontal flip
2403
jr .next2
2404
.movingLeft
2405
ld a, [de]
2406
ld b, a
2407
ld a, [hl]
2408
sub b
2409
ld [hli], a ; X
2410
inc hl
2411
ld a, OAM_XFLIP
2412
.next2
2413
ld [hl], a ; attribute
2414
ret
2415
2416
FallingObjects_DeltaXs:
2417
db 0, 1, 3, 5, 7, 9, 11, 13, 15
2418
2419
FallingObjects_UpdateMovementByte:
2420
ld a, [wFallingObjectMovementByte]
2421
inc a
2422
ld b, a
2423
and $7f
2424
cp 9 ; have we reached the end of the delta-Xs?
2425
ld a, b
2426
jr nz, .next
2427
; We've reached the end of the delta-Xs, so wrap to the start and change
2428
; direction from right to left or vice versa.
2429
and $80
2430
xor $80
2431
.next
2432
ld [wFallingObjectMovementByte], a
2433
ret
2434
2435
FallingObjects_InitXCoords:
2436
ld hl, wShadowOAMSprite00XCoord
2437
ld de, FallingObjects_InitialXCoords
2438
ld a, [wNumFallingObjects]
2439
ld c, a
2440
.loop
2441
ld a, [de]
2442
ld [hli], a
2443
inc hl
2444
inc hl
2445
inc hl
2446
inc de
2447
dec c
2448
jr nz, .loop
2449
ret
2450
2451
FallingObjects_InitialXCoords:
2452
db $38, $40, $50, $60, $70, $88, $90, $56, $67, $4A, $77, $84, $98, $32, $22, $5C, $6C, $7D, $8E, $99
2453
2454
FallingObjects_InitMovementData:
2455
ld hl, wFallingObjectsMovementData
2456
ld de, FallingObjects_InitialMovementData
2457
ld a, [wNumFallingObjects]
2458
ld c, a
2459
.loop
2460
ld a, [de]
2461
ld [hli], a
2462
inc de
2463
dec c
2464
jr nz, .loop
2465
ret
2466
2467
FallingObjects_InitialMovementData:
2468
db $00, $84, $06, $81, $02, $88, $01, $83, $05, $89, $09, $80, $07, $87, $03, $82, $04, $85, $08, $86
2469
2470
AnimationShakeEnemyHUD:
2471
; Shakes the enemy HUD.
2472
2473
; Make a copy of the back pic's tile patterns in sprite tile pattern VRAM.
2474
ld de, vBackPic
2475
ld hl, vSprites
2476
ld bc, 7 * 7
2477
call CopyVideoData
2478
2479
xor a
2480
ldh [hSCX], a
2481
2482
; Copy wTileMap to BG map 0. The regular BG (not the window) is set to use
2483
; map 0 and can be scrolled with SCX, which allows a shaking effect.
2484
ld hl, vBGMap0
2485
call BattleAnimCopyTileMapToVRAM
2486
2487
; Now that the regular BG is showing the same thing the window was, move the
2488
; window off the screen so that we can modify its contents below.
2489
ld a, SCREEN_HEIGHT_PX
2490
ldh [hWY], a
2491
2492
; Copy wTileMap to VRAM such that the row below the enemy HUD (in wTileMap) is
2493
; lined up with row 0 of the window.
2494
ld hl, vBGMap1 - $20 * 7
2495
call BattleAnimCopyTileMapToVRAM
2496
2497
; Move the window so that the row below the enemy HUD (in BG map 0) lines up
2498
; with the top row of the window on the screen. This makes it so that the window
2499
; covers everything below the enemy HD with a copy that looks just like what
2500
; was there before.
2501
ld a, 7 * 8
2502
ldh [hWY], a
2503
2504
; Write OAM entries so that the copy of the back pic from the top of this
2505
; function shows up on screen. We need this because the back pic's Y coordinates
2506
; range overlaps with that of the enemy HUD and we don't want to shake the top
2507
; of the back pic when we shake the enemy HUD. The OAM copy won't be affected
2508
; by SCX.
2509
call ShakeEnemyHUD_WritePlayerMonPicOAM
2510
2511
ld hl, vBGMap0
2512
call BattleAnimCopyTileMapToVRAM
2513
2514
; Remove the back pic from the BG map.
2515
call AnimationHideMonPic
2516
call Delay3
2517
2518
; Use SCX to shake the regular BG. The window and the back pic OAM copy are
2519
; not affected.
2520
lb de, 2, 8
2521
call ShakeEnemyHUD_ShakeBG
2522
2523
; Restore the original graphics.
2524
call AnimationShowMonPic
2525
call ClearSprites
2526
ld a, SCREEN_HEIGHT_PX
2527
ldh [hWY], a
2528
ld hl, vBGMap1
2529
call BattleAnimCopyTileMapToVRAM
2530
xor a
2531
ldh [hWY], a
2532
call SaveScreenTilesToBuffer1
2533
ld hl, vBGMap0
2534
call BattleAnimCopyTileMapToVRAM
2535
call ClearScreen
2536
call Delay3
2537
call LoadScreenTilesFromBuffer1
2538
ld hl, vBGMap1
2539
jp BattleAnimCopyTileMapToVRAM
2540
2541
; b = tile ID list index
2542
; c = base tile ID
2543
CopyTileIDsFromList:
2544
call GetPredefRegisters
2545
ld a, c
2546
ldh [hBaseTileID], a
2547
ld a, b
2548
push hl
2549
call GetTileIDList
2550
pop hl
2551
jp CopyTileIDs
2552
2553
ShakeEnemyHUD_ShakeBG:
2554
ldh a, [hSCX]
2555
ld [wTempSCX], a
2556
.loop
2557
ld a, [wTempSCX]
2558
add d
2559
ldh [hSCX], a
2560
ld c, 2
2561
call DelayFrames
2562
ld a, [wTempSCX]
2563
sub d
2564
ldh [hSCX], a
2565
ld c, 2
2566
call DelayFrames
2567
dec e
2568
jr nz, .loop
2569
ld a, [wTempSCX]
2570
ldh [hSCX], a
2571
ret
2572
2573
BattleAnimCopyTileMapToVRAM:
2574
ld a, h
2575
ldh [hAutoBGTransferDest + 1], a
2576
ld a, l
2577
ldh [hAutoBGTransferDest], a
2578
jp Delay3
2579
2580
TossBallAnimation:
2581
ld a, [wIsInBattle]
2582
cp 2
2583
jr z, .BlockBall ; if in trainer battle, play different animation
2584
ld a, [wPokeBallAnimData]
2585
ld b, a
2586
2587
; upper nybble: how many animations (from PokeBallAnimations) to play
2588
; this will be 4 for successful capture, 6 for breakout
2589
and $F0
2590
swap a
2591
ld c, a
2592
2593
; lower nybble: number of shakes
2594
; store these for later
2595
ld a, b
2596
and $F
2597
ld [wNumShakes], a
2598
2599
ld hl, .PokeBallAnimations
2600
; choose which toss animation to use
2601
ld a, [wCurItem]
2602
cp POKE_BALL
2603
ld b, TOSS_ANIM
2604
jr z, .done
2605
cp GREAT_BALL
2606
ld b, GREATTOSS_ANIM
2607
jr z, .done
2608
ld b, ULTRATOSS_ANIM
2609
.done
2610
ld a, b
2611
.PlayNextAnimation
2612
ld [wAnimationID], a
2613
push bc
2614
push hl
2615
call PlayAnimation
2616
pop hl
2617
ld a, [hli]
2618
pop bc
2619
dec c
2620
jr nz, .PlayNextAnimation
2621
ret
2622
2623
.PokeBallAnimations:
2624
; sequence of animations that make up the Poké Ball toss
2625
db POOF_ANIM, HIDEPIC_ANIM, SHAKE_ANIM, POOF_ANIM, SHOWPIC_ANIM
2626
2627
.BlockBall
2628
ld a, TOSS_ANIM
2629
ld [wAnimationID], a
2630
call PlayAnimation
2631
ld a, SFX_FAINT_THUD
2632
call PlaySound
2633
ld a, BLOCKBALL_ANIM
2634
ld [wAnimationID], a
2635
jp PlayAnimation
2636
2637
PlayApplyingAttackSound:
2638
; play a different sound depending if move is not very effective, neutral, or super-effective
2639
; don't play any sound at all if move is ineffective
2640
call WaitForSoundToFinish
2641
ld a, [wDamageMultipliers]
2642
and $7f
2643
ret z
2644
cp 10
2645
ld a, $20
2646
ld b, $30
2647
ld c, SFX_DAMAGE
2648
jr z, .playSound
2649
ld a, $e0
2650
ld b, $ff
2651
ld c, SFX_SUPER_EFFECTIVE
2652
jr nc, .playSound
2653
ld a, $50
2654
ld b, $1
2655
ld c, SFX_NOT_VERY_EFFECTIVE
2656
.playSound
2657
ld [wFrequencyModifier], a
2658
ld a, b
2659
ld [wTempoModifier], a
2660
ld a, c
2661
jp PlaySound
2662
2663