pokered/engine/battle/animations.asm

2623 lines
50 KiB
NASM
Raw Normal View History

2014-05-22 22:13:20 +00:00
; Draws a "frame block". Frame blocks are blocks of tiles that are put
; together to form frames in battle animations.
2016-06-12 00:24:04 +00:00
DrawFrameBlock:
ld l, c
ld h, b
ld a, [hli]
ld [wNumFBTiles], a
ld a, [wFBDestAddr + 1]
ld e, a
ld a, [wFBDestAddr]
ld d, a
2014-05-22 22:13:20 +00:00
xor a
ld [wFBTileCounter], a ; loop counter
2014-05-22 22:13:20 +00:00
.loop
ld a, [wFBTileCounter]
2014-05-22 22:13:20 +00:00
inc a
ld [wFBTileCounter], a
ld a, [wSubAnimTransform]
2014-05-22 22:13:20 +00:00
dec a
jr z, .flipHorizontalAndVertical ; SUBANIMTYPE_HVFLIP
2014-05-22 22:13:20 +00:00
dec a
jp z, .flipHorizontalTranslateDown ; SUBANIMTYPE_HFLIP
2014-05-22 22:13:20 +00:00
dec a
jr z, .flipBaseCoords ; SUBANIMTYPE_COORDFLIP
2014-05-22 22:13:20 +00:00
.noTransformation
ld a, [wBaseCoordY]
2014-05-22 22:13:20 +00:00
add [hl]
ld [de], a ; store Y
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [wBaseCoordX]
2014-05-22 22:13:20 +00:00
jr .finishCopying
.flipBaseCoords
ld a, [wBaseCoordY]
ld b, a
ld a, 136
2014-05-22 22:13:20 +00:00
sub b ; flip Y base coordinate
add [hl] ; Y offset
ld [de], a ; store Y
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [wBaseCoordX]
ld b, a
ld a, 168
2014-05-22 22:13:20 +00:00
sub b ; flip X base coordinate
.finishCopying ; finish copying values to OAM (when subanimation not transformed)
2014-05-22 22:13:20 +00:00
add [hl] ; X offset
ld [de], a ; store X
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [hli]
add $31 ; base tile ID for battle animations
ld [de], a ; store tile ID
2014-05-22 22:13:20 +00:00
inc de
ld a, [hli]
ld [de], a ; store flags
2014-05-22 22:13:20 +00:00
inc de
jp .nextTile
.flipHorizontalAndVertical
ld a, [wBaseCoordY]
2014-05-22 22:13:20 +00:00
add [hl] ; Y offset
ld b, a
ld a, 136
2014-05-22 22:13:20 +00:00
sub b ; flip Y coordinate
ld [de], a ; store Y
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [wBaseCoordX]
2014-05-22 22:13:20 +00:00
add [hl] ; X offset
ld b, a
ld a, 168
2014-05-22 22:13:20 +00:00
sub b ; flip X coordinate
ld [de], a ; store X
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [hli]
add $31 ; base tile ID for battle animations
ld [de], a ; store tile ID
2014-05-22 22:13:20 +00:00
inc de
; toggle horizontal and vertical flip
ld a, [hli] ; flags
2014-05-22 22:13:20 +00:00
and a
ld b, OAM_VFLIP | OAM_HFLIP
jr z, .storeFlags1
cp OAM_HFLIP
ld b, OAM_VFLIP
jr z, .storeFlags1
cp OAM_VFLIP
ld b, OAM_HFLIP
jr z, .storeFlags1
ld b, 0
2014-05-22 22:13:20 +00:00
.storeFlags1
ld a, b
ld [de], a
2014-05-22 22:13:20 +00:00
inc de
jp .nextTile
.flipHorizontalTranslateDown
ld a, [wBaseCoordY]
2014-05-22 22:13:20 +00:00
add [hl]
add 40 ; translate Y coordinate downwards
ld [de], a ; store Y
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [wBaseCoordX]
2014-05-22 22:13:20 +00:00
add [hl]
ld b, a
ld a, 168
2014-05-22 22:13:20 +00:00
sub b ; flip X coordinate
ld [de], a ; store X
2014-05-22 22:13:20 +00:00
inc hl
inc de
ld a, [hli]
add $31 ; base tile ID for battle animations
ld [de], a ; store tile ID
2014-05-22 22:13:20 +00:00
inc de
ld a, [hli]
bit 5, a ; is horizontal flip enabled?
jr nz, .disableHorizontalFlip
2014-05-22 22:13:20 +00:00
.enableHorizontalFlip
set 5, a
2014-05-22 22:13:20 +00:00
jr .storeFlags2
.disableHorizontalFlip
res 5, a
2014-05-22 22:13:20 +00:00
.storeFlags2
ld [de], a
2014-05-22 22:13:20 +00:00
inc de
.nextTile
ld a, [wFBTileCounter]
ld c, a
ld a, [wNumFBTiles]
2014-05-22 22:13:20 +00:00
cp c
jp nz, .loop ; go back up if there are more tiles to draw
2014-05-22 22:13:20 +00:00
.afterDrawingTiles
ld a, [wFBMode]
cp FRAMEBLOCKMODE_02
2020-11-05 21:55:39 +00:00
jr z, .advanceFrameBlockDestAddr ; skip delay and don't clean OAM buffer
ld a, [wSubAnimFrameDelay]
ld c, a
2014-05-22 22:13:20 +00:00
call DelayFrames
ld a, [wFBMode]
cp FRAMEBLOCKMODE_03
jr z, .advanceFrameBlockDestAddr ; skip cleaning OAM buffer
cp FRAMEBLOCKMODE_04
jr z, .done ; skip cleaning OAM buffer and don't advance the frame block destination address
ld a, [wAnimationID]
cp GROWL
jr z, .resetFrameBlockDestAddr
2014-05-22 22:13:20 +00:00
call AnimationCleanOAM
.resetFrameBlockDestAddr
ld hl, wOAMBuffer ; OAM buffer
ld a, l
ld [wFBDestAddr + 1], a
ld a, h
ld [wFBDestAddr], a ; set destination address to beginning of OAM buffer
2014-05-22 22:13:20 +00:00
ret
.advanceFrameBlockDestAddr
ld a, e
ld [wFBDestAddr + 1], a
ld a, d
ld [wFBDestAddr], a
2014-05-22 22:13:20 +00:00
.done
ret
2016-06-12 00:24:04 +00:00
PlayAnimation:
2014-05-22 22:13:20 +00:00
xor a
ldh [hROMBankTemp], a ; it looks like nothing reads this
ld [wSubAnimTransform], a
ld a, [wAnimationID] ; get animation number
2014-05-22 22:13:20 +00:00
dec a
ld l, a
ld h, 0
add hl, hl
ld de, AttackAnimationPointers ; animation command stream pointers
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
2014-05-22 22:13:20 +00:00
.animationLoop
ld a, [hli]
cp -1
jr z, .AnimationOver
cp FIRST_SE_ID ; is this subanimation or a special effect?
jr c, .playSubanimation
2014-05-22 22:13:20 +00:00
.doSpecialEffect
ld c, a
ld de, SpecialEffectPointers
2014-05-22 22:13:20 +00:00
.searchSpecialEffectTableLoop
ld a, [de]
2014-05-22 22:13:20 +00:00
cp c
jr z, .foundMatch
2014-05-22 22:13:20 +00:00
inc de
inc de
inc de
jr .searchSpecialEffectTableLoop
.foundMatch
ld a, [hli]
cp NO_MOVE - 1 ; is there a sound to play?
jr z, .skipPlayingSound
ld [wAnimSoundID], a ; store sound
2014-05-22 22:13:20 +00:00
push hl
push de
call GetMoveSound
2014-05-22 22:13:20 +00:00
call PlaySound
pop de
pop hl
.skipPlayingSound
push hl
inc de
ld a, [de]
ld l, a
2014-05-22 22:13:20 +00:00
inc de
ld a, [de]
ld h, a
ld de, .nextAnimationCommand
2014-05-22 22:13:20 +00:00
push de
jp hl ; jump to special effect function
2014-05-22 22:13:20 +00:00
.playSubanimation
ld c, a
and %00111111
ld [wSubAnimFrameDelay], a
2014-05-22 22:13:20 +00:00
xor a
sla c
rla
sla c
rla
ld [wWhichBattleAnimTileset], a
ld a, [hli] ; sound
ld [wAnimSoundID], a ; store sound
ld a, [hli] ; subanimation ID
ld c, l
ld b, h
ld l, a
ld h, 0
add hl, hl
ld de, SubanimationPointers
add hl, de
ld a, l
ld [wSubAnimAddrPtr], a
ld a, h
ld [wSubAnimAddrPtr + 1], a
ld l, c
ld h, b
2014-05-22 22:13:20 +00:00
push hl
ldh a, [rOBP0]
2014-05-22 22:13:20 +00:00
push af
ld a, [wAnimPalette]
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
call LoadAnimationTileset
call LoadSubanimation
call PlaySubanimation
pop af
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
.nextAnimationCommand
pop hl
jr .animationLoop
.AnimationOver
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
LoadSubanimation:
ld a, [wSubAnimAddrPtr + 1]
ld h, a
ld a, [wSubAnimAddrPtr]
ld l, a
ld a, [hli]
ld e, a
ld a, [hl]
ld d, a ; de = address of subanimation
ld a, [de]
ld b, a
and %00011111
ld [wSubAnimCounter], a ; number of frame blocks
ld a, b
and %11100000
cp SUBANIMTYPE_ENEMY << 5
jr nz, .isNotType5
2014-05-22 22:13:20 +00:00
.isType5
call GetSubanimationTransform2
jr .saveTransformation
.isNotType5
call GetSubanimationTransform1
.saveTransformation
; place the upper 3 bits of a into bits 0-2 of a before storing
srl a
swap a
ld [wSubAnimTransform], a
cp SUBANIMTYPE_REVERSE
ld hl, 0
jr nz, .storeSubentryAddr
2014-05-22 22:13:20 +00:00
; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
ld a, [wSubAnimCounter]
2014-05-22 22:13:20 +00:00
dec a
ld bc, 3
2014-05-22 22:13:20 +00:00
.loop
add hl, bc
2014-05-22 22:13:20 +00:00
dec a
jr nz, .loop
2014-05-22 22:13:20 +00:00
.storeSubentryAddr
inc de
add hl, de
ld a, l
ld [wSubAnimSubEntryAddr], a
ld a, h
ld [wSubAnimSubEntryAddr + 1], a
2014-05-22 22:13:20 +00:00
ret
; called if the subanimation type is not SUBANIMTYPE_ENEMY
; sets the transform to SUBANIMTYPE_NORMAL if it's the player's turn
2014-05-22 22:13:20 +00:00
; sets the transform to the subanimation type if it's the enemy's turn
2016-06-12 00:24:04 +00:00
GetSubanimationTransform1:
ld b, a
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
ld a, b
2014-05-22 22:13:20 +00:00
ret nz
xor a ; SUBANIMTYPE_NORMAL << 5
2014-05-22 22:13:20 +00:00
ret
; called if the subanimation type is SUBANIMTYPE_ENEMY
; sets the transform to SUBANIMTYPE_HFLIP if it's the player's turn
; sets the transform to SUBANIMTYPE_NORMAL if it's the enemy's turn
2016-06-12 00:24:04 +00:00
GetSubanimationTransform2:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
ld a, SUBANIMTYPE_HFLIP << 5
2014-05-22 22:13:20 +00:00
ret z
xor a ; SUBANIMTYPE_NORMAL << 5
2014-05-22 22:13:20 +00:00
ret
; loads tile patterns for battle animations
2016-06-12 00:24:04 +00:00
LoadAnimationTileset:
ld a, [wWhichBattleAnimTileset]
2014-05-22 22:13:20 +00:00
add a
add a
ld hl, AnimationTilesetPointers
ld e, a
ld d, 0
add hl, de
ld a, [hli]
ld [wTempTilesetNumTiles], a ; number of tiles
ld a, [hli]
ld e, a
ld a, [hl]
ld d, a ; de = address of tileset
2020-07-07 19:09:54 +00:00
ld hl, vSprites tile $31
2014-05-22 22:13:20 +00:00
ld b, BANK(AnimationTileset1) ; ROM bank
ld a, [wTempTilesetNumTiles]
ld c, a ; number of tiles
2014-05-22 22:13:20 +00:00
jp CopyVideoData ; load tileset
anim_tileset: MACRO
db \1
dw \2
db -1 ; padding
ENDM
2014-05-22 22:13:20 +00:00
AnimationTilesetPointers:
; number of tiles, gfx pointer
anim_tileset 79, AnimationTileset1
anim_tileset 79, AnimationTileset2
anim_tileset 64, AnimationTileset1
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationTileset1:
2020-06-27 20:27:30 +00:00
INCBIN "gfx/battle/attack_anim_1.2bpp"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationTileset2:
2020-06-27 20:27:30 +00:00
INCBIN "gfx/battle/attack_anim_2.2bpp"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SlotMachineTiles2:
2014-10-17 08:42:32 +00:00
IF DEF(_RED)
2020-06-27 20:27:30 +00:00
INCBIN "gfx/slots/red_slots_2.2bpp"
2014-05-22 22:13:20 +00:00
ENDC
2014-10-17 08:42:32 +00:00
IF DEF(_BLUE)
2020-06-27 20:27:30 +00:00
INCBIN "gfx/slots/blue_slots_2.2bpp"
2014-05-22 22:13:20 +00:00
ENDC
2020-07-07 19:09:54 +00:00
SlotMachineTiles2End:
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MoveAnimation:
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
push af
call WaitForSoundToFinish
call SetAnimationPalette
ld a, [wAnimationID]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr z, .animationFinished
2014-05-22 22:13:20 +00:00
; if throwing a Poké Ball, skip the regular animation code
cp TOSS_ANIM
2016-06-12 04:30:05 +00:00
jr nz, .moveAnimation
ld de, .animationFinished
2014-05-22 22:13:20 +00:00
push de
jp TossBallAnimation
2016-06-12 04:30:05 +00:00
.moveAnimation
2014-05-22 22:13:20 +00:00
; check if battle animations are disabled in the options
ld a, [wOptions]
bit 7, a
2016-06-12 04:30:05 +00:00
jr nz, .animationsDisabled
2014-05-22 22:13:20 +00:00
call ShareMoveAnimations
call PlayAnimation
jr .next4
2016-06-12 04:30:05 +00:00
.animationsDisabled
ld c, 30
2014-05-22 22:13:20 +00:00
call DelayFrames
.next4
call PlayApplyingAttackAnimation ; shake the screen or flash the pic in and out (to show damage)
2016-06-12 04:30:05 +00:00
.animationFinished
2014-05-22 22:13:20 +00:00
call WaitForSoundToFinish
xor a
ld [wSubAnimSubEntryAddr], a
ld [wUnusedD09B], a
ld [wSubAnimTransform], a
dec a ; NO_MOVE - 1
ld [wAnimSoundID], a
2014-05-22 22:13:20 +00:00
pop af
pop bc
pop de
pop hl
ret
2016-06-12 00:24:04 +00:00
ShareMoveAnimations:
2014-05-22 22:13:20 +00:00
; some moves just reuse animations from status conditions
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
ret z
2020-07-07 01:15:12 +00:00
; opponent's turn
2014-05-22 22:13:20 +00:00
ld a, [wAnimationID]
2014-05-22 22:13:20 +00:00
cp AMNESIA
ld b, CONF_ANIM
2016-06-12 04:30:05 +00:00
jr z, .replaceAnim
2014-05-22 22:13:20 +00:00
cp REST
ld b, SLP_ANIM
2014-05-22 22:13:20 +00:00
ret nz
2016-06-12 04:30:05 +00:00
.replaceAnim
ld a, b
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
PlayApplyingAttackAnimation:
; Generic animation that shows after the move's individual animation
; Different animation depending on whether the move has an additional effect and on whose turn it is
ld a, [wAnimationType]
2014-05-22 22:13:20 +00:00
and a
ret z
dec a
add a
ld c, a
ld b, 0
ld hl, AnimationTypePointerTable
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationTypePointerTable:
dw ShakeScreenVertically ; enemy mon has used a damaging move without a side effect
dw ShakeScreenHorizontallyHeavy ; enemy mon has used a damaging move with a side effect
dw ShakeScreenHorizontallySlow ; enemy mon has used a non-damaging move
dw BlinkEnemyMonSprite ; player mon has used a damaging move without a side effect
dw ShakeScreenHorizontallyLight ; player mon has used a damaging move with a side effect
dw ShakeScreenHorizontallySlow2 ; player mon has used a non-damaging move
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ShakeScreenVertically:
2015-03-31 19:09:43 +00:00
call PlayApplyingAttackSound
2015-07-24 21:39:45 +00:00
ld b, 8
jp AnimationShakeScreenVertically
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ShakeScreenHorizontallyHeavy:
2015-03-31 19:09:43 +00:00
call PlayApplyingAttackSound
2015-07-24 21:39:45 +00:00
ld b, 8
jp AnimationShakeScreenHorizontallyFast
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ShakeScreenHorizontallySlow:
2015-07-24 21:39:45 +00:00
lb bc, 6, 2
jr AnimationShakeScreenHorizontallySlow
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BlinkEnemyMonSprite:
2015-03-31 19:09:43 +00:00
call PlayApplyingAttackSound
2014-05-22 22:13:20 +00:00
jp AnimationBlinkEnemyMon
2016-06-12 00:24:04 +00:00
ShakeScreenHorizontallyLight:
2015-03-31 19:09:43 +00:00
call PlayApplyingAttackSound
2015-07-24 21:39:45 +00:00
ld b, 2
jp AnimationShakeScreenHorizontallyFast
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ShakeScreenHorizontallySlow2:
2015-07-24 21:39:45 +00:00
lb bc, 3, 2
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationShakeScreenHorizontallySlow:
2014-05-22 22:13:20 +00:00
push bc
push bc
2015-07-24 21:39:45 +00:00
.loop1
ldh a, [rWX]
2014-05-22 22:13:20 +00:00
inc a
ldh [rWX], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
dec b
2015-07-24 21:39:45 +00:00
jr nz, .loop1
2014-05-22 22:13:20 +00:00
pop bc
2015-07-24 21:39:45 +00:00
.loop2
ldh a, [rWX]
2014-05-22 22:13:20 +00:00
dec a
ldh [rWX], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
dec b
2015-07-24 21:39:45 +00:00
jr nz, .loop2
2014-05-22 22:13:20 +00:00
pop bc
dec c
jr nz, AnimationShakeScreenHorizontallySlow
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
SetAnimationPalette:
2014-09-13 07:50:56 +00:00
ld a, [wOnSGB]
2014-05-22 22:13:20 +00:00
and a
ld a, $e4
2015-07-24 21:39:45 +00:00
jr z, .notSGB
2014-05-22 22:13:20 +00:00
ld a, $f0
2015-07-24 21:39:45 +00:00
ld [wAnimPalette], a
2014-05-22 22:13:20 +00:00
ld b, $e4
2015-08-31 02:38:41 +00:00
ld a, [wAnimationID]
2015-02-07 10:43:08 +00:00
cp TRADE_BALL_DROP_ANIM
2015-07-24 21:39:45 +00:00
jr c, .next
2015-02-07 10:43:08 +00:00
cp TRADE_BALL_POOF_ANIM + 1
2015-07-24 21:39:45 +00:00
jr nc, .next
2014-05-22 22:13:20 +00:00
ld b, $f0
2015-07-24 21:39:45 +00:00
.next
2014-05-22 22:13:20 +00:00
ld a, b
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
ld a, $6c
ldh [rOBP1], a
2014-05-22 22:13:20 +00:00
ret
2015-07-24 21:39:45 +00:00
.notSGB
2014-05-22 22:13:20 +00:00
ld a, $e4
2015-07-24 21:39:45 +00:00
ld [wAnimPalette], a
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
ld a, $6c
ldh [rOBP1], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
PlaySubanimation:
ld a, [wAnimSoundID]
cp NO_MOVE - 1
jr z, .skipPlayingSound
call GetMoveSound
call PlaySound
2014-05-22 22:13:20 +00:00
.skipPlayingSound
ld hl, wOAMBuffer ; base address of OAM buffer
ld a, l
ld [wFBDestAddr + 1], a
ld a, h
ld [wFBDestAddr], a
ld a, [wSubAnimSubEntryAddr + 1]
ld h, a
ld a, [wSubAnimSubEntryAddr]
ld l, a
2014-05-22 22:13:20 +00:00
.loop
push hl
ld c, [hl] ; frame block ID
ld b, 0
ld hl, FrameBlockPointers
add hl, bc
add hl, bc
ld a, [hli]
ld c, a
ld a, [hli]
ld b, a
2014-05-22 22:13:20 +00:00
pop hl
inc hl
push hl
ld e, [hl] ; base coordinate ID
ld d, 0
ld hl, FrameBlockBaseCoords ; base coordinate table
add hl, de
add hl, de
ld a, [hli]
ld [wBaseCoordY], a
ld a, [hl]
ld [wBaseCoordX], a
2014-05-22 22:13:20 +00:00
pop hl
inc hl
ld a, [hl] ; frame block mode
ld [wFBMode], a
2014-05-22 22:13:20 +00:00
call DrawFrameBlock
call DoSpecialEffectByAnimationId ; run animation-specific function (if there is one)
ld a, [wSubAnimCounter]
2014-05-22 22:13:20 +00:00
dec a
ld [wSubAnimCounter], a
2014-05-22 22:13:20 +00:00
ret z
ld a, [wSubAnimSubEntryAddr + 1]
ld h, a
ld a, [wSubAnimSubEntryAddr]
ld l, a
ld a, [wSubAnimTransform]
cp SUBANIMTYPE_REVERSE
ld bc, 3
jr nz, .nextSubanimationSubentry
ld bc, -3
2014-05-22 22:13:20 +00:00
.nextSubanimationSubentry
add hl, bc
ld a, h
ld [wSubAnimSubEntryAddr + 1], a
ld a, l
ld [wSubAnimSubEntryAddr], a
2014-05-22 22:13:20 +00:00
jp .loop
2016-06-12 00:24:04 +00:00
AnimationCleanOAM:
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
push af
call DelayFrame
2014-05-23 22:34:35 +00:00
call ClearSprites
2014-05-22 22:13:20 +00:00
pop af
pop bc
pop de
pop hl
ret
; this runs after each frame block is drawn in a subanimation
; it runs a particular special effect based on the animation ID
2016-06-12 00:24:04 +00:00
DoSpecialEffectByAnimationId:
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
ld a, [wAnimationID]
ld hl, AnimationIdSpecialEffects
ld de, 3
2014-05-22 22:13:20 +00:00
call IsInArray
jr nc, .done
2014-05-22 22:13:20 +00:00
inc hl
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .done
2014-05-22 22:13:20 +00:00
push de
jp hl
2014-05-22 22:13:20 +00:00
.done
pop bc
pop de
pop hl
ret
INCLUDE "data/battle_anims/special_effects.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
DoBallTossSpecialEffects:
ld a, [wcf91]
cp 3 ; is it a Master Ball or Ultra Ball?
jr nc, .skipFlashingEffect
2014-05-22 22:13:20 +00:00
.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
ldh a, [rOBP0]
xor %00111100 ; complement colors 1 and 2
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
.skipFlashingEffect
ld a, [wSubAnimCounter]
cp 11 ; is it the beginning of the subanimation?
jr nz, .skipPlayingSound
2014-05-22 22:13:20 +00:00
; if it is the beginning of the subanimation, play a sound
ld a, SFX_BALL_TOSS
call PlaySound
2014-05-22 22:13:20 +00:00
.skipPlayingSound
ld a, [wIsInBattle]
cp 02 ; is it a trainer battle?
jr z, .isTrainerBattle
ld a, [wd11e]
cp $10 ; is the enemy pokemon the Ghost Marowak?
2014-05-22 22:13:20 +00:00
ret nz
; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
ld a, [wSubAnimCounter]
cp 3
jr z, .moveGhostMarowakLeft
cp 2
jr z, .moveGhostMarowakLeft
cp 1
2014-05-22 22:13:20 +00:00
ret nz
.moveGhostMarowakLeft
hlcoord 17, 0
ld de, 20
2015-07-24 21:39:45 +00:00
lb bc, 7, 7
2014-05-22 22:13:20 +00:00
.loop
push hl
push bc
2015-07-24 21:39:45 +00:00
call AnimCopyRowRight ; move row of tiles left
2014-05-22 22:13:20 +00:00
pop bc
pop hl
add hl, de
2014-05-22 22:13:20 +00:00
dec b
jr nz, .loop
ld a, %00001000
ldh [rNR10], a ; Channel 1 sweep register
2014-05-22 22:13:20 +00:00
ret
.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
ld a, [wSubAnimCounter]
cp 3
2014-05-22 22:13:20 +00:00
ret nz
dec a
ld [wSubAnimCounter], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
DoBallShakeSpecialEffects:
ld a, [wSubAnimCounter]
cp 4 ; is it the beginning of a shake?
jr nz, .skipPlayingSound
2014-05-22 22:13:20 +00:00
; if it is the beginning of a shake, play a sound and wait 2/3 of a second
ld a, SFX_TINK
call PlaySound
ld c, 40
2014-05-22 22:13:20 +00:00
call DelayFrames
.skipPlayingSound
ld a, [wSubAnimCounter]
2014-05-22 22:13:20 +00:00
dec a
ret nz
; if it's the end of the ball shaking subanimation, check if more shakes are left and restart the subanimation
ld a, [wNumShakes] ; number of shakes
2014-05-22 22:13:20 +00:00
dec a ; decrement number of shakes
ld [wNumShakes], a
2014-05-22 22:13:20 +00:00
ret z
; if there are shakes left, restart the subanimation
ld a, [wSubAnimSubEntryAddr]
ld l, a
ld a, [wSubAnimSubEntryAddr + 1]
ld h, a
ld de, -(4 * 3) ; 4 subentries and 3 bytes per subentry
add hl, de
ld a, l
ld [wSubAnimSubEntryAddr], a
ld a, h
ld [wSubAnimSubEntryAddr + 1], a
ld a, 5 ; number of subentries in the ball shaking subanimation plus one
ld [wSubAnimCounter], a
2014-05-22 22:13:20 +00:00
ret
; plays a sound after the second frame of the poof animation
2016-06-12 00:24:04 +00:00
DoPoofSpecialEffects:
ld a, [wSubAnimCounter]
cp 5
2014-05-22 22:13:20 +00:00
ret nz
ld a, SFX_BALL_POOF
2014-05-22 22:13:20 +00:00
jp PlaySound
2016-06-12 00:24:04 +00:00
DoRockSlideSpecialEffects:
ld a, [wSubAnimCounter]
cp 12
2014-05-22 22:13:20 +00:00
ret nc
cp 8
jr nc, .shakeScreen
cp 1
jp z, AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
2014-05-22 22:13:20 +00:00
ret
2017-06-24 20:01:43 +00:00
; if the subanimation counter is between 8 and 11, shake the screen horizontally and vertically
2014-05-22 22:13:20 +00:00
.shakeScreen
ld b, 1
2015-07-12 23:24:03 +00:00
predef PredefShakeScreenHorizontally ; shake horizontally
ld b, 1
2015-07-12 23:24:03 +00:00
predef_jump PredefShakeScreenVertically ; shake vertically
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FlashScreenEveryEightFrameBlocks:
ld a, [wSubAnimCounter]
and 7 ; is the subanimation counter exactly 8?
call z, AnimationFlashScreen ; if so, flash the screen
2014-05-22 22:13:20 +00:00
ret
; flashes the screen if the subanimation counter is divisible by 4
2016-06-12 00:24:04 +00:00
FlashScreenEveryFourFrameBlocks:
ld a, [wSubAnimCounter]
and 3
call z, AnimationFlashScreen
2014-05-22 22:13:20 +00:00
ret
; used for Explosion and Selfdestruct
2016-06-12 00:24:04 +00:00
DoExplodeSpecialEffects:
ld a, [wSubAnimCounter]
cp 1 ; is it the end of the subanimation?
jr nz, FlashScreenEveryFourFrameBlocks
2014-05-22 22:13:20 +00:00
; if it's the end of the subanimation, make the attacking pokemon disappear
hlcoord 1, 5
2014-05-22 22:13:20 +00:00
jp AnimationHideMonPic ; make pokemon disappear
; flashes the screen when subanimation counter is 1 modulo 4
2016-06-12 00:24:04 +00:00
DoBlizzardSpecialEffects:
ld a, [wSubAnimCounter]
cp 13
jp z, AnimationFlashScreen
cp 9
jp z, AnimationFlashScreen
cp 5
jp z, AnimationFlashScreen
cp 1
jp z, AnimationFlashScreen
2014-05-22 22:13:20 +00:00
ret
; flashes the screen at 3 points in the subanimation
; unused
2016-06-12 00:24:04 +00:00
FlashScreenUnused:
ld a, [wSubAnimCounter]
cp 14
jp z, AnimationFlashScreen
cp 9
jp z, AnimationFlashScreen
cp 2
jp z, AnimationFlashScreen
2014-05-22 22:13:20 +00:00
ret
; function to make the pokemon disappear at the beginning of the animation
2016-06-12 00:24:04 +00:00
TradeHidePokemon:
ld a, [wSubAnimCounter]
cp 6
2014-05-22 22:13:20 +00:00
ret nz
ld a, 2 * SCREEN_WIDTH + 7
2015-07-24 21:39:45 +00:00
jp ClearMonPicFromTileMap ; make pokemon disappear
2014-05-22 22:13:20 +00:00
; function to make a shaking pokeball jump up at the end of the animation
2016-06-12 00:24:04 +00:00
TradeShakePokeball:
ld a, [wSubAnimCounter]
cp 1
2014-05-22 22:13:20 +00:00
ret nz
; if it's the end of the animation, make the ball jump up
ld de, BallMoveDistances1
2014-05-22 22:13:20 +00:00
.loop
ld hl, wOAMBuffer ; OAM buffer
ld bc, 4
2014-05-22 22:13:20 +00:00
.innerLoop
ld a, [de]
cp $ff
jr z, .done
2014-05-22 22:13:20 +00:00
add [hl] ; add to Y value of OAM entry
ld [hl], a
add hl, bc
ld a, l
cp 4 * 4 ; there are 4 entries, each 4 bytes
jr nz, .innerLoop
2014-05-22 22:13:20 +00:00
inc de
push bc
call Delay3
pop bc
jr .loop
.done
call AnimationCleanOAM
ld a, SFX_TRADE_MACHINE
jp PlaySound
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BallMoveDistances1:
db -12, -12, -8
db -1 ; end
2014-05-22 22:13:20 +00:00
; function to make the pokeball jump up
TradeJumpPokeball:
ld de, BallMoveDistances2
2014-05-22 22:13:20 +00:00
.loop
ld hl, wOAMBuffer ; OAM buffer
ld bc, 4
2014-05-22 22:13:20 +00:00
.innerLoop
ld a, [de]
cp $ff
jp z, ClearScreen
2014-05-22 22:13:20 +00:00
add [hl]
ld [hl], a
add hl, bc
ld a, l
cp 4 * 4 ; there are 4 entries, each 4 bytes
jr nz, .innerLoop
2014-05-22 22:13:20 +00:00
inc de
push de
ld a, [de]
cp 12
jr z, .playSound
cp $ff
jr nz, .skipPlayingSound
2014-05-22 22:13:20 +00:00
.playSound ; play sound if next move distance is 12 or this is the last one
ld a, SFX_BATTLE_18
2014-05-22 22:13:20 +00:00
call PlaySound
.skipPlayingSound
push bc
ld c, 5
2014-05-22 22:13:20 +00:00
call DelayFrames
pop bc
ldh a, [hSCX] ; background scroll X
sub 8 ; scroll to the left
ldh [hSCX], a
2014-05-22 22:13:20 +00:00
pop de
jr .loop
2016-06-12 00:24:04 +00:00
BallMoveDistances2:
db 11, 12, -12, -7, 7, 12, -8, 8
db -1 ; end
2014-05-22 22:13:20 +00:00
; this function copies the current musical note graphic
; so that there are two musical notes flying towards the defending pokemon
2016-06-12 00:24:04 +00:00
DoGrowlSpecialEffects:
ld hl, wOAMBuffer ; OAM buffer
ld de, wOAMBuffer + $10
ld bc, $10
2014-05-22 22:13:20 +00:00
call CopyData ; copy the musical note graphic
ld a, [wSubAnimCounter]
2014-05-22 22:13:20 +00:00
dec a
call z, AnimationCleanOAM ; clean up at the end of the subanimation
2014-05-22 22:13:20 +00:00
ret
; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
2016-06-12 00:24:04 +00:00
TailWhipAnimationUnused:
ld a, 1
ld [wSubAnimCounter], a
ld c, 20
2014-05-22 22:13:20 +00:00
jp DelayFrames
INCLUDE "data/battle_anims/special_effect_pointers.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationDelay10:
ld c, 10
2014-05-22 22:13:20 +00:00
jp DelayFrames
; calls a function with the turn flipped from player to enemy or vice versa
; input - hl - address of function to call
2016-06-12 00:24:04 +00:00
CallWithTurnFlipped:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
push af
xor 1
ldh [hWhoseTurn], a
ld de, .returnAddress
2014-05-22 22:13:20 +00:00
push de
jp hl
2014-05-22 22:13:20 +00:00
.returnAddress
pop af
ldh [hWhoseTurn], a
2014-05-22 22:13:20 +00:00
ret
; flashes the screen for an extended period (48 frames)
2016-06-12 00:24:04 +00:00
AnimationFlashScreenLong:
ld a, 3 ; cycle through the palettes 3 times
ld [wFlashScreenLongCounter], a
ld a, [wOnSGB] ; running on SGB?
2014-05-22 22:13:20 +00:00
and a
ld hl, FlashScreenLongMonochrome
jr z, .loop
ld hl, FlashScreenLongSGB
2014-05-22 22:13:20 +00:00
.loop
push hl
.innerLoop
ld a, [hli]
cp $01 ; is it the end of the palettes?
jr z, .endOfPalettes
ldh [rBGP], a
2014-05-22 22:13:20 +00:00
call FlashScreenLongDelay
jr .innerLoop
.endOfPalettes
ld a, [wFlashScreenLongCounter]
2014-05-22 22:13:20 +00:00
dec a
ld [wFlashScreenLongCounter], a
2014-05-22 22:13:20 +00:00
pop hl
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
; BG palettes
2016-06-12 00:24:04 +00:00
FlashScreenLongMonochrome:
2014-05-22 22:13:20 +00:00
db %11111001 ; 3, 3, 2, 1
db %11111110 ; 3, 3, 3, 2
db %11111111 ; 3, 3, 3, 3
db %11111110 ; 3, 3, 3, 2
db %11111001 ; 3, 3, 2, 1
db %11100100 ; 3, 2, 1, 0
db %10010000 ; 2, 1, 0, 0
db %01000000 ; 1, 0, 0, 0
db %00000000 ; 0, 0, 0, 0
db %01000000 ; 1, 0, 0, 0
db %10010000 ; 2, 1, 0, 0
db %11100100 ; 3, 2, 1, 0
db $01 ; terminator
; BG palettes
2016-06-12 00:24:04 +00:00
FlashScreenLongSGB:
2014-05-22 22:13:20 +00:00
db %11111000 ; 3, 3, 2, 0
db %11111100 ; 3, 3, 3, 0
db %11111111 ; 3, 3, 3, 3
db %11111100 ; 3, 3, 3, 0
db %11111000 ; 3, 3, 2, 0
db %11100100 ; 3, 2, 1, 0
db %10010000 ; 2, 1, 0, 0
db %01000000 ; 1, 0, 0, 0
db %00000000 ; 0, 0, 0, 0
db %01000000 ; 1, 0, 0, 0
db %10010000 ; 2, 1, 0, 0
db %11100100 ; 3, 2, 1, 0
db $01 ; terminator
; causes a delay of 2 frames for the first cycle
; causes a delay of 1 frame for the second and third cycles
2016-06-12 00:24:04 +00:00
FlashScreenLongDelay:
ld a, [wFlashScreenLongCounter]
cp 4 ; never true since [wFlashScreenLongCounter] starts at 3
ld c, 4
jr z, .delayFrames
cp 3
ld c, 2
jr z, .delayFrames
cp 2 ; nothing is done with this
ld c, 1
2014-05-22 22:13:20 +00:00
.delayFrames
jp DelayFrames
2016-06-12 00:24:04 +00:00
AnimationFlashScreen:
ldh a, [rBGP]
2014-05-22 22:13:20 +00:00
push af ; save initial palette
ld a, %00011011 ; 0, 1, 2, 3 (inverted colors)
ldh [rBGP], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
xor a ; white out background
ldh [rBGP], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
pop af
ldh [rBGP], a ; restore initial palette
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationDarkScreenPalette:
2014-05-22 22:13:20 +00:00
; Changes the screen's palette to a dark palette.
2015-07-24 21:39:45 +00:00
lb bc, $6f, $6f
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationDarkenMonPalette:
2014-05-22 22:13:20 +00:00
; Darkens the mon sprite's palette.
2015-07-24 21:39:45 +00:00
lb bc, $f9, $f4
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationUnusedPalette1:
2015-07-24 21:39:45 +00:00
lb bc, $fe, $f8
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationUnusedPalette2:
2015-07-24 21:39:45 +00:00
lb bc, $ff, $ff
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationResetScreenPalette:
2014-05-22 22:13:20 +00:00
; Restores the screen's palette to the normal palette.
2015-07-24 21:39:45 +00:00
lb bc, $e4, $e4
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationUnusedPalette3:
2015-07-24 21:39:45 +00:00
lb bc, $00, $00
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationLightScreenPalette:
2014-05-22 22:13:20 +00:00
; Changes the screen to use a palette with light colors.
2015-07-24 21:39:45 +00:00
lb bc, $90, $90
jr SetAnimationBGPalette
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationUnusedPalette4:
2015-07-24 21:39:45 +00:00
lb bc, $40, $40
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SetAnimationBGPalette:
2014-09-13 07:50:56 +00:00
ld a, [wOnSGB]
2014-05-22 22:13:20 +00:00
and a
ld a, b
2015-07-24 21:39:45 +00:00
jr z, .next
2014-05-22 22:13:20 +00:00
ld a, c
2015-07-24 21:39:45 +00:00
.next
ldh [rBGP], a
2014-05-22 22:13:20 +00:00
ret
ld b, $5
2016-06-12 00:24:04 +00:00
AnimationShakeScreenVertically:
2015-07-12 23:24:03 +00:00
predef_jump PredefShakeScreenVertically
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationShakeScreen:
2014-05-22 22:13:20 +00:00
; Shakes the screen for a while. Used in Earthquake/Fissure/etc. animations.
ld b, $8
2016-06-12 00:24:04 +00:00
AnimationShakeScreenHorizontallyFast:
2015-07-12 23:24:03 +00:00
predef_jump PredefShakeScreenHorizontally
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationWaterDropletsEverywhere:
2014-05-22 22:13:20 +00:00
; Draws water droplets all over the screen and makes them
; scroll. It's hard to describe, but it's the main animation
; in Surf/Mist/Toxic.
xor a
2015-07-24 21:39:45 +00:00
ld [wWhichBattleAnimTileset], a
2014-05-22 22:13:20 +00:00
call LoadAnimationTileset
2015-07-24 21:39:45 +00:00
ld d, 32
ld a, -16
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2014-05-22 22:13:20 +00:00
ld a, $71
2015-07-24 21:39:45 +00:00
ld [wDropletTile], a
.loop
ld a, 16
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2015-07-24 21:39:45 +00:00
ld a, 0
ld [wUnusedD08A], a
call _AnimationWaterDroplets
2015-07-24 21:39:45 +00:00
ld a, 24
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2015-07-24 21:39:45 +00:00
ld a, 32
ld [wUnusedD08A], a
call _AnimationWaterDroplets
2014-05-22 22:13:20 +00:00
dec d
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
_AnimationWaterDroplets:
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
.loop
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordY]
2015-07-24 21:39:45 +00:00
ld [hli], a ; Y
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordX]
2015-07-24 21:39:45 +00:00
add 27
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2015-07-24 21:39:45 +00:00
ld [hli], a ; X
ld a, [wDropletTile]
ld [hli], a ; tile
2014-05-22 22:13:20 +00:00
xor a
2015-07-24 21:39:45 +00:00
ld [hli], a ; attribute
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordX]
2015-07-24 21:39:45 +00:00
cp 144
jr c, .loop
sub 168
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
ld a, [wBaseCoordY]
2015-07-24 21:39:45 +00:00
add 16
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2015-07-24 21:39:45 +00:00
cp 112
jr c, .loop
2014-05-22 22:13:20 +00:00
call AnimationCleanOAM
jp DelayFrame
2016-06-12 00:24:04 +00:00
AnimationSlideMonUp:
2014-05-22 22:13:20 +00:00
; Slides the mon's sprite upwards.
2015-07-24 21:39:45 +00:00
ld c, 7
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
hlcoord 1, 6
decoord 1, 5
2014-05-22 22:13:20 +00:00
ld a, $30
2015-07-24 21:39:45 +00:00
jr z, .next
hlcoord 12, 1
decoord 12, 0
2014-05-22 22:13:20 +00:00
ld a, $ff
2015-07-24 21:39:45 +00:00
.next
ld [wSlideMonUpBottomRowLeftTile], a
jp _AnimationSlideMonUp
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationSlideMonDown:
2014-05-22 22:13:20 +00:00
; Slides the mon's sprite down out of the screen.
2020-07-17 17:44:28 +00:00
xor a ; TILEMAP_MON_PIC
2015-02-07 10:43:08 +00:00
call GetTileIDList
2015-07-24 21:39:45 +00:00
.loop
2015-02-07 10:43:08 +00:00
call GetMonSpriteTileMapPointerFromRowCount
2014-05-22 22:13:20 +00:00
push bc
push de
call CopyPicTiles
2014-05-22 22:13:20 +00:00
call Delay3
call AnimationHideMonPic
pop de
pop bc
dec b
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationSlideMonOff:
2015-07-24 21:39:45 +00:00
; Slides the mon's sprite off the screen horizontally.
ld e, 8
ld a, 3
ld [wSlideMonDelay], a
jp _AnimationSlideMonOff
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationSlideEnemyMonOff:
2015-07-24 21:39:45 +00:00
; Slides the enemy mon off the screen horizontally.
ld hl, AnimationSlideMonOff
2014-05-22 22:13:20 +00:00
jp CallWithTurnFlipped
2016-06-12 00:24:04 +00:00
_AnimationSlideMonUp:
2014-05-22 22:13:20 +00:00
push de
push hl
push bc
2015-07-24 21:39:45 +00:00
; In each iteration, slide up all rows but the top one (which is overwritten).
ld b, 6
.slideLoop
2014-05-22 22:13:20 +00:00
push bc
push de
push hl
2015-07-24 21:39:45 +00:00
ld bc, 7
2014-05-22 22:13:20 +00:00
call CopyData
2015-07-24 21:39:45 +00:00
; Note that de and hl are popped in the same order they are pushed, swapping
; their values. When CopyData is called, hl points to a tile 1 row below
; the one de points to. To maintain this relationship, after swapping, we add 2
; rows to hl so that it is 1 row below again.
2014-05-22 22:13:20 +00:00
pop de
pop hl
2015-07-12 22:51:04 +00:00
ld bc, SCREEN_WIDTH * 2
2014-05-22 22:13:20 +00:00
add hl, bc
pop bc
dec b
2015-07-24 21:39:45 +00:00
jr nz, .slideLoop
; Fill in the bottom row of the mon pic with the next row's tile IDs.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
hlcoord 1, 11
2015-07-24 21:39:45 +00:00
jr z, .next
hlcoord 12, 6
2015-07-24 21:39:45 +00:00
.next
ld a, [wSlideMonUpBottomRowLeftTile]
2014-05-22 22:13:20 +00:00
inc a
2015-07-24 21:39:45 +00:00
ld [wSlideMonUpBottomRowLeftTile], a
ld c, 7
.fillBottomRowLoop
2014-05-22 22:13:20 +00:00
ld [hli], a
2015-07-24 21:39:45 +00:00
add 7
2014-05-22 22:13:20 +00:00
dec c
2015-07-24 21:39:45 +00:00
jr nz, .fillBottomRowLoop
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
pop bc
pop hl
pop de
dec c
jr nz, _AnimationSlideMonUp
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
ShakeEnemyHUD_WritePlayerMonPicOAM:
2015-07-24 21:39:45 +00:00
; Writes the OAM entries for a copy of the player mon's pic in OAM.
; The top 5 rows are reproduced in OAM, although only 2 are actually needed.
2014-05-22 22:13:20 +00:00
ld a, $10
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2014-05-22 22:13:20 +00:00
ld a, $30
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
ld d, 0
ld c, 7
.loop
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordY]
2014-05-22 22:13:20 +00:00
ld e, a
2015-07-24 21:39:45 +00:00
ld b, 5
.innerLoop
call BattleAnimWriteOAMEntry
2014-05-22 22:13:20 +00:00
inc d
dec b
2015-07-24 21:39:45 +00:00
jr nz, .innerLoop
2014-05-22 22:13:20 +00:00
dec c
ret z
inc d
inc d
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordX]
2015-07-24 21:39:45 +00:00
add 8
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2015-07-24 21:39:45 +00:00
jr .loop
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BattleAnimWriteOAMEntry:
2015-07-24 21:39:45 +00:00
; Y coordinate = e (increased by 8 each call, before the write to OAM)
2015-08-31 02:38:41 +00:00
; X coordinate = [wBaseCoordX]
2015-07-24 21:39:45 +00:00
; tile = d
; attributes = 0
2014-05-22 22:13:20 +00:00
ld a, e
2015-07-24 21:39:45 +00:00
add 8
2014-05-22 22:13:20 +00:00
ld e, a
ld [hli], a
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordX]
2014-05-22 22:13:20 +00:00
ld [hli], a
ld a, d
ld [hli], a
xor a
ld [hli], a
ret
2016-06-12 00:24:04 +00:00
AdjustOAMBlockXPos:
2014-05-22 22:13:20 +00:00
ld l, e
ld h, d
2016-06-12 00:24:04 +00:00
AdjustOAMBlockXPos2:
2015-07-24 21:39:45 +00:00
ld de, 4
.loop
2015-07-24 21:39:45 +00:00
ld a, [wCoordAdjustmentAmount]
2014-05-22 22:13:20 +00:00
ld b, a
ld a, [hl]
add b
2015-07-24 21:39:45 +00:00
cp 168
jr c, .skipPuttingEntryOffScreen
2015-07-24 21:39:45 +00:00
; put off-screen if X >= 168
2014-05-22 22:13:20 +00:00
dec hl
2015-07-24 21:39:45 +00:00
ld a, 160
2014-05-22 22:13:20 +00:00
ld [hli], a
.skipPuttingEntryOffScreen
2014-05-22 22:13:20 +00:00
ld [hl], a
add hl, de
dec c
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AdjustOAMBlockYPos:
2014-05-22 22:13:20 +00:00
ld l, e
ld h, d
2016-06-12 00:24:04 +00:00
AdjustOAMBlockYPos2:
2015-07-24 21:39:45 +00:00
ld de, 4
.loop
2015-07-24 21:39:45 +00:00
ld a, [wCoordAdjustmentAmount]
2014-05-22 22:13:20 +00:00
ld b, a
ld a, [hl]
add b
2015-07-24 21:39:45 +00:00
cp 112
jr c, .skipSettingPreviousEntrysAttribute
2014-05-22 22:13:20 +00:00
dec hl
2015-07-24 21:39:45 +00:00
ld a, 160 ; bug, sets previous OAM entry's attribute
2014-05-22 22:13:20 +00:00
ld [hli], a
.skipSettingPreviousEntrysAttribute
2014-05-22 22:13:20 +00:00
ld [hl], a
add hl, de
dec c
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationBlinkEnemyMon:
2014-05-22 22:13:20 +00:00
; Make the enemy mon's sprite blink on and off for a second or two
ld hl, AnimationBlinkMon
2014-05-22 22:13:20 +00:00
jp CallWithTurnFlipped
2016-06-12 00:24:04 +00:00
AnimationBlinkMon:
2014-05-22 22:13:20 +00:00
; Make the mon's sprite blink on and off for a second or two.
push af
2015-07-24 21:39:45 +00:00
ld c, 6
.loop
2014-05-22 22:13:20 +00:00
push bc
call AnimationHideMonPic
ld c, 5
2014-05-22 22:13:20 +00:00
call DelayFrames
call AnimationShowMonPic
ld c, 5
2014-05-22 22:13:20 +00:00
call DelayFrames
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
pop af
ret
2016-06-12 00:24:04 +00:00
AnimationFlashMonPic:
2014-05-22 22:13:20 +00:00
; Flashes the mon's sprite on and off
ld a, [wBattleMonSpecies]
2015-07-24 21:39:45 +00:00
ld [wChangeMonPicPlayerTurnSpecies], a
ld a, [wEnemyMonSpecies]
2015-07-24 21:39:45 +00:00
ld [wChangeMonPicEnemyTurnSpecies], a
jp ChangeMonPic
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationFlashEnemyMonPic:
2014-05-22 22:13:20 +00:00
; Flashes the enemy mon's sprite on and off
ld hl, AnimationFlashMonPic
jp CallWithTurnFlipped
2016-06-12 00:24:04 +00:00
AnimationShowMonPic:
2020-07-17 17:44:28 +00:00
xor a ; TILEMAP_MON_PIC
2015-02-07 10:43:08 +00:00
call GetTileIDList
call GetMonSpriteTileMapPointerFromRowCount
call CopyPicTiles
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
AnimationShowEnemyMonPic:
2017-06-24 20:01:43 +00:00
; Shows the enemy mon's front sprite. Used in animations like Seismic Toss
2014-05-22 22:13:20 +00:00
; to make the mon's sprite reappear after disappears offscreen.
ld hl, AnimationShowMonPic
jp CallWithTurnFlipped
2016-06-12 00:24:04 +00:00
AnimationShakeBackAndForth:
2014-05-22 22:13:20 +00:00
; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
; The mon's sprite disappears after this animation.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
hlcoord 0, 5
decoord 2, 5
2015-07-24 21:39:45 +00:00
jr z, .next
hlcoord 11, 0
decoord 13, 0
2014-05-22 22:13:20 +00:00
2015-07-24 21:39:45 +00:00
.next
2020-07-17 17:44:28 +00:00
xor a ; TILEMAP_MON_PIC
2014-05-22 22:13:20 +00:00
ld c, $10
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
push af
push bc
push de
push hl
push hl
push de
push af
push hl
push hl
2015-02-07 10:43:08 +00:00
call GetTileIDList
2014-05-22 22:13:20 +00:00
pop hl
call CopyPicTiles
2014-05-22 22:13:20 +00:00
call Delay3
pop hl
2015-07-24 21:39:45 +00:00
lb bc, 7, 9
2014-05-22 22:13:20 +00:00
call ClearScreenArea
pop af
2015-02-07 10:43:08 +00:00
call GetTileIDList
2014-05-22 22:13:20 +00:00
pop hl
call CopyPicTiles
2014-05-22 22:13:20 +00:00
call Delay3
pop hl
2015-07-24 21:39:45 +00:00
lb bc, 7, 9
2014-05-22 22:13:20 +00:00
call ClearScreenArea
pop hl
pop de
pop bc
pop af
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationMoveMonHorizontally:
2014-05-22 22:13:20 +00:00
; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
; animations like Tackle/Body Slam.
call AnimationHideMonPic
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
hlcoord 2, 5
2015-07-24 21:39:45 +00:00
jr z, .next
hlcoord 11, 0
2015-07-24 21:39:45 +00:00
.next
2020-07-17 17:44:28 +00:00
xor a ; TILEMAP_MON_PIC
2014-05-22 22:13:20 +00:00
push hl
2015-02-07 10:43:08 +00:00
call GetTileIDList
2014-05-22 22:13:20 +00:00
pop hl
call CopyPicTiles
ld c, 3
2014-05-22 22:13:20 +00:00
jp DelayFrames
2016-06-12 00:24:04 +00:00
AnimationResetMonPosition:
2014-05-22 22:13:20 +00:00
; Resets the mon's sprites to be located at the normal coordinates.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
ld a, 5 * SCREEN_WIDTH + 2
jr z, .next
ld a, 11
.next
call ClearMonPicFromTileMap
2014-05-22 22:13:20 +00:00
jp AnimationShowMonPic
2016-06-12 00:24:04 +00:00
AnimationSpiralBallsInward:
2015-07-24 21:39:45 +00:00
; Creates an effect that looks like energy balls spiralling into the
2014-05-22 22:13:20 +00:00
; player mon's sprite. Used in Focus Energy, for example.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
ld a, -40
ld [wSpiralBallsBaseY], a
ld a, 80
ld [wSpiralBallsBaseX], a
jr .next
.playerTurn
2014-05-22 22:13:20 +00:00
xor a
2015-07-24 21:39:45 +00:00
ld [wSpiralBallsBaseY], a
ld [wSpiralBallsBaseX], a
.next
ld d, $7a ; ball tile
ld c, 3 ; number of balls
2014-05-22 22:13:20 +00:00
xor a
2015-07-24 21:39:45 +00:00
call InitMultipleObjectsOAM
ld hl, SpiralBallAnimationCoordinates
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
push hl
2015-07-24 21:39:45 +00:00
ld c, 3
2014-05-22 22:13:20 +00:00
ld de, wOAMBuffer
2015-07-24 21:39:45 +00:00
.innerLoop
2014-05-22 22:13:20 +00:00
ld a, [hl]
cp $ff
2015-07-24 21:39:45 +00:00
jr z, .done
ld a, [wSpiralBallsBaseY]
2014-05-22 22:13:20 +00:00
add [hl]
2015-07-24 21:39:45 +00:00
ld [de], a ; Y
2014-05-22 22:13:20 +00:00
inc de
inc hl
2015-07-24 21:39:45 +00:00
ld a, [wSpiralBallsBaseX]
2014-05-22 22:13:20 +00:00
add [hl]
2015-07-24 21:39:45 +00:00
ld [de], a ; X
2014-05-22 22:13:20 +00:00
inc hl
inc de
inc de
inc de
dec c
2015-07-24 21:39:45 +00:00
jr nz, .innerLoop
ld c, 5
2014-05-22 22:13:20 +00:00
call DelayFrames
pop hl
inc hl
inc hl
2015-07-24 21:39:45 +00:00
jr .loop
.done
2014-05-22 22:13:20 +00:00
pop hl
call AnimationCleanOAM
jp AnimationFlashScreen
2016-06-12 00:24:04 +00:00
SpiralBallAnimationCoordinates:
2014-05-22 22:13:20 +00:00
; y, x pairs
2015-07-24 21:39:45 +00:00
; This is the sequence of screen coordinates that the spiralling
2014-05-22 22:13:20 +00:00
; balls are positioned at.
db $38, $28
db $40, $18
db $50, $10
db $60, $18
db $68, $28
db $60, $38
db $50, $40
db $40, $38
db $40, $28
db $46, $1E
db $50, $18
db $5B, $1E
db $60, $28
db $5B, $32
db $50, $38
db $46, $32
db $48, $28
db $50, $20
db $58, $28
db $50, $30
db $50, $28
db -1 ; end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationSquishMonPic:
2014-05-22 22:13:20 +00:00
; Squishes the mon's sprite horizontally making it
; disappear. Used by Teleport/Sky Attack animations.
2015-07-24 21:39:45 +00:00
ld c, 4
.loop
2014-05-22 22:13:20 +00:00
push bc
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
hlcoord 16, 0
decoord 14, 0
2015-07-24 21:39:45 +00:00
jr .next
.playerTurn
hlcoord 5, 5
decoord 3, 5
2015-07-24 21:39:45 +00:00
.next
2014-05-22 22:13:20 +00:00
push de
2015-07-24 21:39:45 +00:00
xor a ; left
ld [wSquishMonCurrentDirection], a
call _AnimationSquishMonPic
2014-05-22 22:13:20 +00:00
pop hl
2015-07-24 21:39:45 +00:00
ld a, 1 ; right
ld [wSquishMonCurrentDirection], a
call _AnimationSquishMonPic
2014-05-22 22:13:20 +00:00
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
call AnimationHideMonPic
2015-07-24 21:39:45 +00:00
ld c, 2
2014-05-22 22:13:20 +00:00
jp DelayFrame
2016-06-12 00:24:04 +00:00
_AnimationSquishMonPic:
2015-07-24 21:39:45 +00:00
ld c, 7
.loop
2014-05-22 22:13:20 +00:00
push bc
push hl
2015-07-24 21:39:45 +00:00
ld c, 3
ld a, [wSquishMonCurrentDirection]
cp 0
jr nz, .right
call AnimCopyRowLeft
2014-05-22 22:13:20 +00:00
dec hl
2015-07-24 21:39:45 +00:00
jr .next
.right
call AnimCopyRowRight
2014-05-22 22:13:20 +00:00
inc hl
2015-07-24 21:39:45 +00:00
.next
2015-07-14 07:16:19 +00:00
ld [hl], " "
2014-05-22 22:13:20 +00:00
pop hl
2015-07-14 07:16:19 +00:00
ld de, SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
add hl, de
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
AnimationShootBallsUpward:
2014-05-22 22:13:20 +00:00
; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
; animations.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
lb bc, 0, 16 * 8
jr .next
.playerTurn
lb bc, 6 * 8, 5 * 8
.next
2014-05-22 22:13:20 +00:00
ld a, b
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2014-05-22 22:13:20 +00:00
ld a, c
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2015-07-24 21:39:45 +00:00
lb bc, 5, 1
call _AnimationShootBallsUpward
2014-05-22 22:13:20 +00:00
jp AnimationCleanOAM
2016-06-12 00:24:04 +00:00
_AnimationShootBallsUpward:
2014-05-22 22:13:20 +00:00
push bc
xor a
2015-07-24 21:39:45 +00:00
ld [wWhichBattleAnimTileset], a
2014-05-22 22:13:20 +00:00
call LoadAnimationTileset
pop bc
2015-07-24 21:39:45 +00:00
ld d, $7a ; ball tile
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
push bc
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordY]
2014-05-22 22:13:20 +00:00
ld e, a
2015-07-24 21:39:45 +00:00
.initOAMLoop
call BattleAnimWriteOAMEntry
2014-05-22 22:13:20 +00:00
dec b
2015-07-24 21:39:45 +00:00
jr nz, .initOAMLoop
2014-05-22 22:13:20 +00:00
call DelayFrame
pop bc
ld a, b
2015-07-24 21:39:45 +00:00
ld [wNumShootingBalls], a
.loop
2014-05-22 22:13:20 +00:00
push bc
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
.innerLoop
2015-08-31 02:38:41 +00:00
ld a, [wBaseCoordY]
2015-07-24 21:39:45 +00:00
add 8
2014-05-22 22:13:20 +00:00
ld e, a
ld a, [hl]
2015-07-24 21:39:45 +00:00
cp e ; has the ball reached the top?
jr z, .reachedTop
add -4 ; ball hasn't reached the top. move it up 4 pixels
2014-05-22 22:13:20 +00:00
ld [hl], a
2015-07-24 21:39:45 +00:00
jr .next
.reachedTop
; remove the ball once it has reached the top
ld [hl], 0 ; put it off-screen
ld a, [wNumShootingBalls]
2014-05-22 22:13:20 +00:00
dec a
2015-07-24 21:39:45 +00:00
ld [wNumShootingBalls], a
.next
ld de, 4
add hl, de ; next OAM entry
2014-05-22 22:13:20 +00:00
dec b
2015-07-24 21:39:45 +00:00
jr nz, .innerLoop
2014-05-22 22:13:20 +00:00
call DelayFrames
pop bc
2015-07-24 21:39:45 +00:00
ld a, [wNumShootingBalls]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationShootManyBallsUpward:
2014-05-22 22:13:20 +00:00
; Shoots several pillars of "energy" balls upward.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
ld a, $50 ; y coordinate for "energy" ball pillar
jr z, .player
ld hl, UpwardBallsAnimXCoordinatesEnemyTurn
ld a, $28 ; y coordinate for "energy" ball pillar
.player
2015-07-24 21:39:45 +00:00
ld [wSavedY], a
2014-05-22 22:13:20 +00:00
.loop
2015-07-24 21:39:45 +00:00
ld a, [wSavedY]
2015-08-31 02:38:41 +00:00
ld [wBaseCoordY], a
2014-05-22 22:13:20 +00:00
ld a, [hli]
cp $ff
jp z, AnimationCleanOAM
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2015-07-24 21:39:45 +00:00
lb bc, 4, 1
2014-05-22 22:13:20 +00:00
push hl
call _AnimationShootBallsUpward
2014-05-22 22:13:20 +00:00
pop hl
jr .loop
2016-06-12 00:24:04 +00:00
UpwardBallsAnimXCoordinatesPlayerTurn:
2014-05-22 22:13:20 +00:00
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
db $10, $40, $28, $18, $38, $30
db -1 ; end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
UpwardBallsAnimXCoordinatesEnemyTurn:
2014-05-22 22:13:20 +00:00
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
db $60, $90, $78, $68, $88, $80
db -1 ; end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationMinimizeMon:
2014-05-22 22:13:20 +00:00
; Changes the mon's sprite to a mini black sprite. Used by the
; Minimize animation.
ld hl, wTempPic
2014-05-22 22:13:20 +00:00
push hl
xor a
2016-06-12 04:30:05 +00:00
ld bc, 7 * 7 * $10
2014-05-22 22:13:20 +00:00
call FillMemory
pop hl
ld de, $194
add hl, de
ld de, MinimizedMonSprite
2016-06-12 04:30:05 +00:00
ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
ld a, [de]
ld [hli], a
ld [hli], a
inc de
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
call CopyTempPicToMonPic
2014-05-22 22:13:20 +00:00
call Delay3
jp AnimationShowMonPic
2016-06-12 00:24:04 +00:00
MinimizedMonSprite:
2020-06-27 20:27:30 +00:00
INCBIN "gfx/battle/minimize.1bpp"
2016-06-12 04:30:05 +00:00
MinimizedMonSpriteEnd:
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationSlideMonDownAndHide:
2014-05-22 22:13:20 +00:00
; Slides the mon's sprite down and disappears. Used in Acid Armor.
2020-07-17 17:44:28 +00:00
ld a, TILEMAP_SLIDE_DOWN_MON_PIC_7X5
ld c, 2
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
push bc
push af
call AnimationHideMonPic
pop af
push af
2015-02-07 10:43:08 +00:00
call GetTileIDList
call GetMonSpriteTileMapPointerFromRowCount
call CopyPicTiles
ld c, 8
2014-05-22 22:13:20 +00:00
call DelayFrames
pop af
inc a
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
call AnimationHideMonPic
ld hl, wTempPic
2020-07-17 17:44:28 +00:00
ld bc, 7 * 7 tiles
2014-05-22 22:13:20 +00:00
xor a
call FillMemory
2015-07-24 21:39:45 +00:00
jp CopyTempPicToMonPic
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
_AnimationSlideMonOff:
2015-07-24 21:39:45 +00:00
; Slides the mon's sprite off the screen horizontally by e tiles and waits
; [wSlideMonDelay] V-blanks each time the pic is slid by one tile.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
hlcoord 12, 0
2015-07-24 21:39:45 +00:00
jr .next
.playerTurn
hlcoord 0, 5
2015-07-24 21:39:45 +00:00
.next
ld d, 8 ; d's value is unused
.slideLoop ; iterates once for each time the pic slides by one tile
2014-05-22 22:13:20 +00:00
push hl
2015-07-24 21:39:45 +00:00
ld b, 7
.rowLoop ; iterates once for each row
ld c, 8
.tileLoop ; iterates once for each tile in the row
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn2
call .EnemyNextTile
jr .next2
.playerTurn2
call .PlayerNextTile
.next2
2014-05-22 22:13:20 +00:00
ld [hli], a
dec c
2015-07-24 21:39:45 +00:00
jr nz, .tileLoop
2014-05-22 22:13:20 +00:00
push de
2015-07-24 21:39:45 +00:00
ld de, SCREEN_WIDTH - 8
2014-05-22 22:13:20 +00:00
add hl, de
pop de
dec b
2015-07-24 21:39:45 +00:00
jr nz, .rowLoop
ld a, [wSlideMonDelay]
2014-05-22 22:13:20 +00:00
ld c, a
call DelayFrames
pop hl
dec d
dec e
2015-07-24 21:39:45 +00:00
jr nz, .slideLoop
2014-05-22 22:13:20 +00:00
ret
2015-07-24 21:39:45 +00:00
; Since mon pic tile numbers go from top to bottom, left to right in order,
; adding the height of the mon pic in tiles to a tile number gives the tile
; number of the tile one column to the right (and thus subtracting the height
; gives the reverse). If the next tile would be past the edge of the pic, the 2
; functions below catch it by checking if the tile number is within the valid
; range and if not, replacing it with a blank tile.
2016-06-12 06:42:19 +00:00
.PlayerNextTile
2014-05-22 22:13:20 +00:00
ld a, [hl]
2015-07-24 21:39:45 +00:00
add 7
; This is a bug. The lower right corner tile of the mon back pic is blanked
; while the mon is sliding off the screen. It should compare with the max tile
; plus one instead.
2014-05-22 22:13:20 +00:00
cp $61
ret c
2015-07-24 21:39:45 +00:00
ld a, " "
2014-05-22 22:13:20 +00:00
ret
2016-06-12 06:42:19 +00:00
.EnemyNextTile
2014-05-22 22:13:20 +00:00
ld a, [hl]
2015-07-24 21:39:45 +00:00
sub 7
; This has the same problem as above, but it has no visible effect because
; the lower right tile is in the first column to slide off the screen.
2014-05-22 22:13:20 +00:00
cp $30
ret c
2015-07-24 21:39:45 +00:00
ld a, " "
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationSlideMonHalfOff:
2015-07-24 21:39:45 +00:00
; Slides the mon's sprite halfway off the screen. It's used in Softboiled.
ld e, 4
ld a, 4
ld [wSlideMonDelay], a
call _AnimationSlideMonOff
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
CopyTempPicToMonPic:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
ld hl, vBackPic ; player turn
jr z, .next
ld hl, vFrontPic ; enemy turn
.next
ld de, wTempPic
2014-05-29 08:31:46 +00:00
ld bc, 7 * 7
2014-05-22 22:13:20 +00:00
jp CopyVideoData
2016-06-12 00:24:04 +00:00
AnimationWavyScreen:
2014-05-22 22:13:20 +00:00
; used in Psywave/Psychic etc.
2014-05-29 08:31:46 +00:00
ld hl, vBGMap0
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
2014-05-22 22:13:20 +00:00
call Delay3
xor a
ldh [hAutoBGTransferEnabled], a
ld a, SCREEN_HEIGHT_PX
ldh [hWY], a
2015-07-24 21:39:45 +00:00
ld d, $80 ; terminator
ld e, SCREEN_HEIGHT_PX - 1
2014-05-22 22:13:20 +00:00
ld c, $ff
ld hl, WavyScreenLineOffsets
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
push hl
2015-07-24 21:39:45 +00:00
.innerLoop
call WavyScreen_SetSCX
ldh a, [rLY]
2015-07-24 21:39:45 +00:00
cp e ; is it the last visible line in the frame?
jr nz, .innerLoop ; keep going if not
2014-05-22 22:13:20 +00:00
pop hl
inc hl
ld a, [hl]
2015-07-24 21:39:45 +00:00
cp d ; have we reached the end?
jr nz, .next
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
.next
2014-05-22 22:13:20 +00:00
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
xor a
ldh [hWY], a
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer2
call ClearScreen
2015-07-24 21:39:45 +00:00
ld a, 1
ldh [hAutoBGTransferEnabled], a
2014-05-22 22:13:20 +00:00
call Delay3
call LoadScreenTilesFromBuffer2
2014-05-29 08:31:46 +00:00
ld hl, vBGMap1
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
WavyScreen_SetSCX:
ldh a, [rSTAT]
2015-07-24 21:39:45 +00:00
and $3 ; is it H-blank?
jr nz, WavyScreen_SetSCX ; wait until it's H-blank
2014-05-22 22:13:20 +00:00
ld a, [hl]
ldh [rSCX], a
2014-05-22 22:13:20 +00:00
inc hl
ld a, [hl]
2015-07-24 21:39:45 +00:00
cp d ; have we reached the end?
2014-05-22 22:13:20 +00:00
ret nz
2015-07-24 21:39:45 +00:00
ld hl, WavyScreenLineOffsets ; go back to the beginning if so
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
WavyScreenLineOffsets:
2014-05-22 22:13:20 +00:00
; Sequence of horizontal line pixel offsets for the wavy screen animation.
; This sequence vaguely resembles a sine wave.
db 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1
db 0, 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, -1
db $80 ; terminator
2016-06-12 00:24:04 +00:00
AnimationSubstitute:
2014-05-22 22:13:20 +00:00
; Changes the pokemon's sprite to the mini sprite
ld hl, wTempPic
2014-05-22 22:13:20 +00:00
xor a
ld bc, $310
2014-05-22 22:13:20 +00:00
call FillMemory
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
ld hl, MonsterSprite tile 0 ; facing down sprite
ld de, wTempPic + $120
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 1
ld de, wTempPic + $120 + $70
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 2
ld de, wTempPic + $120 + $10
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 3
ld de, wTempPic + $120 + $10 + $70
call CopyMonsterSpriteData
2015-07-24 21:39:45 +00:00
jr .next
.playerTurn
ld hl, MonsterSprite tile 4 ; facing up sprite
ld de, wTempPic + $120 + $70
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 5
ld de, wTempPic + $120 + $e0
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 6
ld de, wTempPic + $120 + $80
call CopyMonsterSpriteData
ld hl, MonsterSprite tile 7
ld de, wTempPic + $120 + $f0
call CopyMonsterSpriteData
2015-07-24 21:39:45 +00:00
.next
call CopyTempPicToMonPic
2014-05-22 22:13:20 +00:00
jp AnimationShowMonPic
CopyMonsterSpriteData:
ld bc, 1 tiles
ld a, BANK(MonsterSprite)
2014-05-22 22:13:20 +00:00
jp FarCopyData2
2016-06-12 00:24:04 +00:00
HideSubstituteShowMonAnim:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-12 22:51:04 +00:00
ld hl, wPlayerMonMinimized
2015-08-31 02:38:41 +00:00
ld a, [wPlayerBattleStatus2]
2015-07-12 22:51:04 +00:00
jr z, .next1
ld hl, wEnemyMonMinimized
2015-08-31 02:38:41 +00:00
ld a, [wEnemyBattleStatus2]
2015-07-12 22:51:04 +00:00
.next1
2014-05-22 22:13:20 +00:00
push hl
2015-07-12 22:51:04 +00:00
; if the substitute broke, slide it down, else slide it offscreen horizontally
2017-12-29 23:59:48 +00:00
bit HAS_SUBSTITUTE_UP, a
2015-07-12 22:51:04 +00:00
jr nz, .substituteStillUp
2014-05-22 22:13:20 +00:00
call AnimationSlideMonDown
2015-07-12 22:51:04 +00:00
jr .next2
.substituteStillUp
2015-07-24 21:39:45 +00:00
call AnimationSlideMonOff
2015-07-12 22:51:04 +00:00
.next2
2014-05-22 22:13:20 +00:00
pop hl
ld a, [hl]
and a
jp nz, AnimationMinimizeMon
call AnimationFlashMonPic
jp AnimationShowMonPic
2016-06-12 00:24:04 +00:00
ReshowSubstituteAnim:
2015-07-24 21:39:45 +00:00
call AnimationSlideMonOff
2014-05-22 22:13:20 +00:00
call AnimationSubstitute
jp AnimationShowMonPic
2016-06-12 00:24:04 +00:00
AnimationBoundUpAndDown:
2014-05-22 22:13:20 +00:00
; Bounces the mon's sprite up and down several times. It is used
; by Splash's animation.
2015-07-24 21:39:45 +00:00
ld c, 5
.loop
2014-05-22 22:13:20 +00:00
push bc
call AnimationSlideMonDown
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
jp AnimationShowMonPic
2016-06-12 00:24:04 +00:00
AnimationTransformMon:
2014-05-22 22:13:20 +00:00
; Redraws this mon's sprite as the back/front sprite of the opposing mon.
; Used in Transform.
ld a, [wEnemyMonSpecies]
2015-07-24 21:39:45 +00:00
ld [wChangeMonPicPlayerTurnSpecies], a
ld a, [wBattleMonSpecies]
2015-07-24 21:39:45 +00:00
ld [wChangeMonPicEnemyTurnSpecies], a
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ChangeMonPic:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
ld a, [wChangeMonPicEnemyTurnSpecies]
ld [wcf91], a
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld [wSpriteFlipped], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
hlcoord 12, 0
2014-05-22 22:13:20 +00:00
call LoadFrontSpriteByMonIndex
2015-07-24 21:39:45 +00:00
jr .done
.playerTurn
ld a, [wBattleMonSpecies2]
2014-05-22 22:13:20 +00:00
push af
2015-07-24 21:39:45 +00:00
ld a, [wChangeMonPicPlayerTurnSpecies]
ld [wBattleMonSpecies2], a
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
predef LoadMonBackPic
2020-07-17 17:44:28 +00:00
xor a ; TILEMAP_MON_PIC
2015-02-07 10:43:08 +00:00
call GetTileIDList
call GetMonSpriteTileMapPointerFromRowCount
call CopyPicTiles
2014-05-22 22:13:20 +00:00
pop af
ld [wBattleMonSpecies2], a
2015-07-24 21:39:45 +00:00
.done
2015-08-12 09:16:56 +00:00
ld b, SET_PAL_BATTLE
jp RunPaletteCommand
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationHideEnemyMonPic:
2014-05-22 22:13:20 +00:00
; Hides the enemy mon's sprite
xor a
ldh [hAutoBGTransferEnabled], a
ld hl, AnimationHideMonPic
2014-05-22 22:13:20 +00:00
call CallWithTurnFlipped
ld a, $1
ldh [hAutoBGTransferEnabled], a
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
InitMultipleObjectsOAM:
2015-07-24 21:39:45 +00:00
; Writes c OAM entries with tile d.
; Sets their Y coordinates to sequential multiples of 8, starting from 0.
; Sets their X coordinates to 0.
; Loads animation tileset a.
2014-05-22 22:13:20 +00:00
push bc
push de
2015-07-24 21:39:45 +00:00
ld [wWhichBattleAnimTileset], a
2014-05-22 22:13:20 +00:00
call LoadAnimationTileset
pop de
pop bc
xor a
ld e, a
2015-08-31 02:38:41 +00:00
ld [wBaseCoordX], a
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
.loop
call BattleAnimWriteOAMEntry
2014-05-22 22:13:20 +00:00
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationHideMonPic:
2014-05-22 22:13:20 +00:00
; Hides the mon's sprite.
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 21:39:45 +00:00
jr z, .playerTurn
ld a, 12
jr ClearMonPicFromTileMap
.playerTurn
ld a, 5 * SCREEN_WIDTH + 1
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ClearMonPicFromTileMap:
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
ld e, a
2015-07-24 21:39:45 +00:00
ld d, 0
hlcoord 0, 0
2014-05-22 22:13:20 +00:00
add hl, de
2015-07-24 21:39:45 +00:00
lb bc, 7, 7
2014-05-22 22:13:20 +00:00
call ClearScreenArea
pop bc
pop de
pop hl
ret
2015-02-07 10:43:08 +00:00
; puts the tile map destination address of a mon sprite in hl, given the row count in b
; The usual row count is 7, but it may be smaller when sliding a mon sprite in/out,
; in order to show only a portion of the mon sprite.
2016-06-12 00:24:04 +00:00
GetMonSpriteTileMapPointerFromRowCount:
2014-05-22 22:13:20 +00:00
push de
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-02-07 10:43:08 +00:00
jr nz, .enemyTurn
ld a, 20 * 5 + 1
jr .next
.enemyTurn
ld a, 12
.next
hlcoord 0, 0
2014-05-22 22:13:20 +00:00
ld e, a
2015-02-07 10:43:08 +00:00
ld d, 0
2014-05-22 22:13:20 +00:00
add hl, de
2015-02-07 10:43:08 +00:00
ld a, 7
2014-05-22 22:13:20 +00:00
sub b
and a
2015-02-07 10:43:08 +00:00
jr z, .done
ld de, 20
.loop
2014-05-22 22:13:20 +00:00
add hl, de
dec a
2015-02-07 10:43:08 +00:00
jr nz, .loop
.done
2014-05-22 22:13:20 +00:00
pop de
ret
2015-02-07 10:43:08 +00:00
; Input:
; a = tile ID list index
; Output:
; de = tile ID list pointer
; b = number of rows
; c = number of columns
2016-06-12 00:24:04 +00:00
GetTileIDList:
2015-02-07 10:43:08 +00:00
ld hl, TileIDListPointerTable
2014-05-22 22:13:20 +00:00
ld e, a
2015-02-07 10:43:08 +00:00
ld d, 0
2014-05-22 22:13:20 +00:00
add hl, de
add hl, de
add hl, de
ld a, [hli]
ld e, a
ld a, [hli]
ld d, a
ld a, [hli]
ld b, a
and $f
ld c, a
ld a, b
swap a
and $f
ld b, a
ret
2016-06-12 00:24:04 +00:00
AnimCopyRowLeft:
2015-07-24 21:39:45 +00:00
; copy a row of c tiles 1 tile left
2014-05-22 22:13:20 +00:00
ld a, [hld]
ld [hli], a
inc hl
dec c
2015-07-24 21:39:45 +00:00
jr nz, AnimCopyRowLeft
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimCopyRowRight:
2015-07-24 21:39:45 +00:00
; copy a row of c tiles 1 tile right
2014-05-22 22:13:20 +00:00
ld a, [hli]
ld [hld], a
dec hl
dec c
2015-07-24 21:39:45 +00:00
jr nz, AnimCopyRowRight
2014-05-22 22:13:20 +00:00
ret
; get the sound of the move id in b
2016-06-12 00:24:04 +00:00
GetMoveSoundB:
2014-05-22 22:13:20 +00:00
ld a, b
call GetMoveSound
2014-05-22 22:13:20 +00:00
ld b, a
ret
2016-06-12 00:24:04 +00:00
GetMoveSound:
ld hl, MoveSoundTable
ld e, a
ld d, 0
add hl, de
add hl, de
add hl, de
ld a, [hli]
ld b, a
2014-05-22 22:13:20 +00:00
call IsCryMove
jr nc, .NotCryMove
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
jr nz, .next
ld a, [wBattleMonSpecies] ; get number of current monster
2014-05-22 22:13:20 +00:00
jr .Continue
.next
ld a, [wEnemyMonSpecies]
2014-05-22 22:13:20 +00:00
.Continue
push hl
call GetCryData
ld b, a
2014-05-22 22:13:20 +00:00
pop hl
ld a, [wFrequencyModifier]
2014-05-22 22:13:20 +00:00
add [hl]
ld [wFrequencyModifier], a
2014-05-22 22:13:20 +00:00
inc hl
ld a, [wTempoModifier]
2014-05-22 22:13:20 +00:00
add [hl]
ld [wTempoModifier], a
2014-05-22 22:13:20 +00:00
jr .done
.NotCryMove
ld a, [hli]
ld [wFrequencyModifier], a
ld a, [hli]
ld [wTempoModifier], a
2014-05-22 22:13:20 +00:00
.done
ld a, b
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
IsCryMove:
2014-05-22 22:13:20 +00:00
; set carry if the move animation involves playing a monster cry
ld a, [wAnimationID]
cp GROWL
jr z, .CryMove
cp ROAR
jr z, .CryMove
2014-05-22 22:13:20 +00:00
and a ; clear carry
ret
.CryMove
scf
ret
INCLUDE "data/moves/sfx.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
CopyPicTiles:
ldh a, [hWhoseTurn]
2014-05-22 22:13:20 +00:00
and a
2015-02-07 10:43:08 +00:00
ld a, $31 ; base tile ID of player mon sprite
2015-07-15 06:16:06 +00:00
jr z, .next
2015-02-07 10:43:08 +00:00
; enemy turn
xor a ; base tile ID of enemy mon sprite
2015-07-15 06:16:06 +00:00
.next
ldh [hBaseTileID], a
2015-07-15 06:16:06 +00:00
jr CopyTileIDs_NoBGTransfer
2014-05-22 22:13:20 +00:00
2015-07-15 06:16:06 +00:00
; copy the tiles used when a mon is being sent out of or into a pokeball
2016-06-12 00:24:04 +00:00
CopyDownscaledMonTiles:
call GetPredefRegisters
2015-07-15 06:16:06 +00:00
ld a, [wDownscaledMonSize]
2014-05-22 22:13:20 +00:00
and a
2015-07-15 06:16:06 +00:00
jr nz, .smallerSize
ld de, DownscaledMonTiles_5x5
jr CopyTileIDs_NoBGTransfer
.smallerSize
ld de, DownscaledMonTiles_3x3
; fall through
2016-06-12 00:24:04 +00:00
CopyTileIDs_NoBGTransfer:
2014-05-22 22:13:20 +00:00
xor a
ldh [hAutoBGTransferEnabled], a
2015-07-15 06:16:06 +00:00
; fall through
2014-05-22 22:13:20 +00:00
2015-02-07 10:43:08 +00:00
; b = number of rows
; c = number of columns
2016-06-12 00:24:04 +00:00
CopyTileIDs:
2014-05-22 22:13:20 +00:00
push hl
2015-02-07 10:43:08 +00:00
.rowLoop
2014-05-22 22:13:20 +00:00
push bc
push hl
ldh a, [hBaseTileID]
2014-05-22 22:13:20 +00:00
ld b, a
2015-02-07 10:43:08 +00:00
.columnLoop
2014-05-22 22:13:20 +00:00
ld a, [de]
add b
inc de
ld [hli], a
dec c
2015-02-07 10:43:08 +00:00
jr nz, .columnLoop
2014-05-22 22:13:20 +00:00
pop hl
2015-02-07 10:43:08 +00:00
ld bc, 20
2014-05-22 22:13:20 +00:00
add hl, bc
pop bc
dec b
2015-02-07 10:43:08 +00:00
jr nz, .rowLoop
2014-05-22 22:13:20 +00:00
ld a, $1
ldh [hAutoBGTransferEnabled], a
2014-05-22 22:13:20 +00:00
pop hl
ret
2020-07-17 02:23:03 +00:00
INCLUDE "data/tilemaps.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationLeavesFalling:
2014-05-22 22:13:20 +00:00
; Makes leaves float down from the top of the screen. This is used
; in Razor Leaf's animation.
ldh a, [rOBP0]
2014-05-22 22:13:20 +00:00
push af
2015-07-24 21:39:45 +00:00
ld a, [wAnimPalette]
ldh [rOBP0], a
2015-07-24 21:39:45 +00:00
ld d, $37 ; leaf tile
ld a, 3 ; number of leaves
ld [wNumFallingObjects], a
call AnimationFallingObjects
2014-05-22 22:13:20 +00:00
pop af
ldh [rOBP0], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnimationPetalsFalling:
2014-05-22 22:13:20 +00:00
; Makes lots of petals fall down from the top of the screen. It's used in
; the animation for Petal Dance.
2015-07-24 21:39:45 +00:00
ld d, $71 ; petal tile
ld a, 20 ; number of petals
ld [wNumFallingObjects], a
call AnimationFallingObjects
2014-05-23 22:34:35 +00:00
jp ClearSprites
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationFallingObjects:
2014-05-22 22:13:20 +00:00
ld c, a
2015-07-24 21:39:45 +00:00
ld a, 1
call InitMultipleObjectsOAM
call FallingObjects_InitXCoords
call FallingObjects_InitMovementData
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
ld [hl], 0
.loop
ld hl, wFallingObjectsMovementData
ld de, 0
ld a, [wNumFallingObjects]
2014-05-22 22:13:20 +00:00
ld c, a
2015-07-24 21:39:45 +00:00
.innerLoop
2014-05-22 22:13:20 +00:00
push bc
push hl
push de
ld a, [hl]
2015-07-24 21:39:45 +00:00
ld [wFallingObjectMovementByte], a
call FallingObjects_UpdateMovementByte
call FallingObjects_UpdateOAMEntry
2014-05-22 22:13:20 +00:00
pop de
2015-07-24 21:39:45 +00:00
ld hl, 4
2014-05-22 22:13:20 +00:00
add hl, de
ld e, l
ld d, h
pop hl
2015-07-24 21:39:45 +00:00
ld a, [wFallingObjectMovementByte]
2014-05-22 22:13:20 +00:00
ld [hli], a
pop bc
dec c
2015-07-24 21:39:45 +00:00
jr nz, .innerLoop
2014-05-22 22:13:20 +00:00
call Delay3
ld hl, wOAMBuffer
2015-07-24 21:39:45 +00:00
ld a, [hl] ; Y
cp 104 ; has the top falling object reached 104 yet?
jr nz, .loop ; keep moving the falling objects down until it does
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
FallingObjects_UpdateOAMEntry:
2015-07-24 21:39:45 +00:00
; Increases Y by 2 pixels and adjusts X and X flip based on the falling object's
; movement byte.
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
add hl, de
ld a, [hl]
inc a
inc a
2015-07-24 21:39:45 +00:00
cp 112
jr c, .next
ld a, 160 ; if Y >= 112, put it off-screen
.next
ld [hli], a ; Y
ld a, [wFallingObjectMovementByte]
2014-05-22 22:13:20 +00:00
ld b, a
2015-07-24 21:39:45 +00:00
ld de, FallingObjects_DeltaXs
2014-05-22 22:13:20 +00:00
and $7f
add e
2015-07-24 21:39:45 +00:00
jr nc, .noCarry
2014-05-22 22:13:20 +00:00
inc d
2015-07-24 21:39:45 +00:00
.noCarry
2014-05-22 22:13:20 +00:00
ld e, a
ld a, b
and $80
2015-07-24 21:39:45 +00:00
jr nz, .movingLeft
; moving right
2014-05-22 22:13:20 +00:00
ld a, [de]
add [hl]
2015-07-24 21:39:45 +00:00
ld [hli], a ; X
2014-05-22 22:13:20 +00:00
inc hl
2015-07-24 21:39:45 +00:00
xor a ; no horizontal flip
jr .next2
.movingLeft
2014-05-22 22:13:20 +00:00
ld a, [de]
ld b, a
ld a, [hl]
sub b
2015-07-24 21:39:45 +00:00
ld [hli], a ; X
2014-05-22 22:13:20 +00:00
inc hl
2015-07-24 21:39:45 +00:00
ld a, (1 << OAM_X_FLIP)
.next2
ld [hl], a ; attribute
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
FallingObjects_DeltaXs:
2015-07-24 21:39:45 +00:00
db 0, 1, 3, 5, 7, 9, 11, 13, 15
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FallingObjects_UpdateMovementByte:
2015-07-24 21:39:45 +00:00
ld a, [wFallingObjectMovementByte]
2014-05-22 22:13:20 +00:00
inc a
ld b, a
and $7f
2015-07-24 21:39:45 +00:00
cp 9 ; have we reached the end of the delta-Xs?
2014-05-22 22:13:20 +00:00
ld a, b
2015-07-24 21:39:45 +00:00
jr nz, .next
; We've reached the end of the delta-Xs, so wrap to the start and change
; direction from right to left or vice versa.
2014-05-22 22:13:20 +00:00
and $80
xor $80
2015-07-24 21:39:45 +00:00
.next
ld [wFallingObjectMovementByte], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
FallingObjects_InitXCoords:
ld hl, wOAMBuffer + $01
2015-07-24 21:39:45 +00:00
ld de, FallingObjects_InitialXCoords
ld a, [wNumFallingObjects]
2014-05-22 22:13:20 +00:00
ld c, a
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
ld a, [de]
ld [hli], a
inc hl
inc hl
inc hl
inc de
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
FallingObjects_InitialXCoords:
2020-11-05 21:55:39 +00:00
db $38, $40, $50, $60, $70, $88, $90, $56, $67, $4A, $77, $84, $98, $32, $22, $5C, $6C, $7D, $8E, $99
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FallingObjects_InitMovementData:
2015-07-24 21:39:45 +00:00
ld hl, wFallingObjectsMovementData
ld de, FallingObjects_InitialMovementData
ld a, [wNumFallingObjects]
2014-05-22 22:13:20 +00:00
ld c, a
2015-07-24 21:39:45 +00:00
.loop
2014-05-22 22:13:20 +00:00
ld a, [de]
ld [hli], a
inc de
dec c
2015-07-24 21:39:45 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
FallingObjects_InitialMovementData:
2020-11-05 21:55:39 +00:00
db $00, $84, $06, $81, $02, $88, $01, $83, $05, $89, $09, $80, $07, $87, $03, $82, $04, $85, $08, $86
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AnimationShakeEnemyHUD:
2015-07-24 21:39:45 +00:00
; Shakes the enemy HUD.
; Make a copy of the back pic's tile patterns in sprite tile pattern VRAM.
2014-05-29 08:31:46 +00:00
ld de, vBackPic
ld hl, vSprites
ld bc, 7 * 7
2014-05-22 22:13:20 +00:00
call CopyVideoData
2015-07-24 21:39:45 +00:00
2014-05-22 22:13:20 +00:00
xor a
ldh [hSCX], a
2015-07-24 21:39:45 +00:00
; Copy wTileMap to BG map 0. The regular BG (not the window) is set to use
; map 0 and can be scrolled with SCX, which allows a shaking effect.
2014-05-29 08:31:46 +00:00
ld hl, vBGMap0
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
; Now that the regular BG is showing the same thing the window was, move the
; window off the screen so that we can modify its contents below.
ld a, SCREEN_HEIGHT_PX
ldh [hWY], a
2015-07-24 21:39:45 +00:00
; Copy wTileMap to VRAM such that the row below the enemy HUD (in wTileMap) is
; lined up with row 0 of the window.
ld hl, vBGMap1 - $20 * 7
call BattleAnimCopyTileMapToVRAM
; Move the window so that the row below the enemy HUD (in BG map 0) lines up
; with the top row of the window on the screen. This makes it so that the window
; covers everything below the enemy HD with a copy that looks just like what
; was there before.
ld a, 7 * 8
ldh [hWY], a
2015-07-24 21:39:45 +00:00
; Write OAM entries so that the copy of the back pic from the top of this
; function shows up on screen. We need this because the back pic's Y coordinates
; range overlaps with that of the enemy HUD and we don't want to shake the top
; of the back pic when we shake the enemy HUD. The OAM copy won't be affected
; by SCX.
call ShakeEnemyHUD_WritePlayerMonPicOAM
2014-05-29 08:31:46 +00:00
ld hl, vBGMap0
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
; Remove the back pic from the BG map.
2014-05-22 22:13:20 +00:00
call AnimationHideMonPic
call Delay3
2015-07-24 21:39:45 +00:00
; Use SCX to shake the regular BG. The window and the back pic OAM copy are
; not affected.
lb de, 2, 8
call ShakeEnemyHUD_ShakeBG
; Restore the original graphics.
2014-05-22 22:13:20 +00:00
call AnimationShowMonPic
2014-05-23 22:34:35 +00:00
call ClearSprites
ld a, SCREEN_HEIGHT_PX
ldh [hWY], a
2014-05-29 08:31:46 +00:00
ld hl, vBGMap1
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
2014-05-22 22:13:20 +00:00
xor a
ldh [hWY], a
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-05-29 08:31:46 +00:00
ld hl, vBGMap0
2015-07-24 21:39:45 +00:00
call BattleAnimCopyTileMapToVRAM
2014-05-22 22:13:20 +00:00
call ClearScreen
call Delay3
call LoadScreenTilesFromBuffer1
2014-05-29 08:31:46 +00:00
ld hl, vBGMap1
2015-07-24 21:39:45 +00:00
jp BattleAnimCopyTileMapToVRAM
2014-05-22 22:13:20 +00:00
2015-02-07 10:43:08 +00:00
; b = tile ID list index
; c = base tile ID
2016-06-12 00:24:04 +00:00
CopyTileIDsFromList:
call GetPredefRegisters
2014-05-22 22:13:20 +00:00
ld a, c
ldh [hBaseTileID], a
2014-05-22 22:13:20 +00:00
ld a, b
push hl
2015-02-07 10:43:08 +00:00
call GetTileIDList
2014-05-22 22:13:20 +00:00
pop hl
2015-02-07 10:43:08 +00:00
jp CopyTileIDs
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ShakeEnemyHUD_ShakeBG:
ldh a, [hSCX]
2015-07-24 21:39:45 +00:00
ld [wTempSCX], a
.loop
ld a, [wTempSCX]
2014-05-22 22:13:20 +00:00
add d
ldh [hSCX], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-07-24 21:39:45 +00:00
ld a, [wTempSCX]
2014-05-22 22:13:20 +00:00
sub d
ldh [hSCX], a
ld c, 2
2014-05-22 22:13:20 +00:00
call DelayFrames
dec e
2015-07-24 21:39:45 +00:00
jr nz, .loop
ld a, [wTempSCX]
ldh [hSCX], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
BattleAnimCopyTileMapToVRAM:
2014-05-22 22:13:20 +00:00
ld a, h
ldh [hAutoBGTransferDest + 1], a
2014-05-22 22:13:20 +00:00
ld a, l
ldh [hAutoBGTransferDest], a
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
TossBallAnimation:
ld a, [wIsInBattle]
cp 2
jr z, .BlockBall ; if in trainer battle, play different animation
ld a, [wPokeBallAnimData]
ld b, a
2014-05-22 22:13:20 +00:00
; upper nybble: how many animations (from PokeBallAnimations) to play
; this will be 4 for successful capture, 6 for breakout
and $F0
2014-05-22 22:13:20 +00:00
swap a
ld c, a
2014-05-22 22:13:20 +00:00
; lower nybble: number of shakes
; store these for later
ld a, b
and $F
ld [wNumShakes], a
2014-05-22 22:13:20 +00:00
ld hl, .PokeBallAnimations
2014-05-22 22:13:20 +00:00
; choose which toss animation to use
ld a, [wcf91]
cp POKE_BALL
ld b, TOSS_ANIM
jr z, .done
cp GREAT_BALL
ld b, GREATTOSS_ANIM
jr z, .done
ld b, ULTRATOSS_ANIM
2014-05-22 22:13:20 +00:00
.done
ld a, b
2014-05-22 22:13:20 +00:00
.PlayNextAnimation
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
push bc
push hl
call PlayAnimation
pop hl
ld a, [hli]
2014-05-22 22:13:20 +00:00
pop bc
dec c
jr nz, .PlayNextAnimation
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
.PokeBallAnimations:
2014-05-22 22:13:20 +00:00
; sequence of animations that make up the Poké Ball toss
2020-11-05 21:55:39 +00:00
db POOF_ANIM, HIDEPIC_ANIM, SHAKE_ANIM, POOF_ANIM, SHOWPIC_ANIM
2014-05-22 22:13:20 +00:00
.BlockBall
ld a, TOSS_ANIM
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
call PlayAnimation
ld a, SFX_FAINT_THUD
call PlaySound
ld a, BLOCKBALL_ANIM
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
jp PlayAnimation
2016-06-12 00:24:04 +00:00
PlayApplyingAttackSound:
2015-03-31 19:09:43 +00:00
; play a different sound depending if move is not very effective, neutral, or super-effective
; don't play any sound at all if move is ineffective
2014-05-22 22:13:20 +00:00
call WaitForSoundToFinish
2015-03-31 18:28:42 +00:00
ld a, [wDamageMultipliers]
2014-05-22 22:13:20 +00:00
and $7f
ret z
2015-07-24 21:39:45 +00:00
cp 10
2014-05-22 22:13:20 +00:00
ld a, $20
ld b, $30
2015-07-22 01:58:19 +00:00
ld c, SFX_DAMAGE
2015-07-24 21:39:45 +00:00
jr z, .playSound
2014-05-22 22:13:20 +00:00
ld a, $e0
ld b, $ff
2015-07-22 01:58:19 +00:00
ld c, SFX_SUPER_EFFECTIVE
2015-07-24 21:39:45 +00:00
jr nc, .playSound
2014-05-22 22:13:20 +00:00
ld a, $50
ld b, $1
2015-07-22 01:58:19 +00:00
ld c, SFX_NOT_VERY_EFFECTIVE
2015-07-24 21:39:45 +00:00
.playSound
2015-08-09 05:32:44 +00:00
ld [wFrequencyModifier], a
2014-05-22 22:13:20 +00:00
ld a, b
2015-08-09 05:32:44 +00:00
ld [wTempoModifier], a
2014-05-22 22:13:20 +00:00
ld a, c
jp PlaySound