summaryrefslogtreecommitdiff
path: root/engine/battle
diff options
context:
space:
mode:
Diffstat (limited to 'engine/battle')
-rwxr-xr-xengine/battle/animations.asm1808
-rw-r--r--engine/battle/bank3d_battle.asm291
-rwxr-xr-xengine/battle/bank_e_misc.asm19
-rw-r--r--engine/battle/battle_transitions.asm14
-rw-r--r--engine/battle/common_text.asm20
-rwxr-xr-xengine/battle/core.asm984
-rw-r--r--engine/battle/decrement_pp.asm2
-rw-r--r--engine/battle/draw_hud_pokeball_gfx.asm12
-rwxr-xr-xengine/battle/end_of_battle.asm4
-rw-r--r--engine/battle/experience.asm26
-rw-r--r--engine/battle/get_trainer_name.asm9
-rw-r--r--engine/battle/ghost_marowak_anim.asm5
-rw-r--r--engine/battle/link_battle_versus_text.asm3
-rw-r--r--engine/battle/moveEffects/heal_effect.asm6
-rw-r--r--engine/battle/moveEffects/reflect_light_screen_effect.asm6
-rw-r--r--engine/battle/moveEffects/transform_effect.asm11
-rwxr-xr-xengine/battle/read_trainer_party.asm109
-rwxr-xr-xengine/battle/safari_zone.asm10
-rw-r--r--engine/battle/scale_sprites.asm7
-rw-r--r--engine/battle/trainer_ai.asm45
-rw-r--r--engine/battle/wild_encounters.asm7
21 files changed, 1929 insertions, 1469 deletions
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm
index ea5738bc..31148392 100755
--- a/engine/battle/animations.asm
+++ b/engine/battle/animations.asm
@@ -1,202 +1,229 @@
; Draws a "frame block". Frame blocks are blocks of tiles that are put
; together to form frames in battle animations.
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
+ 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
xor a
- ld [wFBTileCounter],a ; loop counter
+ ld [wFBTileCounter], a ; loop counter
.loop
- ld a,[wFBTileCounter]
+ ld a, [wFBTileCounter]
inc a
- ld [wFBTileCounter],a
- ld a,[wSubAnimTransform]
+ ld [wFBTileCounter], a
+ ld a, $2
+ ld [wdef5], a
+ ld a, [wSubAnimTransform]
dec a
- jr z,.flipHorizontalAndVertical ; 1
+ jr z, .flipHorizontalAndVertical ; 1
dec a
- jp z,.flipHorizontalTranslateDown ; 2
+ jp z, .flipHorizontalTranslateDown ; 2
dec a
- jr z,.flipBaseCoords ; 3
+ jr z, .flipBaseCoords ; 3
.noTransformation
- ld a,[wBaseCoordY]
+ ld a, [wBaseCoordY]
add [hl]
- ld [de],a ; store Y
+ ld [de], a ; store Y
inc hl
inc de
- ld a,[wBaseCoordX]
+ ld a, [wBaseCoordX]
jr .finishCopying
.flipBaseCoords
- ld a,[wBaseCoordY]
- ld b,a
- ld a,136
+ ld a, [wBaseCoordY]
+ ld b, a
+ ld a, 136
sub b ; flip Y base coordinate
add [hl] ; Y offset
- ld [de],a ; store Y
+ ld [de], a ; store Y
inc hl
inc de
- ld a,[wBaseCoordX]
- ld b,a
- ld a,168
+ ld a, [wBaseCoordX]
+ ld b, a
+ ld a, 168
sub b ; flip X base coordinate
.finishCopying ; finish copying values to OAM (when [wSubAnimTransform] not 1 or 2)
add [hl] ; X offset
- ld [de],a ; store X
+ ld [de], a ; store X
+ cp 88
+ jr c, .asm_78056
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_78056
inc hl
inc de
- ld a,[hli]
- add a,$31 ; base tile ID for battle animations
- ld [de],a ; store tile ID
+ ld a, [hli]
+ add a, $31 ; base tile ID for battle animations
+ ld [de], a ; store tile ID
inc de
- ld a,[hli]
- ld [de],a ; store flags
+ ld a, [hli]
+ ld b, a
+ ld a, [wdef5]
+ or b
+ ld [de], a ; store flags
inc de
jp .nextTile
.flipHorizontalAndVertical
- ld a,[wBaseCoordY]
+ ld a, [wBaseCoordY]
add [hl] ; Y offset
- ld b,a
- ld a,136
+ ld b, a
+ ld a, 136
sub b ; flip Y coordinate
- ld [de],a ; store Y
+ ld [de], a ; store Y
inc hl
inc de
- ld a,[wBaseCoordX]
+ ld a, [wBaseCoordX]
add [hl] ; X offset
- ld b,a
- ld a,168
+ ld b, a
+ ld a, 168
sub b ; flip X coordinate
- ld [de],a ; store X
+ ld [de], a ; store X
+ cp 88
+ jr c, .asm_78087
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_78087
inc hl
inc de
- ld a,[hli]
- add a,$31 ; base tile ID for battle animations
- ld [de],a ; store tile ID
+ ld a, [hli]
+ add a, $31 ; base tile ID for battle animations
+ ld [de], a ; store tile ID
inc de
; toggle horizontal and vertical flip
- ld a,[hli] ; flags
+ ld a, [hli] ; flags
and a
- ld b,OAM_VFLIP | OAM_HFLIP
- jr z,.storeFlags1
- cp a,OAM_HFLIP
- ld b,OAM_VFLIP
- jr z,.storeFlags1
- cp a,OAM_VFLIP
- ld b,OAM_HFLIP
- jr z,.storeFlags1
- ld b,0
+ ld b, OAM_VFLIP | OAM_HFLIP
+ jr z, .storeFlags1
+ cp a, OAM_HFLIP
+ ld b, OAM_VFLIP
+ jr z, .storeFlags1
+ cp a, OAM_VFLIP
+ ld b, OAM_HFLIP
+ jr z, .storeFlags1
+ ld b, 0
.storeFlags1
- ld a,b
- ld [de],a
+ ld a, [wdef5]
+ or b
+ ld [de], a
inc de
jp .nextTile
.flipHorizontalTranslateDown
- ld a,[wBaseCoordY]
+ ld a, [wBaseCoordY]
add [hl]
- add a,40 ; translate Y coordinate downwards
- ld [de],a ; store Y
+ add a, 40 ; translate Y coordinate downwards
+ ld [de], a ; store Y
inc hl
inc de
- ld a,[wBaseCoordX]
+ ld a, [wBaseCoordX]
add [hl]
- ld b,a
- ld a,168
+ ld b, a
+ ld a, 168
sub b ; flip X coordinate
- ld [de],a ; store X
+ ld [de], a ; store X
+ cp 88
+ jr c, .asm_780c8
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_780c8
inc hl
inc de
- ld a,[hli]
- add a,$31 ; base tile ID for battle animations
- ld [de],a ; store tile ID
+ ld a, [hli]
+ add a, $31 ; base tile ID for battle animations
+ ld [de], a ; store tile ID
inc de
- ld a,[hli]
- bit 5,a ; is horizontal flip enabled?
- jr nz,.disableHorizontalFlip
+ ld a, [hli]
+ bit 5, a ; is horizontal flip enabled?
+ jr nz, .disableHorizontalFlip
.enableHorizontalFlip
- set 5,a
+ set 5, a
jr .storeFlags2
.disableHorizontalFlip
- res 5,a
+ res 5, a
.storeFlags2
- ld [de],a
+ ld b, a
+ ld a, [wdef5]
+ or b
+ ld [de], a
inc de
.nextTile
- ld a,[wFBTileCounter]
- ld c,a
- ld a,[wNumFBTiles]
+ ld a, [wFBTileCounter]
+ ld c, a
+ ld a, [wNumFBTiles]
cp c
- jp nz,.loop ; go back up if there are more tiles to draw
+ jp nz, .loop ; go back up if there are more tiles to draw
.afterDrawingTiles
- ld a,[wFBMode]
- cp a,2
- jr z,.advanceFrameBlockDestAddr; skip delay and don't clean OAM buffer
- ld a,[wSubAnimFrameDelay]
- ld c,a
+ ld a, [wFBMode]
+ cp a, 2
+ jr z, .advanceFrameBlockDestAddr; skip delay and don't clean OAM buffer
+ ld a, [wSubAnimFrameDelay]
+ ld c, a
call DelayFrames
- ld a,[wFBMode]
- cp a,3
- jr z,.advanceFrameBlockDestAddr ; skip cleaning OAM buffer
- cp a,4
- jr z,.done ; skip cleaning OAM buffer and don't advance the frame block destination address
- ld a,[wAnimationID]
- cp a,GROWL
- jr z,.resetFrameBlockDestAddr
+ ld a, [wFBMode]
+ cp a, 3
+ jr z, .advanceFrameBlockDestAddr ; skip cleaning OAM buffer
+ cp a, 4
+ jr z, .done ; skip cleaning OAM buffer and don't advance the frame block destination address
+ ld a, [wAnimationID]
+ cp a, GROWL
+ jr z, .resetFrameBlockDestAddr
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
+ 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
ret
.advanceFrameBlockDestAddr
- ld a,e
- ld [wFBDestAddr + 1],a
- ld a,d
- ld [wFBDestAddr],a
+ ld a, e
+ ld [wFBDestAddr + 1], a
+ ld a, d
+ ld [wFBDestAddr], a
.done
ret
PlayAnimation:
xor a
- ld [$FF8B],a ; it looks like nothing reads this
- ld [wSubAnimTransform],a
- ld a,[wAnimationID] ; get animation number
+ ld [$FF8B], a ; it looks like nothing reads this
+ ld [wSubAnimTransform], a
+ ld a, [wAnimationID] ; get animation number
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
+ 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
.animationLoop
- ld a,[hli]
- cp a,$FF
- jr z,.AnimationOver
- cp a,$C0 ; is this subanimation or a special effect?
- jr c,.playSubanimation
+ ld a, [hli]
+ cp a, $FF
+ jr z, .AnimationOver
+ cp a, $C0 ; is this subanimation or a special effect?
+ jr c, .playSubanimation
.doSpecialEffect
- ld c,a
- ld de,SpecialEffectPointers
+ ld c, a
+ ld de, SpecialEffectPointers
.searchSpecialEffectTableLoop
- ld a,[de]
+ ld a, [de]
cp c
- jr z,.foundMatch
+ jr z, .foundMatch
inc de
inc de
inc de
jr .searchSpecialEffectTableLoop
.foundMatch
- ld a,[hli]
- cp a,$FF ; is there a sound to play?
- jr z,.skipPlayingSound
- ld [wAnimSoundID],a ; store sound
+ ld a, [hli]
+ cp a, $FF ; is there a sound to play?
+ jr z, .skipPlayingSound
+ ld [wAnimSoundID], a ; store sound
push hl
push de
call GetMoveSound
@@ -206,50 +233,52 @@ PlayAnimation:
.skipPlayingSound
push hl
inc de
- ld a,[de]
- ld l,a
+ ld a, [de]
+ ld l, a
inc de
- ld a,[de]
- ld h,a
- ld de,.nextAnimationCommand
+ ld a, [de]
+ ld h, a
+ ld de, .nextAnimationCommand
push de
jp [hl] ; jump to special effect function
.playSubanimation
- ld c,a
- and a,%00111111
- ld [wSubAnimFrameDelay],a
+ ld c, a
+ and a, %00111111
+ ld [wSubAnimFrameDelay], a
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
+ 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
push hl
- ld a,[rOBP0]
+ ld a, [rOBP0]
push af
- ld a,[wAnimPalette]
- ld [rOBP0],a
+ ld a, [wAnimPalette]
+ ld [rOBP0], a
+ call UpdateGBCPal_OBP0
call LoadAnimationTileset
call LoadSubanimation
call PlaySubanimation
pop af
- ld [rOBP0],a
+ ld [rOBP0], a
+ call UpdateGBCPal_OBP0
.nextAnimationCommand
pop hl
jr .animationLoop
@@ -257,22 +286,22 @@ PlayAnimation:
ret
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 a,31
- ld [wSubAnimCounter],a ; number of frame blocks
- ld a,b
- and a,%11100000
- cp a,5 << 5 ; is subanimation type 5?
- jr nz,.isNotType5
+ 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 a, 31
+ ld [wSubAnimCounter], a ; number of frame blocks
+ ld a, b
+ and a, %11100000
+ cp a, 5 << 5 ; is subanimation type 5?
+ jr nz, .isNotType5
.isType5
call GetSubanimationTransform2
jr .saveTransformation
@@ -282,35 +311,35 @@ LoadSubanimation:
; place the upper 3 bits of a into bits 0-2 of a before storing
srl a
swap a
- ld [wSubAnimTransform],a
- cp a,4 ; is the animation reversed?
- ld hl,0
- jr nz,.storeSubentryAddr
+ ld [wSubAnimTransform], a
+ cp a, 4 ; is the animation reversed?
+ ld hl, 0
+ jr nz, .storeSubentryAddr
; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
- ld a,[wSubAnimCounter]
+ ld a, [wSubAnimCounter]
dec a
- ld bc,3
+ ld bc, 3
.loop
- add hl,bc
+ add hl, bc
dec a
- jr nz,.loop
+ jr nz, .loop
.storeSubentryAddr
inc de
- add hl,de
- ld a,l
- ld [wSubAnimSubEntryAddr],a
- ld a,h
- ld [wSubAnimSubEntryAddr + 1],a
+ add hl, de
+ ld a, l
+ ld [wSubAnimSubEntryAddr], a
+ ld a, h
+ ld [wSubAnimSubEntryAddr + 1], a
ret
; called if the subanimation type is not 5
; sets the transform to 0 (i.e. no transform) if it's the player's turn
; sets the transform to the subanimation type if it's the enemy's turn
GetSubanimationTransform1:
- ld b,a
- ld a,[H_WHOSETURN]
+ ld b, a
+ ld a, [H_WHOSETURN]
and a
- ld a,b
+ ld a, b
ret nz
xor a
ret
@@ -319,32 +348,32 @@ GetSubanimationTransform1:
; sets the transform to 2 (i.e. horizontal and vertical flip) if it's the player's turn
; sets the transform to 0 (i.e. no transform) if it's the enemy's turn
GetSubanimationTransform2:
- ld a,[H_WHOSETURN]
+ ld a, [H_WHOSETURN]
and a
- ld a,2 << 5
+ ld a, 2 << 5
ret z
xor a
ret
; loads tile patterns for battle animations
LoadAnimationTileset:
- ld a,[wWhichBattleAnimTileset]
+ ld a, [wWhichBattleAnimTileset]
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
- ld hl,vSprites + $310
+ 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
+ ld hl, vSprites + $310
ld b, BANK(AnimationTileset1) ; ROM bank
- ld a,[wTempTilesetNumTiles]
- ld c,a ; number of tiles
+ ld a, [wTempTilesetNumTiles]
+ ld c, a ; number of tiles
jp CopyVideoData ; load tileset
AnimationTilesetPointers:
@@ -367,12 +396,7 @@ AnimationTileset2:
INCBIN "gfx/attack_anim_2.2bpp"
SlotMachineTiles2:
-IF DEF(_RED)
- INCBIN "gfx/red/slotmachine2.2bpp"
-ENDC
-IF DEF(_BLUE)
- INCBIN "gfx/blue/slotmachine2.2bpp"
-ENDC
+ INCBIN "gfx/slotmachine2.2bpp"
MoveAnimation:
push hl
@@ -381,38 +405,38 @@ MoveAnimation:
push af
call WaitForSoundToFinish
call SetAnimationPalette
- ld a,[wAnimationID]
+ ld a, [wAnimationID]
and a
- jr z,.AnimationFinished
+ jr z, .animationFinished
; if throwing a Poké Ball, skip the regular animation code
- cp a,TOSS_ANIM
- jr nz,.MoveAnimation
- ld de,.AnimationFinished
+ cp a, TOSS_ANIM
+ jr nz, .moveAnimation
+ ld de, .animationFinished
push de
jp TossBallAnimation
-.MoveAnimation
+.moveAnimation
; check if battle animations are disabled in the options
- ld a,[wOptions]
- bit 7,a
- jr nz,.AnimationsDisabled
+ ld a, [wOptions]
+ bit 7, a
+ jr nz, .animationsDisabled
call ShareMoveAnimations
call PlayAnimation
jr .next4
-.AnimationsDisabled
- ld c,30
+.animationsDisabled
+ ld c, 30
call DelayFrames
.next4
call PlayApplyingAttackAnimation ; shake the screen or flash the pic in and out (to show damage)
-.AnimationFinished
+.animationFinished
call WaitForSoundToFinish
xor a
- ld [wSubAnimSubEntryAddr],a
- ld [wUnusedD09B],a
- ld [wSubAnimTransform],a
+ ld [wSubAnimSubEntryAddr], a
+ ld [wUnusedD09B], a
+ ld [wSubAnimTransform], a
dec a
- ld [wAnimSoundID],a
+ ld [wAnimSoundID], a
pop af
pop bc
pop de
@@ -421,42 +445,42 @@ MoveAnimation:
ShareMoveAnimations:
; some moves just reuse animations from status conditions
- ld a,[H_WHOSETURN]
+ ld a, [H_WHOSETURN]
and a
ret z
; opponent’s turn
- ld a,[wAnimationID]
+ ld a, [wAnimationID]
- cp a,AMNESIA
- ld b,CONF_ANIM
- jr z,.Replace
+ cp a, AMNESIA
+ ld b, CONF_ANIM
+ jr z, .replaceAnim
- cp a,REST
- ld b,SLP_ANIM
+ cp a, REST
+ ld b, SLP_ANIM
ret nz
-.Replace
- ld a,b
- ld [wAnimationID],a
+.replaceAnim
+ ld a, b
+ ld [wAnimationID], a
ret
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]
+ ld a, [wAnimationType]
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
+ ld c, a
+ ld b, 0
+ ld hl, AnimationTypePointerTable
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
jp [hl]
AnimationTypePointerTable:
@@ -537,6 +561,8 @@ SetAnimationPalette:
ld [rOBP0], a
ld a, $6c
ld [rOBP1], a
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
ret
.notSGB
ld a, $e4
@@ -544,72 +570,94 @@ SetAnimationPalette:
ld [rOBP0], a
ld a, $6c
ld [rOBP1], a
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
+ ret
+
+Func_78e98:
+ call SaveScreenTilesToBuffer2
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ ld h, vBGMap0 / $100
+ call WriteLowerByteOfBGMapAndEnableBGTransfer
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call LoadScreenTilesFromBuffer2
+ ld h, vBGMap1 / $100
+
+WriteLowerByteOfBGMapAndEnableBGTransfer:
+ ld l, vBGMap0 & $ff
+ call BattleAnimCopyTileMapToVRAM
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
ret
PlaySubanimation:
- ld a,[wAnimSoundID]
- cp a,$FF
- jr z,.skipPlayingSound
+ ld a, [wAnimSoundID]
+ cp a, $FF
+ jr z, .skipPlayingSound
call GetMoveSound
call PlaySound
.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
+ 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
.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
+ 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
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
+ 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
pop hl
inc hl
- ld a,[hl] ; frame block mode
- ld [wFBMode],a
+ ld a, [hl] ; frame block mode
+ ld [wFBMode], a
call DrawFrameBlock
call DoSpecialEffectByAnimationId ; run animation-specific function (if there is one)
- ld a,[wSubAnimCounter]
+ ld a, [wSubAnimCounter]
dec a
- ld [wSubAnimCounter],a
+ ld [wSubAnimCounter], a
ret z
- ld a,[wSubAnimSubEntryAddr + 1]
- ld h,a
- ld a,[wSubAnimSubEntryAddr]
- ld l,a
- ld a,[wSubAnimTransform]
- cp a,4 ; is the animation reversed?
- ld bc,3
- jr nz,.nextSubanimationSubentry
- ld bc,-3
+ ld a, [wSubAnimSubEntryAddr + 1]
+ ld h, a
+ ld a, [wSubAnimSubEntryAddr]
+ ld l, a
+ ld a, [wSubAnimTransform]
+ cp a, 4 ; is the animation reversed?
+ ld bc, 3
+ jr nz, .nextSubanimationSubentry
+ ld bc, -3
.nextSubanimationSubentry
- add hl,bc
- ld a,h
- ld [wSubAnimSubEntryAddr + 1],a
- ld a,l
- ld [wSubAnimSubEntryAddr],a
+ add hl, bc
+ ld a, h
+ ld [wSubAnimSubEntryAddr + 1], a
+ ld a, l
+ ld [wSubAnimSubEntryAddr], a
jp .loop
AnimationCleanOAM:
@@ -631,16 +679,16 @@ DoSpecialEffectByAnimationId:
push hl
push de
push bc
- ld a,[wAnimationID]
- ld hl,AnimationIdSpecialEffects
- ld de,3
+ ld a, [wAnimationID]
+ ld hl, AnimationIdSpecialEffects
+ ld de, 3
call IsInArray
- jr nc,.done
+ jr nc, .done
inc hl
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld de,.done
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .done
push de
jp [hl]
.done
@@ -691,7 +739,7 @@ AnimationIdSpecialEffects:
dw DoExplodeSpecialEffects
db SPORE
- dw AnimationFlashScreen
+ dw FlashScreenEveryFourFrameBlocks
db EXPLOSION
dw DoExplodeSpecialEffects
@@ -726,38 +774,39 @@ AnimationIdSpecialEffects:
db $FF ; terminator
DoBallTossSpecialEffects:
- ld a,[wcf91]
- cp a,3 ; is it a Master Ball or Ultra Ball?
- jr nc,.skipFlashingEffect
+ ld a, [wcf91]
+ cp a, 3 ; is it a Master Ball or Ultra Ball?
+ jr nc, .skipFlashingEffect
.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
- ld a,[rOBP0]
- xor a,%00111100 ; complement colors 1 and 2
- ld [rOBP0],a
+ ld a, [rOBP0]
+ xor a, %00111100 ; complement colors 1 and 2
+ ld [rOBP0], a
+ call UpdateGBCPal_OBP0
.skipFlashingEffect
- ld a,[wSubAnimCounter]
- cp a,11 ; is it the beginning of the subanimation?
- jr nz,.skipPlayingSound
+ ld a, [wSubAnimCounter]
+ cp a, 11 ; is it the beginning of the subanimation?
+ jr nz, .skipPlayingSound
; if it is the beginning of the subanimation, play a sound
- ld a,SFX_BALL_TOSS
+ ld a, SFX_BALL_TOSS
call PlaySound
.skipPlayingSound
- ld a,[wIsInBattle]
- cp a,02 ; is it a trainer battle?
- jr z,.isTrainerBattle
- ld a,[wd11e]
- cp a,$10 ; is the enemy pokemon the Ghost Marowak?
+ ld a, [wIsInBattle]
+ cp a, 02 ; is it a trainer battle?
+ jr z, .isTrainerBattle
+ ld a, [wd11e]
+ cp a, $10 ; is the enemy pokemon the Ghost Marowak?
ret nz
; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
- ld a,[wSubAnimCounter]
- cp a,3
- jr z,.moveGhostMarowakLeft
- cp a,2
- jr z,.moveGhostMarowakLeft
- cp a,1
+ ld a, [wSubAnimCounter]
+ cp a, 3
+ jr z, .moveGhostMarowakLeft
+ cp a, 2
+ jr z, .moveGhostMarowakLeft
+ cp a, 1
ret nz
.moveGhostMarowakLeft
coord hl, 17, 0
- ld de,20
+ ld de, 20
lb bc, 7, 7
.loop
push hl
@@ -765,152 +814,152 @@ DoBallTossSpecialEffects:
call AnimCopyRowRight ; move row of tiles left
pop bc
pop hl
- add hl,de
+ add hl, de
dec b
- jr nz,.loop
- ld a,%00001000
- ld [rNR10],a ; Channel 1 sweep register
+ jr nz, .loop
+ ld a, %00001000
+ ld [rNR10], a ; Channel 1 sweep register
ret
.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
- ld a,[wSubAnimCounter]
- cp a,3
+ ld a, [wSubAnimCounter]
+ cp a, 3
ret nz
dec a
- ld [wSubAnimCounter],a
+ ld [wSubAnimCounter], a
ret
DoBallShakeSpecialEffects:
- ld a,[wSubAnimCounter]
- cp a,4 ; is it the beginning of a shake?
- jr nz,.skipPlayingSound
+ ld a, [wSubAnimCounter]
+ cp a, 4 ; is it the beginning of a shake?
+ jr nz, .skipPlayingSound
; if it is the beginning of a shake, play a sound and wait 2/3 of a second
- ld a,SFX_TINK
+ ld a, SFX_TINK
call PlaySound
- ld c,40
+ ld c, 40
call DelayFrames
.skipPlayingSound
- ld a,[wSubAnimCounter]
+ ld a, [wSubAnimCounter]
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
+ ld a, [wNumShakes] ; number of shakes
dec a ; decrement number of shakes
- ld [wNumShakes],a
+ ld [wNumShakes], a
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
+ 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
ret
; plays a sound after the second frame of the poof animation
DoPoofSpecialEffects:
- ld a,[wSubAnimCounter]
- cp a,5
+ ld a, [wSubAnimCounter]
+ cp a, 5
ret nz
- ld a,SFX_BALL_POOF
+ ld a, SFX_BALL_POOF
jp PlaySound
DoRockSlideSpecialEffects:
- ld a,[wSubAnimCounter]
- cp a,12
+ ld a, [wSubAnimCounter]
+ cp a, 12
ret nc
- cp a,8
- jr nc,.shakeScreen
- cp a,1
- jp z,AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
+ cp a, 8
+ jr nc, .shakeScreen
+ cp a, 1
+ jp z, AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
ret
; if the subaninmation counter is between 8 and 11, shake the screen horizontally and vertically
.shakeScreen
- ld b,1
+ ld b, 1
predef PredefShakeScreenHorizontally ; shake horizontally
- ld b,1
+ ld b, 1
predef_jump PredefShakeScreenVertically ; shake vertically
FlashScreenEveryEightFrameBlocks:
- ld a,[wSubAnimCounter]
- and a,7 ; is the subanimation counter exactly 8?
- call z,AnimationFlashScreen ; if so, flash the screen
+ ld a, [wSubAnimCounter]
+ and a, 7 ; is the subanimation counter exactly 8?
+ call z, AnimationFlashScreen ; if so, flash the screen
ret
; flashes the screen if the subanimation counter is divisible by 4
FlashScreenEveryFourFrameBlocks:
- ld a,[wSubAnimCounter]
- and a,3
- call z,AnimationFlashScreen
+ ld a, [wSubAnimCounter]
+ and a, 3
+ call z, AnimationFlashScreen
ret
; used for Explosion and Selfdestruct
DoExplodeSpecialEffects:
- ld a,[wSubAnimCounter]
- cp a,1 ; is it the end of the subanimation?
- jr nz,FlashScreenEveryFourFrameBlocks
+ ld a, [wSubAnimCounter]
+ cp a, 1 ; is it the end of the subanimation?
+ jr nz, FlashScreenEveryFourFrameBlocks
; if it's the end of the subanimation, make the attacking pokemon disappear
coord hl, 1, 5
jp AnimationHideMonPic ; make pokemon disappear
; flashes the screen when subanimation counter is 1 modulo 4
DoBlizzardSpecialEffects:
- ld a,[wSubAnimCounter]
- cp a,13
- jp z,AnimationFlashScreen
- cp a,9
- jp z,AnimationFlashScreen
- cp a,5
- jp z,AnimationFlashScreen
- cp a,1
- jp z,AnimationFlashScreen
+ ld a, [wSubAnimCounter]
+ cp a, 13
+ jp z, AnimationFlashScreen
+ cp a, 9
+ jp z, AnimationFlashScreen
+ cp a, 5
+ jp z, AnimationFlashScreen
+ cp a, 1
+ jp z, AnimationFlashScreen
ret
; flashes the screen at 3 points in the subanimation
; unused
FlashScreenUnused:
- ld a,[wSubAnimCounter]
- cp a,14
- jp z,AnimationFlashScreen
- cp a,9
- jp z,AnimationFlashScreen
- cp a,2
- jp z,AnimationFlashScreen
+ ld a, [wSubAnimCounter]
+ cp a, 14
+ jp z, AnimationFlashScreen
+ cp a, 9
+ jp z, AnimationFlashScreen
+ cp a, 2
+ jp z, AnimationFlashScreen
ret
; function to make the pokemon disappear at the beginning of the animation
TradeHidePokemon:
- ld a,[wSubAnimCounter]
- cp a,6
+ ld a, [wSubAnimCounter]
+ cp a, 6
ret nz
- ld a,2 * SCREEN_WIDTH + 7
+ ld a, 2 * SCREEN_WIDTH + 7
jp ClearMonPicFromTileMap ; make pokemon disappear
; function to make a shaking pokeball jump up at the end of the animation
TradeShakePokeball:
- ld a,[wSubAnimCounter]
- cp a,1
+ ld a, [wSubAnimCounter]
+ cp a, 1
ret nz
; if it's the end of the animation, make the ball jump up
- ld de,BallMoveDistances1
+ ld de, BallMoveDistances1
.loop
- ld hl,wOAMBuffer ; OAM buffer
- ld bc,4
+ ld hl, wOAMBuffer ; OAM buffer
+ ld bc, 4
.innerLoop
- ld a,[de]
- cp a,$ff
- jr z,.done
+ ld a, [de]
+ cp a, $ff
+ jr z, .done
add [hl] ; add to Y value of OAM entry
- ld [hl],a
- add hl,bc
- ld a,l
- cp a,4 * 4 ; there are 4 entries, each 4 bytes
- jr nz,.innerLoop
+ ld [hl], a
+ add hl, bc
+ ld a, l
+ cp a, 4 * 4 ; there are 4 entries, each 4 bytes
+ jr nz, .innerLoop
inc de
push bc
call Delay3
@@ -918,74 +967,73 @@ TradeShakePokeball:
jr .loop
.done
call AnimationCleanOAM
- ld a,SFX_TRADE_MACHINE
+ ld a, SFX_TRADE_MACHINE
jp PlaySound
BallMoveDistances1:
- db -12,-12,-8
+ db -12, -12, -8
db $ff ; terminator
; function to make the pokeball jump up
-TradeJumpPokeball: ; 507C
- ld de,BallMoveDistances2
+TradeJumpPokeball:
+ ld de, BallMoveDistances2
.loop
- ld hl,wOAMBuffer ; OAM buffer
- ld bc,4
+ ld hl, wOAMBuffer ; OAM buffer
+ ld bc, 4
.innerLoop
- ld a,[de]
- cp a,$ff
- jp z,ClearScreen
+ ld a, [de]
+ cp a, $ff
+ jp z, ClearScreen
add [hl]
- ld [hl],a
- add hl,bc
- ld a,l
- cp a,4 * 4 ; there are 4 entries, each 4 bytes
- jr nz,.innerLoop
+ ld [hl], a
+ add hl, bc
+ ld a, l
+ cp a, 4 * 4 ; there are 4 entries, each 4 bytes
+ jr nz, .innerLoop
inc de
push de
- ld a,[de]
- cp a,12
- jr z,.playSound
- cp a,$ff
- jr nz,.skipPlayingSound
+ ld a, [de]
+ cp a, 12
+ jr z, .playSound
+ cp a, $ff
+ jr nz, .skipPlayingSound
.playSound ; play sound if next move distance is 12 or this is the last one
- ld a,SFX_BATTLE_18
+ ld a, SFX_BATTLE_18
call PlaySound
.skipPlayingSound
push bc
- ld c,5
+ ld c, 5
call DelayFrames
pop bc
- ld a,[hSCX] ; background scroll X
- sub a,8 ; scroll to the left
- ld [hSCX],a
+ ld a, [hSCX] ; background scroll X
+ sub a, 8 ; scroll to the left
+ ld [hSCX], a
pop de
jr .loop
BallMoveDistances2:
- db 11,12,-12,-7,7,12,-8,8
+ db 11, 12, -12, -7, 7, 12, -8, 8
db $ff ; terminator
; this function copies the current musical note graphic
; so that there are two musical notes flying towards the defending pokemon
DoGrowlSpecialEffects:
- ld hl,wOAMBuffer ; OAM buffer
- ld de,wOAMBuffer + $10
- ld bc,$10
+ ld hl, wOAMBuffer ; OAM buffer
+ ld de, wOAMBuffer + $10
+ ld bc, $10
call CopyData ; copy the musical note graphic
- ld a,[wSubAnimCounter]
+ ld a, [wSubAnimCounter]
dec a
- call z,AnimationCleanOAM ; clean up at the end of the subanimation
+ call z, AnimationCleanOAM ; clean up at the end of the subanimation
ret
; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
TailWhipAnimationUnused:
- ld a,1
- ld [wSubAnimCounter],a
- ld c,20
+ ld a, 1
+ ld [wSubAnimCounter], a
+ ld c, 20
jp DelayFrames
-; Format: Special Effect ID (1 byte), Address (2 bytes)
SpecialEffectPointers:
db SE_DARK_SCREEN_FLASH ; $FE
dw AnimationFlashScreen
@@ -1068,48 +1116,49 @@ SpecialEffectPointers:
db $FF
AnimationDelay10:
- ld c,10
+ ld c, 10
jp DelayFrames
; calls a function with the turn flipped from player to enemy or vice versa
; input - hl - address of function to call
CallWithTurnFlipped:
- ld a,[H_WHOSETURN]
+ ld a, [H_WHOSETURN]
push af
- xor a,1
- ld [H_WHOSETURN],a
- ld de,.returnAddress
+ xor a, 1
+ ld [H_WHOSETURN], a
+ ld de, .returnAddress
push de
jp [hl]
.returnAddress
pop af
- ld [H_WHOSETURN],a
+ ld [H_WHOSETURN], a
ret
; flashes the screen for an extended period (48 frames)
AnimationFlashScreenLong:
- ld a,3 ; cycle through the palettes 3 times
- ld [wFlashScreenLongCounter],a
- ld a,[wOnSGB] ; running on SGB?
+ ld a, 3 ; cycle through the palettes 3 times
+ ld [wFlashScreenLongCounter], a
+ ld a, [wOnSGB] ; running on SGB?
and a
- ld hl,FlashScreenLongMonochrome
- jr z,.loop
- ld hl,FlashScreenLongSGB
+ ld hl, FlashScreenLongMonochrome
+ jr z, .loop
+ ld hl, FlashScreenLongSGB
.loop
push hl
.innerLoop
- ld a,[hli]
- cp a,$01 ; is it the end of the palettes?
- jr z,.endOfPalettes
- ld [rBGP],a
+ ld a, [hli]
+ cp a, $01 ; is it the end of the palettes?
+ jr z, .endOfPalettes
+ ld [rBGP], a
+ call UpdateGBCPal_BGP
call FlashScreenLongDelay
jr .innerLoop
.endOfPalettes
- ld a,[wFlashScreenLongCounter]
+ ld a, [wFlashScreenLongCounter]
dec a
- ld [wFlashScreenLongCounter],a
+ ld [wFlashScreenLongCounter], a
pop hl
- jr nz,.loop
+ jr nz, .loop
ret
; BG palettes
@@ -1147,31 +1196,34 @@ FlashScreenLongSGB:
; causes a delay of 2 frames for the first cycle
; causes a delay of 1 frame for the second and third cycles
FlashScreenLongDelay:
- ld a,[wFlashScreenLongCounter]
- cp a,4 ; never true since [wFlashScreenLongCounter] starts at 3
- ld c,4
- jr z,.delayFrames
- cp a,3
- ld c,2
- jr z,.delayFrames
- cp a,2 ; nothing is done with this
- ld c,1
+ ld a, [wFlashScreenLongCounter]
+ cp a, 4 ; never true since [wFlashScreenLongCounter] starts at 3
+ ld c, 4
+ jr z, .delayFrames
+ cp a, 3
+ ld c, 2
+ jr z, .delayFrames
+ cp a, 2 ; nothing is done with this
+ ld c, 1
.delayFrames
jp DelayFrames
AnimationFlashScreen:
- ld a,[rBGP]
+ ld a, [rBGP]
push af ; save initial palette
- ld a,%00011011 ; 0, 1, 2, 3 (inverted colors)
- ld [rBGP],a
- ld c,2
+ ld a, %00011011 ; 0, 1, 2, 3 (inverted colors)
+ ld [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 2
call DelayFrames
xor a ; white out background
- ld [rBGP],a
- ld c,2
+ ld [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 2
call DelayFrames
pop af
- ld [rBGP],a ; restore initial palette
+ ld [rBGP], a ; restore initial palette
+ call UpdateGBCPal_BGP
ret
AnimationDarkScreenPalette:
@@ -1217,6 +1269,7 @@ SetAnimationBGPalette:
ld a, c
.next
ld [rBGP], a
+ call UpdateGBCPal_BGP
ret
ld b, $5
@@ -1261,15 +1314,30 @@ AnimationWaterDropletsEverywhere:
_AnimationWaterDroplets:
ld hl, wOAMBuffer
.loop
+ ld a, $1
+ ld [wdef5], a
ld a, [wBaseCoordY]
ld [hli], a ; Y
+ cp 40
+ jr c, .asm_792d7
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_792d7
ld a, [wBaseCoordX]
add 27
ld [wBaseCoordX], a
ld [hli], a ; X
+ cp 88
+ jr c, .asm_792ee
+ ld a, [wdef5]
+ add $2
+ and $3
+ ld [wdef5], a
+.asm_792ee
ld a, [wDropletTile]
ld [hli], a ; tile
- xor a
+ ld a, [wdef5]
ld [hli], a ; attribute
ld a, [wBaseCoordX]
cp 144
@@ -1412,16 +1480,30 @@ BattleAnimWriteOAMEntry:
; Y coordinate = e (increased by 8 each call, before the write to OAM)
; X coordinate = [wBaseCoordX]
; tile = d
-; attributes = 0
+; attributes = variable (dependant on coords)
+ ld a, $1
+ ld [wdef5], a
ld a, e
add 8
ld e, a
ld [hli], a
+ cp 40
+ jr c, .asm_793d8
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_793d8
ld a, [wBaseCoordX]
ld [hli], a
+ cp 88
+ jr c, .asm_793e8
+ ld a, [wdef5]
+ add $2
+ ld [wdef5], a
+.asm_793e8
ld a, d
ld [hli], a
- xor a
+ ld a, [wdef5]
ld [hli], a
ret
@@ -1473,7 +1555,7 @@ AdjustOAMBlockYPos2:
ret
AnimationBlinkEnemyMon:
-; Make the enemy mon's sprite blink on and off for a second or two
+ ; Make the enemy mon's sprite blink on and off for a second or two
ld hl, AnimationBlinkMon
jp CallWithTurnFlipped
@@ -1626,6 +1708,8 @@ AnimationSpiralBallsInward:
ld a, [hl]
cp $ff
jr z, .done
+ ld a, $2
+ ld [wdef5], a
ld a, [wSpiralBallsBaseY]
add [hl]
ld [de], a ; Y
@@ -1634,9 +1718,20 @@ AnimationSpiralBallsInward:
ld a, [wSpiralBallsBaseX]
add [hl]
ld [de], a ; X
+ cp 88
+ jr c, .asm_79524
+ ld a, $3
+ ld [wdef5], a
+.asm_79524
inc hl
inc de
inc de
+ ld a, [de]
+ and $f0
+ ld b, a
+ ld a, [wdef5]
+ or b
+ ld [de], a
inc de
dec c
jr nz, .innerLoop
@@ -1845,13 +1940,13 @@ AnimationMinimizeMon:
ld hl, wTempPic
push hl
xor a
- ld bc, $310
+ ld bc, 7 * 7 * $10
call FillMemory
pop hl
ld de, $194
add hl, de
ld de, MinimizedMonSprite
- ld c, $5
+ ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
.loop
ld a, [de]
ld [hli], a
@@ -1865,6 +1960,7 @@ AnimationMinimizeMon:
MinimizedMonSprite:
INCBIN "gfx/minimized_mon_sprite.1bpp"
+MinimizedMonSpriteEnd:
AnimationSlideMonDownAndHide:
; Slides the mon's sprite down and disappears. Used in Acid Armor.
@@ -1937,25 +2033,23 @@ _AnimationSlideMonOff:
jr nz, .slideLoop
ret
-; Since mon pic tile numbers go from top to bottom, left to right in order,
+; 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.
-.PlayerNextTile ; 79633 (1e:5633)
+.PlayerNextTile ; 79702 (1e:5702)
ld a, [hl]
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.
- cp $61
+; bugfix: compares against the max tile + 1 as opposed to the max tile
+ cp $62
ret c
ld a, " "
ret
-.EnemyNextTile ; 7963c (1e:563c)
+.EnemyNextTile ; 7970b (1e:570b)
ld a, [hl]
sub 7
; This has the same problem as above, but it has no visible effect because
@@ -2087,18 +2181,24 @@ AnimationSubstitute:
CopySlowbroSpriteData:
ld bc, $0010
ld a, BANK(SlowbroSprite)
- jp FarCopyData2
+ jp FarCopyData
HideSubstituteShowMonAnim:
ld a, [H_WHOSETURN]
and a
ld hl, wPlayerMonMinimized
+ ld de, wPlayerBattleStatus1
+ ld bc, wPlayerMoveNum
ld a, [wPlayerBattleStatus2]
jr z, .next1
ld hl, wEnemyMonMinimized
+ ld de, wEnemyBattleStatus1
+ ld bc, wEnemyMoveNum
ld a, [wEnemyBattleStatus2]
.next1
push hl
+ push de
+ push bc
; if the substitute broke, slide it down, else slide it offscreen horizontally
bit HasSubstituteUp, a
jr nz, .substituteStillUp
@@ -2107,12 +2207,65 @@ HideSubstituteShowMonAnim:
.substituteStillUp
call AnimationSlideMonOff
.next2
+ pop bc
+ pop de
+ ld a, [de]
+ bit Invulnerable, a
pop hl
+ jr nz, .invulnerable
+ ld a, [bc]
+ cp FLY
+ jr z, .flyOrDig
+ cp DIG
+ jr z, .flyOrDig
+.invulnerable
ld a, [hl]
and a
jp nz, AnimationMinimizeMon
call AnimationFlashMonPic
jp AnimationShowMonPic
+.flyOrDig
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .enemy
+ ld a, [wPlayerMonMinimized]
+ and a
+ jr nz, .monIsMinimized
+ ld a, [wBattleMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call GetMonHeader
+ predef LoadMonBackPic
+ ret
+.enemy
+ ld a, [wEnemyMonMinimized]
+ and a
+ jr nz, .monIsMinimized
+ ld a, [wEnemyMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld de, vFrontPic
+ jp LoadMonFrontSprite
+.monIsMinimized
+ ld hl, wTempPic
+ push hl
+ xor a
+ ld bc, 7 * 7 * $10
+ call FillMemory
+ pop hl
+ ld de, $194
+ add hl, de
+ ld de, MinimizedMonSprite
+ ld c, MinimizedMonSpriteEnd - MinimizedMonSprite
+.loop
+ ld a, [de]
+ ld [hli], a
+ ld [hli], a
+ inc de
+ dec c
+ jr nz, .loop
+ jp CopyTempPicToMonPic
ReshowSubstituteAnim:
call AnimationSlideMonOff
@@ -2180,6 +2333,23 @@ AnimationHideEnemyMonPic:
ld [H_AUTOBGTRANSFERENABLED], a
jp Delay3
+Func_79929:
+ ld hl, wPlayerMonMinimized
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+ ld hl, wEnemyMonMinimized
+.playerTurn
+ ld a, [hl]
+ and a
+ jr z, .notMinimized
+ call AnimationMinimizeMon
+ ret
+.notMinimized
+ call AnimationFlashMonPic
+ call AnimationShowMonPic
+ ret
+
InitMultipleObjectsOAM:
; Writes c OAM entries with tile d.
; Sets their Y coordinates to sequential multiples of 8, starting from 0.
@@ -2201,6 +2371,8 @@ InitMultipleObjectsOAM:
jr nz, .loop
ret
+ ret ; unreferenced
+
AnimationHideMonPic:
; Hides the mon's sprite.
ld a, [H_WHOSETURN]
@@ -2227,7 +2399,7 @@ ClearMonPicFromTileMap:
ret
; 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,
+; 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.
GetMonSpriteTileMapPointerFromRowCount:
push de
@@ -2308,54 +2480,53 @@ GetMoveSoundB:
ld b, a
ret
-; get the sound of the (move id - 1) in a
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
+ ld hl, MoveSoundTable
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld b, a
call IsCryMove
- jr nc,.NotCryMove
- ld a,[H_WHOSETURN]
+ jr nc, .NotCryMove
+ ld a, [H_WHOSETURN]
and a
- jr nz,.next
- ld a,[wBattleMonSpecies] ; get number of current monster
+ jr nz, .next
+ ld a, [wBattleMonSpecies] ; get number of current monster
jr .Continue
.next
- ld a,[wEnemyMonSpecies]
+ ld a, [wEnemyMonSpecies]
.Continue
push hl
call GetCryData
- ld b,a
+ ld b, a
pop hl
- ld a,[wFrequencyModifier]
+ ld a, [wFrequencyModifier]
add [hl]
- ld [wFrequencyModifier],a
+ ld [wFrequencyModifier], a
inc hl
- ld a,[wTempoModifier]
+ ld a, [wTempoModifier]
add [hl]
- ld [wTempoModifier],a
+ ld [wTempoModifier], a
jr .done
.NotCryMove
- ld a,[hli]
- ld [wFrequencyModifier],a
- ld a,[hli]
- ld [wTempoModifier],a
+ ld a, [hli]
+ ld [wFrequencyModifier], a
+ ld a, [hli]
+ ld [wTempoModifier], a
.done
- ld a,b
+ ld a, b
ret
IsCryMove:
; set carry if the move animation involves playing a monster cry
- ld a,[wAnimationID]
- cp a,GROWL
- jr z,.CryMove
- cp a,ROAR
- jr z,.CryMove
+ ld a, [wAnimationID]
+ cp a, GROWL
+ jr z, .CryMove
+ cp a, ROAR
+ jr z, .CryMove
and a ; clear carry
ret
.CryMove
@@ -2363,172 +2534,173 @@ IsCryMove:
ret
MoveSoundTable:
- db SFX_POUND, $00,$80 ; POUND
- db SFX_BATTLE_0C, $10,$80 ; KARATE_CHOP
- db SFX_DOUBLESLAP, $00,$80 ; DOUBLESLAP
- db SFX_BATTLE_0B, $01,$80 ; COMET_PUNCH
- db SFX_BATTLE_0D, $00,$40 ; MEGA_PUNCH
- db SFX_SILPH_SCOPE, $00,$ff ; PAY_DAY
- db SFX_BATTLE_0D, $10,$60 ; FIRE_PUNCH
- db SFX_BATTLE_0D, $20,$80 ; ICE_PUNCH
- db SFX_BATTLE_0D, $00,$a0 ; THUNDERPUNCH
- db SFX_DAMAGE, $00,$80 ; SCRATCH
- db SFX_BATTLE_0F, $20,$40 ; VICEGRIP
- db SFX_BATTLE_0F, $00,$80 ; GUILLOTINE
- db SFX_BATTLE_0E, $00,$a0 ; RAZOR_WIND
- db SFX_NOT_VERY_EFFECTIVE,$10,$c0 ; SWORDS_DANCE
- db SFX_NOT_VERY_EFFECTIVE,$00,$a0 ; CUT
- db SFX_BATTLE_12, $00,$c0 ; GUST
- db SFX_BATTLE_12, $10,$a0 ; WING_ATTACK
- db SFX_BATTLE_13, $00,$e0 ; WHIRLWIND
- db SFX_NOT_VERY_EFFECTIVE,$20,$c0 ; FLY
- db SFX_BATTLE_14, $00,$80 ; BIND
- db SFX_BATTLE_22, $00,$80 ; SLAM
- db SFX_VINE_WHIP, $01,$80 ; VINE_WHIP
- db SFX_BATTLE_20, $00,$80 ; STOMP
- db SFX_BATTLE_17, $f0,$40 ; DOUBLE_KICK
- db SFX_SUPER_EFFECTIVE, $00,$80 ; MEGA_KICK
- db SFX_BATTLE_17, $00,$80 ; JUMP_KICK
- db SFX_BATTLE_21, $10,$80 ; ROLLING_KICK
- db SFX_BATTLE_1B, $01,$a0 ; SAND_ATTACK
- db SFX_BATTLE_18, $00,$80 ; HEADBUTT
- db SFX_BATTLE_1E, $00,$60 ; HORN_ATTACK
- db SFX_BATTLE_1E, $01,$40 ; FURY_ATTACK
- db SFX_HORN_DRILL, $00,$a0 ; HORN_DRILL
- db SFX_SUPER_EFFECTIVE, $10,$a0 ; TACKLE
- db SFX_BATTLE_20, $00,$c0 ; BODY_SLAM
- db SFX_BATTLE_14, $10,$60 ; WRAP
- db SFX_SUPER_EFFECTIVE, $00,$a0 ; TAKE_DOWN
- db SFX_BATTLE_22, $11,$c0 ; THRASH
- db SFX_SUPER_EFFECTIVE, $20,$c0 ; DOUBLE_EDGE
- db SFX_BATTLE_21, $00,$80 ; TAIL_WHIP
- db SFX_BATTLE_1B, $00,$80 ; POISON_STING
- db SFX_BATTLE_1B, $20,$c0 ; TWINEEDLE
- db SFX_BATTLE_19, $00,$80 ; PIN_MISSILE
- db SFX_BATTLE_31, $ff,$40 ; LEER
- db SFX_BATTLE_1E, $00,$80 ; BITE
- db SFX_BATTLE_0B, $00,$c0 ; GROWL
- db SFX_BATTLE_0B, $00,$40 ; ROAR
- db SFX_BATTLE_35, $00,$80 ; SING
- db SFX_BATTLE_27, $40,$60 ; SUPERSONIC
- db SFX_BATTLE_27, $00,$80 ; SONICBOOM
- db SFX_BATTLE_27, $ff,$40 ; DISABLE
- db SFX_BATTLE_2A, $80,$c0 ; ACID
- db SFX_BATTLE_19, $10,$a0 ; EMBER
- db SFX_BATTLE_19, $21,$e0 ; FLAMETHROWER
- db SFX_BATTLE_29, $00,$80 ; MIST
- db SFX_BATTLE_24, $20,$60 ; WATER_GUN
- db SFX_BATTLE_2A, $00,$80 ; HYDRO_PUMP
- db SFX_BATTLE_2C, $00,$80 ; SURF
- db SFX_BATTLE_28, $40,$80 ; ICE_BEAM
- db SFX_BATTLE_29, $f0,$e0 ; BLIZZARD
- db SFX_PSYBEAM, $00,$80 ; PSYBEAM
- db SFX_BATTLE_2A, $f0,$60 ; BUBBLEBEAM
- db SFX_BATTLE_28, $00,$80 ; AURORA_BEAM
- db SFX_BATTLE_36, $00,$80 ; HYPER_BEAM
- db SFX_PECK,$01, $a0 ; PECK
- db SFX_BATTLE_13, $f0,$20 ; DRILL_PECK
- db SFX_BATTLE_23, $01,$c0 ; SUBMISSION
- db SFX_BATTLE_23, $00,$80 ; LOW_KICK
- db SFX_SUPER_EFFECTIVE, $00,$e0 ; COUNTER
- db SFX_BATTLE_26, $01,$60 ; SEISMIC_TOSS
- db SFX_BATTLE_26, $20,$40 ; STRENGTH
- db SFX_BATTLE_24, $00,$80 ; ABSORB
- db SFX_BATTLE_24, $40,$c0 ; MEGA_DRAIN
- db SFX_BATTLE_1B, $03,$60 ; LEECH_SEED
- db SFX_BATTLE_25, $11,$e0 ; GROWTH
- db SFX_BATTLE_12, $20,$e0 ; RAZOR_LEAF
- db SFX_BATTLE_2E, $00,$80 ; SOLARBEAM
- db SFX_BATTLE_1C, $00,$80 ; POISONPOWDER
- db SFX_BATTLE_1C, $11,$a0 ; STUN_SPORE
- db SFX_BATTLE_1C, $01,$c0 ; SLEEP_POWDER
- db SFX_BATTLE_13, $14,$c0 ; PETAL_DANCE
- db SFX_BATTLE_1B, $02,$a0 ; STRING_SHOT
- db SFX_BATTLE_29, $f0,$80 ; DRAGON_RAGE
- db SFX_BATTLE_29, $20,$c0 ; FIRE_SPIN
- db SFX_BATTLE_2F, $00,$20 ; THUNDERSHOCK
- db SFX_BATTLE_2F, $20,$80 ; THUNDERBOLT
- db SFX_BATTLE_2E, $12,$60 ; THUNDER_WAVE
- db SFX_BATTLE_26, $00,$80 ; THUNDER
- db SFX_BATTLE_14, $01,$e0 ; ROCK_THROW
- db SFX_BATTLE_29, $0f,$e0 ; EARTHQUAKE
- db SFX_BATTLE_29, $11,$20 ; FISSURE
- db SFX_DAMAGE, $10,$40 ; DIG
- db SFX_BATTLE_0F, $10,$c0 ; TOXIC
- db SFX_BATTLE_14, $00,$20 ; CONFUSION
- db SFX_PSYCHIC_M, $00,$80 ; PSYCHIC_M
- db SFX_BATTLE_35, $11,$18 ; HYPNOSIS
- db SFX_BATTLE_09, $20,$c0 ; MEDITATE
- db SFX_FAINT_FALL, $20,$c0 ; AGILITY
- db SFX_BATTLE_25, $00,$10 ; QUICK_ATTACK
- db SFX_BATTLE_26, $f0,$20 ; RAGE
- db SFX_BATTLE_33, $f0,$c0 ; TELEPORT
- db SFX_NOT_VERY_EFFECTIVE,$f0,$e0 ; NIGHT_SHADE
- db SFX_BATTLE_09, $f0,$40 ; MIMIC
- db SFX_BATTLE_31, $00,$80 ; SCREECH
- db SFX_BATTLE_33, $80,$40 ; DOUBLE_TEAM
- db SFX_BATTLE_33, $00,$80 ; RECOVER
- db SFX_BATTLE_14, $11,$20 ; HARDEN
- db SFX_BATTLE_14, $22,$10 ; MINIMIZE
- db SFX_BATTLE_1B, $f1,$ff ; SMOKESCREEN
- db SFX_BATTLE_13, $f1,$ff ; CONFUSE_RAY
- db SFX_BATTLE_14, $33,$30 ; WITHDRAW
- db SFX_BATTLE_32, $40,$c0 ; DEFENSE_CURL
- db SFX_BATTLE_0E, $20,$20 ; BARRIER
- db SFX_BATTLE_0E, $f0,$10 ; LIGHT_SCREEN
- db SFX_BATTLE_0F, $f8,$10 ; HAZE
- db SFX_NOT_VERY_EFFECTIVE,$f0,$10 ; REFLECT
- db SFX_BATTLE_25, $00,$80 ; FOCUS_ENERGY
- db SFX_BATTLE_18, $00,$c0 ; BIDE
- db SFX_BATTLE_32, $c0,$ff ; METRONOME
- db SFX_BATTLE_09, $f2,$20 ; MIRROR_MOVE
- db SFX_BATTLE_34, $00,$80 ; SELFDESTRUCT
- db SFX_BATTLE_34, $00,$40 ; EGG_BOMB
- db SFX_BATTLE_09, $00,$40 ; LICK
- db SFX_NOT_VERY_EFFECTIVE,$10,$ff ; SMOG
- db SFX_BATTLE_2A, $20,$20 ; SLUDGE
- db SFX_BATTLE_32, $00,$80 ; BONE_CLUB
- db SFX_BATTLE_29, $1f,$20 ; FIRE_BLAST
- db SFX_BATTLE_25, $2f,$80 ; WATERFALL
- db SFX_BATTLE_0F, $1f,$ff ; CLAMP
- db SFX_BATTLE_2B, $1f,$60 ; SWIFT
- db SFX_BATTLE_26, $1e,$20 ; SKULL_BASH
- db SFX_BATTLE_26, $1f,$18 ; SPIKE_CANNON
- db SFX_BATTLE_14, $0f,$80 ; CONSTRICT
- db SFX_BATTLE_09, $f8,$10 ; AMNESIA
- db SFX_FAINT_FALL, $18,$20 ; KINESIS
- db SFX_BATTLE_32, $08,$40 ; SOFTBOILED
- db SFX_BATTLE_17, $01,$e0 ; HI_JUMP_KICK
- db SFX_NOT_VERY_EFFECTIVE,$09,$ff ; GLARE
- db SFX_BATTLE_35, $42,$01 ; DREAM_EATER
- db SFX_BATTLE_1C, $00,$ff ; POISON_GAS
- db SFX_BATTLE_32, $08,$e0 ; BARRAGE
- db SFX_BATTLE_24, $00,$80 ; LEECH_LIFE
- db SFX_BATTLE_09, $88,$10 ; LOVELY_KISS
- db SFX_BATTLE_25, $48,$ff ; SKY_ATTACK
- db SFX_FAINT_FALL, $ff,$ff ; TRANSFORM
- db SFX_BATTLE_24, $ff,$10 ; BUBBLE
- db SFX_FAINT_FALL, $ff,$04 ; DIZZY_PUNCH
- db SFX_BATTLE_1C, $01,$ff ; SPORE
- db SFX_BATTLE_13, $f8,$ff ; FLASH
- db SFX_BATTLE_0C, $f0,$f0 ; PSYWAVE
- db SFX_BATTLE_0F, $08,$10 ; SPLASH
- db SFX_BATTLE_0D, $f0,$ff ; ACID_ARMOR
- db SFX_SUPER_EFFECTIVE, $f0,$ff ; CRABHAMMER
- db SFX_BATTLE_34, $10,$ff ; EXPLOSION
- db SFX_BATTLE_0E, $f0,$20 ; FURY_SWIPES
- db SFX_BATTLE_2B, $f0,$60 ; BONEMERANG
- db SFX_BATTLE_21, $12,$10 ; REST
- db SFX_BATTLE_36, $f0,$20 ; ROCK_SLIDE
- db SFX_BATTLE_1E, $12,$ff ; HYPER_FANG
- db SFX_BATTLE_31, $80,$04 ; SHARPEN
- db SFX_BATTLE_33, $f0,$10 ; CONVERSION
- db SFX_BATTLE_29, $f8,$ff ; TRI_ATTACK
- db SFX_BATTLE_26, $f0,$ff ; SUPER_FANG
- db SFX_NOT_VERY_EFFECTIVE,$01,$ff ; SLASH
- db SFX_BATTLE_2C, $d8,$04 ; SUBSTITUTE
- db SFX_BATTLE_0B, $00,$80 ; STRUGGLE
- db SFX_BATTLE_0B, $00,$80
+ ; ID, pitch mod, tempo mod
+ db SFX_POUND, $00, $80 ; POUND
+ db SFX_BATTLE_0C, $10, $80 ; KARATE_CHOP
+ db SFX_DOUBLESLAP, $00, $80 ; DOUBLESLAP
+ db SFX_BATTLE_0B, $01, $80 ; COMET_PUNCH
+ db SFX_BATTLE_0D, $00, $40 ; MEGA_PUNCH
+ db SFX_SILPH_SCOPE, $00, $ff ; PAY_DAY
+ db SFX_BATTLE_0D, $10, $60 ; FIRE_PUNCH
+ db SFX_BATTLE_0D, $20, $80 ; ICE_PUNCH
+ db SFX_BATTLE_0D, $00, $a0 ; THUNDERPUNCH
+ db SFX_DAMAGE, $00, $80 ; SCRATCH
+ db SFX_BATTLE_0F, $20, $40 ; VICEGRIP
+ db SFX_BATTLE_0F, $00, $80 ; GUILLOTINE
+ db SFX_BATTLE_0E, $00, $a0 ; RAZOR_WIND
+ db SFX_NOT_VERY_EFFECTIVE, $10, $c0 ; SWORDS_DANCE
+ db SFX_NOT_VERY_EFFECTIVE, $00, $a0 ; CUT
+ db SFX_BATTLE_12, $00, $c0 ; GUST
+ db SFX_BATTLE_12, $10, $a0 ; WING_ATTACK
+ db SFX_BATTLE_13, $00, $e0 ; WHIRLWIND
+ db SFX_NOT_VERY_EFFECTIVE, $20, $c0 ; FLY
+ db SFX_BATTLE_14, $00, $80 ; BIND
+ db SFX_BATTLE_22, $00, $80 ; SLAM
+ db SFX_VINE_WHIP, $01, $80 ; VINE_WHIP
+ db SFX_BATTLE_20, $00, $80 ; STOMP
+ db SFX_BATTLE_17, $f0, $40 ; DOUBLE_KICK
+ db SFX_SUPER_EFFECTIVE, $00, $80 ; MEGA_KICK
+ db SFX_BATTLE_17, $00, $80 ; JUMP_KICK
+ db SFX_BATTLE_21, $10, $80 ; ROLLING_KICK
+ db SFX_BATTLE_1B, $01, $a0 ; SAND_ATTACK
+ db SFX_BATTLE_18, $00, $80 ; HEADBUTT
+ db SFX_BATTLE_1E, $00, $60 ; HORN_ATTACK
+ db SFX_BATTLE_1E, $01, $40 ; FURY_ATTACK
+ db SFX_HORN_DRILL, $00, $a0 ; HORN_DRILL
+ db SFX_SUPER_EFFECTIVE, $10, $a0 ; TACKLE
+ db SFX_BATTLE_20, $00, $c0 ; BODY_SLAM
+ db SFX_BATTLE_14, $10, $60 ; WRAP
+ db SFX_SUPER_EFFECTIVE, $00, $a0 ; TAKE_DOWN
+ db SFX_BATTLE_22, $11, $c0 ; THRASH
+ db SFX_SUPER_EFFECTIVE, $20, $c0 ; DOUBLE_EDGE
+ db SFX_BATTLE_21, $00, $80 ; TAIL_WHIP
+ db SFX_BATTLE_1B, $00, $80 ; POISON_STING
+ db SFX_BATTLE_1B, $20, $c0 ; TWINEEDLE
+ db SFX_BATTLE_19, $00, $80 ; PIN_MISSILE
+ db SFX_BATTLE_31, $ff, $40 ; LEER
+ db SFX_BATTLE_1E, $00, $80 ; BITE
+ db SFX_BATTLE_0B, $00, $c0 ; GROWL
+ db SFX_BATTLE_0B, $00, $40 ; ROAR
+ db SFX_BATTLE_35, $00, $80 ; SING
+ db SFX_BATTLE_27, $40, $60 ; SUPERSONIC
+ db SFX_BATTLE_27, $00, $80 ; SONICBOOM
+ db SFX_BATTLE_27, $ff, $40 ; DISABLE
+ db SFX_BATTLE_2A, $80, $c0 ; ACID
+ db SFX_BATTLE_19, $10, $a0 ; EMBER
+ db SFX_BATTLE_19, $21, $e0 ; FLAMETHROWER
+ db SFX_EARTHQUAKE, $00, $80 ; MIST
+ db SFX_BATTLE_24, $20, $60 ; WATER_GUN
+ db SFX_BATTLE_2A, $00, $80 ; HYDRO_PUMP
+ db SFX_BATTLE_2C, $00, $80 ; SURF
+ db SFX_BATTLE_28, $40, $80 ; ICE_BEAM
+ db SFX_EARTHQUAKE, $f0, $e0 ; BLIZZARD
+ db SFX_PSYBEAM, $00, $80 ; PSYBEAM
+ db SFX_BATTLE_2A, $f0, $60 ; BUBBLEBEAM
+ db SFX_BATTLE_28, $00, $80 ; AURORA_BEAM
+ db SFX_BATTLE_36, $00, $80 ; HYPER_BEAM
+ db SFX_PECK, $01, $a0 ; PECK
+ db SFX_BATTLE_13, $f0, $20 ; DRILL_PECK
+ db SFX_BATTLE_23, $01, $c0 ; SUBMISSION
+ db SFX_BATTLE_23, $00, $80 ; LOW_KICK
+ db SFX_SUPER_EFFECTIVE, $00, $e0 ; COUNTER
+ db SFX_BATTLE_26, $01, $60 ; SEISMIC_TOSS
+ db SFX_BATTLE_26, $20, $40 ; STRENGTH
+ db SFX_BATTLE_24, $00, $80 ; ABSORB
+ db SFX_BATTLE_24, $40, $c0 ; MEGA_DRAIN
+ db SFX_BATTLE_1B, $03, $60 ; LEECH_SEED
+ db SFX_BATTLE_25, $11, $e0 ; GROWTH
+ db SFX_BATTLE_12, $20, $e0 ; RAZOR_LEAF
+ db SFX_BATTLE_2E, $00, $80 ; SOLARBEAM
+ db SFX_BATTLE_1C, $00, $80 ; POISONPOWDER
+ db SFX_BATTLE_1C, $11, $a0 ; STUN_SPORE
+ db SFX_BATTLE_1C, $01, $c0 ; SLEEP_POWDER
+ db SFX_BATTLE_13, $14, $c0 ; PETAL_DANCE
+ db SFX_BATTLE_1B, $02, $a0 ; STRING_SHOT
+ db SFX_EARTHQUAKE, $f0, $80 ; DRAGON_RAGE
+ db SFX_EARTHQUAKE, $20, $c0 ; FIRE_SPIN
+ db SFX_THUNDERBOLT, $00, $20 ; THUNDERSHOCK
+ db SFX_THUNDERBOLT, $20, $80 ; THUNDERBOLT
+ db SFX_BATTLE_2E, $12, $60 ; THUNDER_WAVE
+ db SFX_BATTLE_26, $00, $80 ; THUNDER
+ db SFX_BATTLE_14, $01, $e0 ; ROCK_THROW
+ db SFX_EARTHQUAKE, $0f, $e0 ; EARTHQUAKE
+ db SFX_EARTHQUAKE, $11, $20 ; FISSURE
+ db SFX_DAMAGE, $10, $40 ; DIG
+ db SFX_BATTLE_0F, $10, $c0 ; TOXIC
+ db SFX_BATTLE_14, $00, $20 ; CONFUSION
+ db SFX_PSYCHIC_M, $00, $80 ; PSYCHIC_M
+ db SFX_BATTLE_35, $11, $18 ; HYPNOSIS
+ db SFX_BATTLE_09, $20, $c0 ; MEDITATE
+ db SFX_FAINT_FALL, $20, $c0 ; AGILITY
+ db SFX_BATTLE_25, $00, $10 ; QUICK_ATTACK
+ db SFX_BATTLE_26, $f0, $20 ; RAGE
+ db SFX_BATTLE_33, $f0, $c0 ; TELEPORT
+ db SFX_NOT_VERY_EFFECTIVE, $f0, $e0 ; NIGHT_SHADE
+ db SFX_BATTLE_09, $f0, $40 ; MIMIC
+ db SFX_BATTLE_31, $00, $80 ; SCREECH
+ db SFX_BATTLE_33, $80, $40 ; DOUBLE_TEAM
+ db SFX_BATTLE_33, $00, $80 ; RECOVER
+ db SFX_BATTLE_14, $11, $20 ; HARDEN
+ db SFX_BATTLE_14, $22, $10 ; MINIMIZE
+ db SFX_BATTLE_1B, $f1, $ff ; SMOKESCREEN
+ db SFX_BATTLE_13, $f1, $ff ; CONFUSE_RAY
+ db SFX_BATTLE_14, $33, $30 ; WITHDRAW
+ db SFX_BATTLE_32, $40, $c0 ; DEFENSE_CURL
+ db SFX_BATTLE_0E, $20, $20 ; BARRIER
+ db SFX_BATTLE_0E, $f0, $10 ; LIGHT_SCREEN
+ db SFX_BATTLE_0F, $f8, $10 ; HAZE
+ db SFX_NOT_VERY_EFFECTIVE, $f0, $10 ; REFLECT
+ db SFX_BATTLE_25, $00, $80 ; FOCUS_ENERGY
+ db SFX_BATTLE_18, $00, $c0 ; BIDE
+ db SFX_BATTLE_32, $c0, $ff ; METRONOME
+ db SFX_BATTLE_09, $f2, $20 ; MIRROR_MOVE
+ db SFX_BATTLE_34, $00, $80 ; SELFDESTRUCT
+ db SFX_BATTLE_34, $00, $40 ; EGG_BOMB
+ db SFX_BATTLE_09, $00, $40 ; LICK
+ db SFX_NOT_VERY_EFFECTIVE, $10, $ff ; SMOG
+ db SFX_BATTLE_2A, $20, $20 ; SLUDGE
+ db SFX_BATTLE_32, $00, $80 ; BONE_CLUB
+ db SFX_EARTHQUAKE, $1f, $20 ; FIRE_BLAST
+ db SFX_BATTLE_25, $2f, $80 ; WATERFALL
+ db SFX_BATTLE_0F, $1f, $ff ; CLAMP
+ db SFX_BATTLE_2B, $1f, $60 ; SWIFT
+ db SFX_BATTLE_26, $1e, $20 ; SKULL_BASH
+ db SFX_BATTLE_26, $1f, $18 ; SPIKE_CANNON
+ db SFX_BATTLE_14, $0f, $80 ; CONSTRICT
+ db SFX_BATTLE_09, $f8, $10 ; AMNESIA
+ db SFX_FAINT_FALL, $18, $20 ; KINESIS
+ db SFX_BATTLE_32, $08, $40 ; SOFTBOILED
+ db SFX_BATTLE_17, $01, $e0 ; HI_JUMP_KICK
+ db SFX_NOT_VERY_EFFECTIVE, $09, $ff ; GLARE
+ db SFX_BATTLE_35, $42, $01 ; DREAM_EATER
+ db SFX_BATTLE_1C, $00, $ff ; POISON_GAS
+ db SFX_BATTLE_32, $08, $e0 ; BARRAGE
+ db SFX_BATTLE_24, $00, $80 ; LEECH_LIFE
+ db SFX_BATTLE_09, $88, $10 ; LOVELY_KISS
+ db SFX_BATTLE_25, $48, $ff ; SKY_ATTACK
+ db SFX_FAINT_FALL, $ff, $ff ; TRANSFORM
+ db SFX_BATTLE_24, $ff, $10 ; BUBBLE
+ db SFX_FAINT_FALL, $ff, $04 ; DIZZY_PUNCH
+ db SFX_BATTLE_1C, $01, $ff ; SPORE
+ db SFX_BATTLE_13, $f8, $ff ; FLASH
+ db SFX_BATTLE_0C, $f0, $f0 ; PSYWAVE
+ db SFX_BATTLE_0F, $08, $10 ; SPLASH
+ db SFX_BATTLE_0D, $f0, $ff ; ACID_ARMOR
+ db SFX_SUPER_EFFECTIVE, $f0, $ff ; CRABHAMMER
+ db SFX_BATTLE_34, $10, $ff ; EXPLOSION
+ db SFX_BATTLE_0E, $f0, $20 ; FURY_SWIPES
+ db SFX_BATTLE_2B, $f0, $60 ; BONEMERANG
+ db SFX_BATTLE_21, $12, $10 ; REST
+ db SFX_BATTLE_36, $f0, $20 ; ROCK_SLIDE
+ db SFX_BATTLE_1E, $12, $ff ; HYPER_FANG
+ db SFX_BATTLE_31, $80, $04 ; SHARPEN
+ db SFX_BATTLE_33, $f0, $10 ; CONVERSION
+ db SFX_EARTHQUAKE, $f8, $ff ; TRI_ATTACK
+ db SFX_BATTLE_26, $f0, $ff ; SUPER_FANG
+ db SFX_NOT_VERY_EFFECTIVE, $01, $ff ; SLASH
+ db SFX_BATTLE_2C, $d8, $04 ; SUBSTITUTE
+ db SFX_BATTLE_0B, $00, $80 ; STRUGGLE
+ db SFX_BATTLE_0B, $00, $80
CopyPicTiles:
ld a, [H_WHOSETURN]
@@ -2586,112 +2758,108 @@ CopyTileIDs:
ret
TileIDListPointerTable:
- dw Unknown_79b24
- db $77
- dw Unknown_79b55
- db $57
- dw Unknown_79b78
- db $37
- dw Unknown_79b8d
- db $77
- dw Unknown_79bbe
- db $77
- dw Unknown_79bef
- db $77
- dw Unknown_79c20
- db $86
- dw Unknown_79c50
- db $3C
+ dw DownscaledMonTiles_7x7
+ dn 7, 7
+ dw DownscaledMonTiles_5x7
+ dn 5, 7
+ dw DownscaledMonTiles_3x7
+ dn 3, 7
+ dw DownscaledMonTiles_79ce9
+ dn 7, 7
+ dw DownscaledMonTiles_79d1a
+ dn 7, 7
+ dw DownscaledMonTiles_79d4b
+ dn 7, 7
+ dw DownscaledMonTiles_79d7c
+ dn 8, 6
+ dw DownscaledMonTiles_79dac
+ dn 3, 12
DownscaledMonTiles_5x5:
- db $31,$38,$46,$54,$5B
- db $32,$39,$47,$55,$5C
- db $34,$3B,$49,$57,$5E
- db $36,$3D,$4B,$59,$60
- db $37,$3E,$4C,$5A,$61
+ db $31, $38, $46, $54, $5B
+ db $32, $39, $47, $55, $5C
+ db $34, $3B, $49, $57, $5E
+ db $36, $3D, $4B, $59, $60
+ db $37, $3E, $4C, $5A, $61
DownscaledMonTiles_3x3:
- db $31,$46,$5B
- db $34,$49,$5E
- db $37,$4C,$61
-
-Unknown_79b24:
- db $00,$07,$0E,$15,$1C,$23,$2A
- db $01,$08,$0F,$16,$1D,$24,$2B
- db $02,$09,$10,$17,$1E,$25,$2C
- db $03,$0A,$11,$18,$1F,$26,$2D
- db $04,$0B,$12,$19,$20,$27,$2E
- db $05,$0C,$13,$1A,$21,$28,$2F
- db $06,$0D,$14,$1B,$22,$29,$30
-
-Unknown_79b55:
- db $00,$07,$0E,$15,$1C,$23,$2A
- db $01,$08,$0F,$16,$1D,$24,$2B
- db $03,$0A,$11,$18,$1F,$26,$2D
- db $04,$0B,$12,$19,$20,$27,$2E
- db $05,$0C,$13,$1A,$21,$28,$2F
-
-Unknown_79b78:
- db $00,$07,$0E,$15,$1C,$23,$2A
- db $02,$09,$10,$17,$1E,$25,$2C
- db $04,$0B,$12,$19,$20,$27,$2E
-
-Unknown_79b8d:
- db $00,$00,$00,$00,$00,$00,$00
- db $00,$00,$00,$00,$00,$19,$00
- db $02,$06,$0B,$10,$14,$1A,$00
- db $00,$07,$0C,$11,$15,$1B,$00
- db $03,$08,$0D,$12,$16,$1C,$00
- db $04,$09,$0E,$13,$17,$1D,$1F
- db $05,$0A,$0F,$01,$18,$1E,$20
-
-Unknown_79bbe:
- db $00,$00,$00,$30,$00,$37,$00
- db $00,$00,$2B,$31,$34,$38,$3D
- db $21,$26,$2C,$01,$35,$39,$3E
- db $22,$27,$2D,$32,$36,$01,$00
- db $23,$28,$2E,$33,$01,$3A,$00
- db $24,$29,$2F,$01,$01,$3B,$00
- db $25,$2A,$01,$01,$01,$3C,$00
-
-Unknown_79bef:
- db $00,$00,$00,$00,$00,$00,$00
- db $00,$00,$47,$4D,$00,$00,$00
- db $00,$00,$48,$4E,$52,$56,$5B
- db $3F,$43,$49,$4F,$53,$57,$5C
- db $40,$44,$4A,$50,$54,$58,$00
- db $41,$45,$4B,$51,$4C,$59,$5D
- db $42,$46,$4C,$4C,$55,$5A,$5E
-
-Unknown_79c20:
- db $31,$32,$32,$32,$32,$33
- db $34,$35,$36,$36,$37,$38
- db $34,$39,$3A,$3A,$3B,$38
- db $3C,$3D,$3E,$3E,$3F,$40
- db $41,$42,$43,$43,$44,$45
- db $46,$47,$43,$48,$49,$4A
- db $41,$43,$4B,$4C,$4D,$4E
- db $4F,$50,$50,$50,$51,$52
-
-Unknown_79c50:
- db $43,$55,$56,$53,$53,$53,$53,$53,$53,$53,$53,$53
- db $43,$57,$58,$54,$54,$54,$54,$54,$54,$54,$54,$54
- db $43,$59,$5A,$43,$43,$43,$43,$43,$43,$43,$43,$43
+ db $31, $46, $5B
+ db $34, $49, $5E
+ db $37, $4C, $61
+
+DownscaledMonTiles_7x7:
+ db $00, $07, $0E, $15, $1C, $23, $2A
+ db $01, $08, $0F, $16, $1D, $24, $2B
+ db $02, $09, $10, $17, $1E, $25, $2C
+ db $03, $0A, $11, $18, $1F, $26, $2D
+ db $04, $0B, $12, $19, $20, $27, $2E
+ db $05, $0C, $13, $1A, $21, $28, $2F
+ db $06, $0D, $14, $1B, $22, $29, $30
+
+DownscaledMonTiles_5x7:
+ db $00, $07, $0E, $15, $1C, $23, $2A
+ db $01, $08, $0F, $16, $1D, $24, $2B
+ db $03, $0A, $11, $18, $1F, $26, $2D
+ db $04, $0B, $12, $19, $20, $27, $2E
+ db $05, $0C, $13, $1A, $21, $28, $2F
+
+DownscaledMonTiles_3x7:
+ db $00, $07, $0E, $15, $1C, $23, $2A
+ db $02, $09, $10, $17, $1E, $25, $2C
+ db $04, $0B, $12, $19, $20, $27, $2E
+
+DownscaledMonTiles_79ce9:
+ db $00, $00, $00, $00, $00, $00, $00
+ db $00, $00, $00, $00, $00, $19, $00
+ db $02, $06, $0B, $10, $14, $1A, $00
+ db $00, $07, $0C, $11, $15, $1B, $00
+ db $03, $08, $0D, $12, $16, $1C, $00
+ db $04, $09, $0E, $13, $17, $1D, $1F
+ db $05, $0A, $0F, $01, $18, $1E, $20
+
+DownscaledMonTiles_79d1a:
+ db $00, $00, $00, $30, $00, $37, $00
+ db $00, $00, $2B, $31, $34, $38, $3D
+ db $21, $26, $2C, $01, $35, $39, $3E
+ db $22, $27, $2D, $32, $36, $01, $00
+ db $23, $28, $2E, $33, $01, $3A, $00
+ db $24, $29, $2F, $01, $01, $3B, $00
+ db $25, $2A, $01, $01, $01, $3C, $00
+
+DownscaledMonTiles_79d4b:
+ db $00, $00, $00, $00, $00, $00, $00
+ db $00, $00, $47, $4D, $00, $00, $00
+ db $00, $00, $48, $4E, $52, $56, $5B
+ db $3F, $43, $49, $4F, $53, $57, $5C
+ db $40, $44, $4A, $50, $54, $58, $00
+ db $41, $45, $4B, $51, $4C, $59, $5D
+ db $42, $46, $4C, $4C, $55, $5A, $5E
+
+DownscaledMonTiles_79d7c:
+ db $31, $32, $32, $32, $32, $33
+ db $34, $35, $36, $36, $37, $38
+ db $34, $39, $3A, $3A, $3B, $38
+ db $3C, $3D, $3E, $3E, $3F, $40
+ db $41, $42, $43, $43, $44, $45
+ db $46, $47, $43, $48, $49, $4A
+ db $41, $43, $4B, $4C, $4D, $4E
+ db $4F, $50, $50, $50, $51, $52
+
+DownscaledMonTiles_79dac:
+ db $43, $55, $56, $53, $53, $53, $53, $53, $53, $53, $53, $53
+ db $43, $57, $58, $54, $54, $54, $54, $54, $54, $54, $54, $54
+ db $43, $59, $5A, $43, $43, $43, $43, $43, $43, $43, $43, $43
AnimationLeavesFalling:
; Makes leaves float down from the top of the screen. This is used
; in Razor Leaf's animation.
- ld a, [rOBP0]
- push af
ld a, [wAnimPalette]
ld [rOBP0], a
+ call UpdateGBCPal_OBP0
ld d, $37 ; leaf tile
ld a, 3 ; number of leaves
ld [wNumFallingObjects], a
- call AnimationFallingObjects
- pop af
- ld [rOBP0], a
- ret
+ jp AnimationFallingObjects
AnimationPetalsFalling:
; Makes lots of petals fall down from the top of the screen. It's used in
@@ -2746,6 +2914,8 @@ FallingObjects_UpdateOAMEntry:
; movement byte.
ld hl, wOAMBuffer
add hl, de
+ ld a, $1
+ ld [wdef5], a
ld a, [hl]
inc a
inc a
@@ -2754,6 +2924,12 @@ FallingObjects_UpdateOAMEntry:
ld a, 160 ; if Y >= 112, put it off-screen
.next
ld [hli], a ; Y
+ cp 40
+ jr c, .asm_79e51
+ ld a, [wdef5]
+ inc a
+ ld [wdef5], a
+.asm_79e51
ld a, [wFallingObjectMovementByte]
ld b, a
ld de, FallingObjects_DeltaXs
@@ -2770,6 +2946,13 @@ FallingObjects_UpdateOAMEntry:
ld a, [de]
add [hl]
ld [hli], a ; X
+ cp 88
+ jr c, .asm_79e75
+ ld a, [wdef5]
+ add $2
+ and $3
+ ld [wdef5], a
+.asm_79e75
inc hl
xor a ; no horizontal flip
jr .next2
@@ -2779,9 +2962,19 @@ FallingObjects_UpdateOAMEntry:
ld a, [hl]
sub b
ld [hli], a ; X
+ cp 88
+ jr c, .asm_79e5c
+ ld a, [wdef5]
+ add $2
+ and $3
+ ld [wdef5], a
+.asm_79e5c
inc hl
ld a, (1 << OAM_X_FLIP)
.next2
+ ld b, a
+ ld a, [wdef5]
+ or b
ld [hl], a ; attribute
ret
@@ -2821,7 +3014,7 @@ FallingObjects_InitXCoords:
ret
FallingObjects_InitialXCoords:
- db $38,$40,$50,$60,$70,$88,$90,$56,$67,$4A,$77,$84,$98,$32,$22,$5C,$6C,$7D,$8E,$99
+ db $38, $40, $50, $60, $70, $88, $90, $56, $67, $4A, $77, $84, $98, $32, $22, $5C, $6C, $7D, $8E, $99
FallingObjects_InitMovementData:
ld hl, wFallingObjectsMovementData
@@ -2837,7 +3030,7 @@ FallingObjects_InitMovementData:
ret
FallingObjects_InitialMovementData:
- db $00,$84,$06,$81,$02,$88,$01,$83,$05,$89,$09,$80,$07,$87,$03,$82,$04,$85,$08,$86
+ db $00, $84, $06, $81, $02, $88, $01, $83, $05, $89, $09, $80, $07, $87, $03, $82, $04, $85, $08, $86
AnimationShakeEnemyHUD:
; Shakes the enemy HUD.
@@ -2866,6 +3059,14 @@ AnimationShakeEnemyHUD:
ld hl, vBGMap1 - $20 * 7
call BattleAnimCopyTileMapToVRAM
+; update BGMap attributes
+ ld a, [hGBC]
+ and a
+ jr z, .notGBC
+ ld c, 13
+ callba LoadBGMapAttributes
+.notGBC
+
; 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
@@ -2899,13 +3100,18 @@ AnimationShakeEnemyHUD:
ld [hWY], a
ld hl, vBGMap1
call BattleAnimCopyTileMapToVRAM
+; update BGMap attributes
+ ld a, [hGBC]
+ and a
+ jr z, .notGBC2
+ ld c, 11
+ callba LoadBGMapAttributes
+.notGBC2
xor a
ld [hWY], a
call SaveScreenTilesToBuffer1
ld hl, vBGMap0
call BattleAnimCopyTileMapToVRAM
- call ClearScreen
- call Delay3
call LoadScreenTilesFromBuffer1
ld hl, vBGMap1
jp BattleAnimCopyTileMapToVRAM
@@ -2950,60 +3156,60 @@ BattleAnimCopyTileMapToVRAM:
jp Delay3
TossBallAnimation:
- ld a,[wIsInBattle]
- cp a,2
- jr z,.BlockBall ; if in trainer battle, play different animation
- ld a,[wPokeBallAnimData]
- ld b,a
+ ld a, [wIsInBattle]
+ cp a, 2
+ jr z, .BlockBall ; if in trainer battle, play different animation
+ ld a, [wPokeBallAnimData]
+ ld b, a
; upper nybble: how many animations (from PokeBallAnimations) to play
; this will be 4 for successful capture, 6 for breakout
- and a,$F0
+ and a, $F0
swap a
- ld c,a
+ ld c, a
; lower nybble: number of shakes
; store these for later
- ld a,b
- and a,$F
- ld [wNumShakes],a
+ ld a, b
+ and a, $F
+ ld [wNumShakes], a
- ld hl,.PokeBallAnimations
+ ld hl, .PokeBallAnimations
; choose which toss animation to use
- ld a,[wcf91]
- cp a,POKE_BALL
- ld b,TOSS_ANIM
- jr z,.done
- cp a,GREAT_BALL
- ld b,GREATTOSS_ANIM
- jr z,.done
- ld b,ULTRATOSS_ANIM
+ ld a, [wcf91]
+ cp a, POKE_BALL
+ ld b, TOSS_ANIM
+ jr z, .done
+ cp a, GREAT_BALL
+ ld b, GREATTOSS_ANIM
+ jr z, .done
+ ld b, ULTRATOSS_ANIM
.done
- ld a,b
+ ld a, b
.PlayNextAnimation
- ld [wAnimationID],a
+ ld [wAnimationID], a
push bc
push hl
call PlayAnimation
pop hl
- ld a,[hli]
+ ld a, [hli]
pop bc
dec c
- jr nz,.PlayNextAnimation
+ jr nz, .PlayNextAnimation
ret
.PokeBallAnimations:
; sequence of animations that make up the Poké Ball toss
- db POOF_ANIM,HIDEPIC_ANIM,SHAKE_ANIM,POOF_ANIM,SHOWPIC_ANIM
+ db POOF_ANIM, HIDEPIC_ANIM, SHAKE_ANIM, POOF_ANIM, SHOWPIC_ANIM
-.BlockBall ; 5E55
- ld a,TOSS_ANIM
- ld [wAnimationID],a
+.BlockBall ; 79ff6 (1e:5ff6)
+ ld a, TOSS_ANIM
+ ld [wAnimationID], a
call PlayAnimation
- ld a,SFX_FAINT_THUD
+ ld a, SFX_FAINT_THUD
call PlaySound
- ld a,BLOCKBALL_ANIM
- ld [wAnimationID],a
+ ld a, BLOCKBALL_ANIM
+ ld [wAnimationID], a
jp PlayAnimation
PlayApplyingAttackSound:
diff --git a/engine/battle/bank3d_battle.asm b/engine/battle/bank3d_battle.asm
new file mode 100644
index 00000000..3719841f
--- /dev/null
+++ b/engine/battle/bank3d_battle.asm
@@ -0,0 +1,291 @@
+InitBattle:
+ ld a, [wCurOpponent]
+ and a
+ jr z, asm_f6003
+
+InitOpponent:
+ ld a, [wCurOpponent]
+ ld [wcf91], a
+ ld [wEnemyMonSpecies2], a
+ jr asm_f601d
+asm_f6003:
+ ld a, [wd732]
+ bit 1, a
+ jr z, .asm_f600f
+ ld a, [hJoyHeld]
+ bit 1, a ; B button pressed?
+ ret nz
+.asm_f600f
+ ld a, [wNumberOfNoRandomBattleStepsLeft]
+ and a
+ ret nz
+ callab TryDoWildEncounter
+ ret nz
+asm_f601d:
+ ld a, [wMapPalOffset]
+ push af
+ ld hl, wLetterPrintingDelayFlags
+ ld a, [hl]
+ push af
+ res 1, [hl]
+ call InitBattleVariables ; 3d:6236
+ ld a, [wEnemyMonSpecies2]
+ sub $c8
+ jp c, InitWildBattle
+ ld [wTrainerClass], a
+ call GetTrainerInformation
+ callab ReadTrainer
+ callab DoBattleTransitionAndInitBattleVariables
+ call _LoadTrainerPic ; 3d:615a
+ xor a
+ ld [wEnemyMonSpecies2], a
+ ld [$ffe1], a
+ dec a
+ ld [wAICount], a
+ coord hl, 12, 0
+ predef CopyUncompressedPicToTilemap
+ ld a, $ff
+ ld [wEnemyMonPartyPos], a
+ ld a, $2
+ ld [wIsInBattle], a
+
+ ; Is this a major story battle?
+ ld a,[wLoneAttackNo]
+ and a
+ jp z,InitBattle_Common
+ callabd_ModifyPikachuHappiness PIKAHAPPY_GYMLEADER ; useless since already in bank3d
+ jp InitBattle_Common
+
+InitWildBattle:
+ ld a, $1
+ ld [wIsInBattle], a
+ callab LoadEnemyMonData
+ callab DoBattleTransitionAndInitBattleVariables
+ ld a, [wCurOpponent]
+ cp MAROWAK
+ jr z, .isGhost
+ callab IsGhostBattle
+ jr nz, .isNoGhost
+.isGhost
+ ld hl, wMonHSpriteDim
+ ld a, $66
+ ld [hli], a ; write sprite dimensions
+ ld bc, GhostPic
+ ld a, c
+ ld [hli], a ; write front sprite pointer
+ ld [hl], b
+ ld hl, wEnemyMonNick ; set name to "GHOST"
+ ld a, "G"
+ ld [hli], a
+ ld a, "H"
+ ld [hli], a
+ ld a, "O"
+ ld [hli], a
+ ld a, "S"
+ ld [hli], a
+ ld a, "T"
+ ld [hli], a
+ ld [hl], "@"
+ ld a, [wcf91]
+ push af
+ ld a, MON_GHOST
+ ld [wcf91], a
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load ghost sprite
+ pop af
+ ld [wcf91], a
+ jr .spriteLoaded
+.isNoGhost
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load mon sprite
+.spriteLoaded
+ xor a
+ ld [wTrainerClass], a
+ ld [$ffe1], a
+ coord hl, 12, 0
+ predef CopyUncompressedPicToTilemap
+
+; common code that executes after init battle code specific to trainer or wild battles
+InitBattle_Common:
+ ld b, $0
+ call RunPaletteCommand
+ callab SlidePlayerAndEnemySilhouettesOnScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, .emptyString
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ call ClearScreen
+ ld a, $98
+ ld [$ffbd], a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld a, $9c
+ ld [$ffbd], a
+ call LoadScreenTilesFromBuffer1
+ coord hl, 9, 7
+ ld bc, $50a
+ call ClearScreenArea
+ coord hl, 1, 0
+ ld bc, $40a
+ call ClearScreenArea
+ call ClearSprites
+ ld a, [wIsInBattle]
+ dec a ; is it a wild battle?
+ ld hl, DrawEnemyHUDAndHPBar
+ ld b,BANK(DrawEnemyHUDAndHPBar)
+ call z, Bankswitch ; draw enemy HUD and HP bar if it's a wild battle
+ callab StartBattle
+ callab EndOfBattle
+ pop af
+ ld [wLetterPrintingDelayFlags], a
+ pop af
+ ld [wMapPalOffset], a
+ ld a, [wSavedTilesetType]
+ ld [hTilesetType], a
+ scf
+ ret
+.emptyString
+ db "@"
+
+_LoadTrainerPic:
+; wd033-wd034 contain pointer to pic
+ ld a, [wTrainerPicPointer] ; wd033
+ ld e, a
+ ld a, [wTrainerPicPointer + 1] ; wd034
+ ld d, a ; de contains pointer to trainer pic
+ ld a, [wLinkState]
+ and a
+ ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
+ jr z, .loadSprite
+ ld a, Bank(RedPicFront)
+.loadSprite
+ call UncompressSpriteFromDE
+ ld de, vFrontPic
+ ld a, $77
+ ld c, a
+ jp LoadUncompressedSpriteData
+
+LoadMonBackPic:
+; Assumes the monster's attributes have
+; been loaded with GetMonHeader.
+ ld a, [wBattleMonSpecies2]
+ ld [wcf91], a
+ coord hl, 1, 5
+ ld bc,$708
+ call ClearScreenArea
+ ld hl, wMonHBackSprite - wMonHeader
+ call UncompressMonSprite
+ predef ScaleSpriteByTwo
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
+ ld hl, vSprites
+ ld de, vBackPic
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+AnimateSendingOutMon:
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ ld l, a
+ ld a, [$ffe1]
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld b, $4c
+ ld a, [wIsInBattle]
+ and a
+ jr z, .asm_f61ef
+ add b
+ ld [hl], a
+ call Delay3
+ ld bc, -41
+ add hl, bc
+ ld a, $1
+ ld [wNumMovesMinusOne], a
+ ld bc, $303
+ predef CopyDownscaledMonTiles
+ ld c, $4
+ call DelayFrames
+ ld bc, -41
+ add hl, bc
+ xor a
+ ld [wNumMovesMinusOne], a
+ ld bc, $505
+ predef CopyDownscaledMonTiles
+ ld c, $5
+ call DelayFrames
+ ld bc, -41
+ jr .asm_f61f2
+.asm_f61ef
+ ld bc, -123
+.asm_f61f2
+ add hl, bc
+ ld a, [H_DOWNARROWBLINKCNT1]
+ add $31
+ jr CopyUncompressedPicToHL
+
+CopyUncompressedPicToTilemap:
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ ld l, a
+ ld a, [$ffe1]
+CopyUncompressedPicToHL:
+ ld bc, $707
+ ld de, $14
+ push af
+ ld a, [wSpriteFlipped]
+ and a
+ jr nz, .asm_f6220
+ pop af
+.asm_f6211
+ push bc
+ push hl
+.asm_f6213
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .asm_f6213
+ pop hl
+ inc hl
+ pop bc
+ dec b
+ jr nz, .asm_f6211
+ ret
+
+.asm_f6220
+ push bc
+ ld b, $0
+ dec c
+ add hl, bc
+ pop bc
+ pop af
+.asm_f6227
+ push bc
+ push hl
+.asm_f6229
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .asm_f6229
+ pop hl
+ dec hl
+ pop bc
+ dec b
+ jr nz, .asm_f6227
+ ret
+
+INCLUDE "engine/battle/init_battle_variables.asm"
+INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm"
+INCLUDE "engine/battle/moveEffects/heal_effect.asm"
+INCLUDE "engine/battle/moveEffects/transform_effect.asm"
+INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm"
+INCLUDE "engine/battle/moveEffects/mist_effect.asm"
+INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm"
+INCLUDE "engine/battle/moveEffects/pay_day_effect.asm"
+INCLUDE "engine/battle/moveEffects/paralyze_effect.asm"
diff --git a/engine/battle/bank_e_misc.asm b/engine/battle/bank_e_misc.asm
index 33af6f6f..df9145f2 100755
--- a/engine/battle/bank_e_misc.asm
+++ b/engine/battle/bank_e_misc.asm
@@ -101,22 +101,3 @@ InitList:
ld a, b
ld [wItemPrices + 1], a
ret
-
-; get species of mon e in list [wMonDataLocation] for LoadMonData
-GetMonSpecies:
- ld hl, wPartySpecies
- ld a, [wMonDataLocation]
- and a
- jr z, .getSpecies
- dec a
- jr z, .enemyParty
- ld hl, wBoxSpecies
- jr .getSpecies
-.enemyParty
- ld hl, wEnemyPartyMons
-.getSpecies
- ld d, 0
- add hl, de
- ld a, [hl]
- ld [wcf91], a
- ret
diff --git a/engine/battle/battle_transitions.asm b/engine/battle/battle_transitions.asm
index 9e02c56f..a4871837 100644
--- a/engine/battle/battle_transitions.asm
+++ b/engine/battle/battle_transitions.asm
@@ -1,5 +1,5 @@
BattleTransition:
- ld a, 1
+ ld a, $1
ld [H_AUTOBGTRANSFERENABLED], a
call Delay3
xor a
@@ -196,6 +196,9 @@ BattleTransition_BlackScreen:
ld [rBGP], a
ld [rOBP0], a
ld [rOBP1], a
+ call UpdateGBCPal_BGP
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
ret
; for non-dungeon trainer battles
@@ -359,7 +362,8 @@ BattleTransition_FlashScreen_:
cp $1
jr z, .done
ld [rBGP], a
- ld c, 2
+ call UpdateGBCPal_BGP
+ ld c, $2
call DelayFrames
jr .loop
.done
@@ -373,7 +377,7 @@ BattleTransition_FlashScreenPalettes:
; used for low level trainer dungeon battles
BattleTransition_Shrink:
- ld c, SCREEN_HEIGHT / 2
+ ld c,9
.loop
push bc
xor a
@@ -407,7 +411,7 @@ BattleTransition_Shrink:
; used for high level trainer dungeon battles
BattleTransition_Split:
- ld c, SCREEN_HEIGHT / 2
+ ld c,$9
xor a
ld [H_AUTOBGTRANSFERENABLED], a
.loop
@@ -628,7 +632,7 @@ BattleTransition_Circle_Sub1:
ret
BattleTransition_TransferDelay3:
- ld a, 1
+ ld a, $1
ld [H_AUTOBGTRANSFERENABLED], a
call Delay3
xor a
diff --git a/engine/battle/common_text.asm b/engine/battle/common_text.asm
index 3d46c947..02bb1a61 100644
--- a/engine/battle/common_text.asm
+++ b/engine/battle/common_text.asm
@@ -1,5 +1,5 @@
PrintBeginningBattleText:
- ld a, [wIsInBattle]
+ ld a, [wIsInBattle] ; W_ISINBATTLE
dec a
jr nz, .trainerBattle
ld a, [wCurMap]
@@ -8,8 +8,20 @@ PrintBeginningBattleText:
cp LAVENDER_HOUSE_1
jr c, .pokemonTower
.notPokemonTower
+ ld a,[wBattleType]
+ cp BATTLE_TYPE_PIKACHU
+ jr nz,.notPikachuBattle
+ callab IsPlayerPikachuAsleepInParty
+ ld e,$24
+ jr c,.asm_f4026
+ ld e,$a
+.asm_f4026
+ callab PlayPikachuSoundClip
+ jr .continue
+.notPikachuBattle
ld a, [wEnemyMonSpecies2]
call PlayCry
+.continue
ld hl, WildMonAppearedText
ld a, [wMoveMissed]
and a
@@ -23,9 +35,13 @@ PrintBeginningBattleText:
call DelayFrames
ld hl, TrainerWantsToFightText
.wildBattle
+ ld a, [wBattleType]
+ and a
+ jr nz, .doNotDrawPokeballs
push hl
callab DrawAllPokeballs
pop hl
+.doNotDrawPokeballs
call PrintText
jr .done
.pokemonTower
@@ -64,7 +80,7 @@ PrintBeginningBattleText:
ld [wFrequencyModifier], a
ld a, $80
ld [wTempoModifier], a
- ld a, SFX_SILPH_SCOPE
+ ld a, $e9 ; (SFX_08_77 - SFX_Headers_08) / 3
call PlaySound
jp WaitForSoundToFinish
.done
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index f8053a9e..fa56e5b2 100755
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -157,6 +157,9 @@ SlidePlayerAndEnemySilhouettesOnScreen:
ld [rBGP], a
ld [rOBP0], a
ld [rOBP1], a
+ call UpdateGBCPal_BGP
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen
ld h, b
ld l, $40
@@ -246,10 +249,16 @@ StartBattle:
call DelayFrames
call SaveScreenTilesToBuffer1
.checkAnyPartyAlive
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_RUN
+ jp z, .specialBattle
+ cp BATTLE_TYPE_PIKACHU
+ jp z, .specialBattle
call AnyPartyAlive
ld a, d
and a
jp z, HandlePlayerBlackOut ; jump if no mon is alive
+.specialBattle
call LoadScreenTilesFromBuffer1
ld a, [wBattleType]
and a ; is it a normal battle?
@@ -443,7 +452,7 @@ MainInBattleLoop:
; the link battle enemy has switched mons
ld a, [wPlayerBattleStatus1]
bit UsingTrappingMove, a ; check if using multi-turn move like Wrap
- jr z, .asm_3c2dd
+ jr z, .specialMoveNotUsed
ld a, [wPlayerMoveListIndex]
ld hl, wBattleMonMoves
ld c, a
@@ -452,9 +461,9 @@ MainInBattleLoop:
ld a, [hl]
cp METRONOME ; a MIRROR MOVE check is missing, might lead to a desync in link battles
; when combined with multi-turn moves
- jr nz, .asm_3c2dd
+ jr nz, .specialMoveNotUsed
ld [wPlayerSelectedMove], a
-.asm_3c2dd
+.specialMoveNotUsed
callab SwitchEnemyMon
.noLinkBattle
ld a, [wPlayerSelectedMove]
@@ -665,7 +674,7 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP:
and a
jr z, .playersTurn
ld hl, wEnemyBattleStatus3
- ld de, wEnemyToxcCounter
+ ld de, wEnemyToxicCounter
.playersTurn
bit BadlyPoisoned, [hl]
jr z, .noToxic
@@ -819,7 +828,7 @@ HandleEnemyMonFainted:
ld [wActionResultOrTookBattleTurn], a
jp MainInBattleLoop
-FaintEnemyPokemon: ; 0x3c567
+FaintEnemyPokemon:
call ReadPlayerMonCurHPAndStatus
ld a, [wIsInBattle]
dec a
@@ -884,6 +893,8 @@ FaintEnemyPokemon: ; 0x3c567
ld a, MUSIC_DEFEATED_WILD_MON
call PlayBattleVictoryMusic
.sfxplayed
+; bug: win sfx is played for wild battles before checking for player mon HP
+; this can lead to odd scenarios where both player and enemy faint, as the win sfx plays yet the player never won the battle
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
@@ -945,7 +956,7 @@ FaintEnemyPokemon: ; 0x3c567
ld [wPartyGainExpFlags], a
jpab GainExperience
-EnemyMonFaintedText: ; 0x3c63e
+EnemyMonFaintedText:
TX_FAR _EnemyMonFaintedText
db "@"
@@ -981,6 +992,11 @@ ReplaceFaintedEnemyMon:
ld hl, wEnemyHPBarColor
ld e, $30
call GetBattleHealthBarColor
+ setpal SHADE_BLACK, SHADE_DARK, SHADE_LIGHT, SHADE_WHITE
+ ld [rOBP0], a
+ ld [rOBP1], a
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
callab DrawEnemyPokeballs
ld a, [wLinkState]
cp LINK_STATE_BATTLING
@@ -1046,9 +1062,7 @@ TrainerDefeatedText:
PlayBattleVictoryMusic:
push af
- ld a, $ff
- ld [wNewSoundID], a
- call PlaySoundWaitForCurrent
+ call StopAllMusic
ld c, BANK(Music_DefeatedTrainer)
pop af
call PlayMusic
@@ -1102,6 +1116,7 @@ RemoveFaintedPlayerMon:
ld a, $ff
ld [wLowHealthAlarm], a ;disable low health alarm
call WaitForSoundToFinish
+ xor a
.skipWaitForSound
; a is 0, so this zeroes the enemy's accumulated damage.
ld hl, wEnemyBideAccumulatedDamage
@@ -1126,10 +1141,36 @@ RemoveFaintedPlayerMon:
and a ; was this called by HandleEnemyMonFainted?
ret z ; if so, return
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ callab IsThisPartymonStarterPikachu_Party
+ jr nc, .notPlayerPikachu
+ ld e, $3
+ callab PlayPikachuSoundClip
+ jr .printText
+.notPlayerPikachu
ld a, [wBattleMonSpecies]
call PlayCry
+.printText
ld hl, PlayerMonFaintedText
- jp PrintText
+ call PrintText
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [wEnemyMonLevel]
+ sub b ; enemylevel - playerlevel
+ ; are we stronger than the opposing pokemon?
+ jr c, .regularFaint ; if so, deduct happiness regularly
+
+ cp 30 ; is the enemy 30 levels greater than us?
+ jr nc, .carelessTrainer ; if so, punish the player for being careless, as they shouldn't be fighting a very high leveled trainer with such a level difference
+.regularFaint
+ callabd_ModifyPikachuHappiness PIKAHAPPY_FAINTED
+ ret
+.carelessTrainer
+ callabd_ModifyPikachuHappiness PIKAHAPPY_CARELESSTRAINER
+ ret
PlayerMonFaintedText:
TX_FAR _PlayerMonFaintedText
@@ -1186,7 +1227,7 @@ ChooseNextMon:
ld a, [wLinkState]
cp LINK_STATE_BATTLING
jr nz, .notLinkBattle
- inc a
+ ld a, $1
ld [wActionResultOrTookBattleTurn], a
call LinkBattleExchangeData
.notLinkBattle
@@ -1285,7 +1326,7 @@ SlideDownFaintedMonPic:
call CopyData
pop de
pop hl
- ld bc, -20
+ ld bc, -SCREEN_WIDTH
add hl, bc
push hl
ld h, d
@@ -1297,7 +1338,7 @@ SlideDownFaintedMonPic:
pop bc
dec b
jr nz, .rowLoop
- ld bc, 20
+ ld bc, SCREEN_WIDTH
add hl, bc
ld de, SevenSpacesText
call PlaceString
@@ -1586,6 +1627,8 @@ TryRunningFromBattle:
ld a, [wBattleType]
cp BATTLE_TYPE_SAFARI
jp z, .canEscape ; jump if it's a safari battle
+ cp BATTLE_TYPE_RUN
+ jp z, .canEscape ; hurry, get away?
ld a, [wLinkState]
cp LINK_STATE_BATTLING
jp z, .canEscape
@@ -1841,19 +1884,46 @@ SendOutMon:
call RunPaletteCommand
ld hl, wEnemyBattleStatus1
res UsingTrappingMove, [hl]
+ callab IsThisPartymonStarterPikachu
+ jr c, .starterPikachu
ld a, $1
ld [H_WHOSETURN], a
ld a, POOF_ANIM
call PlayMoveAnimation
coord hl, 4, 11
predef AnimateSendingOutMon
+ jr .playRegularCry
+.starterPikachu
+ xor a
+ ld [H_WHOSETURN], a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ callab StarterPikachuBattleEntranceAnimation
+ callab IsPlayerPikachuAsleepInParty
+ ld e, $24
+ jr c, .asm_3cd81
+ ld e, $a
+.asm_3cd81
+ callab PlayPikachuSoundClip
+ jr .done
+.playRegularCry
ld a, [wcf91]
call PlayCry
+.done
call PrintEmptyString
jp SaveScreenTilesToBuffer1
; show 2 stages of the player mon getting smaller before disappearing
AnimateRetreatingPlayerMon:
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ callab IsThisPartymonStarterPikachu
+ pop bc
+ ld a, b
+ ld [wWhichPokemon], a
+ jr c, .starterPikachu
coord hl, 1, 5
lb bc, 7, 7
call ClearScreenArea
@@ -1877,10 +1947,17 @@ AnimateRetreatingPlayerMon:
call .clearScreenArea
ld a, $4c
Coorda 5, 11
+ jr .clearScreenArea
+.starterPikachu
+ xor a
+ ld [H_WHOSETURN], a
+ callab AnimationSlideMonOff
+ ret
.clearScreenArea
coord hl, 1, 5
lb bc, 7, 7
- jp ClearScreenArea
+ call ClearScreenArea ; jp
+ ret
; reads player's current mon's HP into wBattleMonHP
ReadPlayerMonCurHPAndStatus:
@@ -1925,9 +2002,9 @@ DrawPlayerHUDAndHPBar:
ld de, wLoadedMonStatus
call PrintStatusConditionNotFainted
pop hl
- jr nz, .asm_3cdae
+ jr nz, .doNotPrintLevel
call PrintLevel
-.asm_3cdae
+.doNotPrintLevel
ld a, [wLoadedMonSpecies]
ld [wcf91], a
coord hl, 10, 9
@@ -1939,14 +2016,14 @@ DrawPlayerHUDAndHPBar:
ld hl, wBattleMonHP
ld a, [hli]
or [hl]
- jr z, .asm_3cdd9
+ jr z, .fainted
ld a, [wLowHealthAlarmDisabled]
and a ; has the alarm been disabled because the player has already won?
ret nz ; if so, return
ld a, [wPlayerHPBarColor]
cp HP_BAR_RED
- jr z, .asm_3cde6
-.asm_3cdd9
+ jr z, .setLowHealthAlarm
+.fainted
ld hl, wLowHealthAlarm
bit 7, [hl] ;low health alarm enabled?
ld [hl], $0
@@ -1954,7 +2031,7 @@ DrawPlayerHUDAndHPBar:
xor a
ld [wChannelSoundIDs + CH4], a
ret
-.asm_3cde6
+.setLowHealthAlarm
ld hl, wLowHealthAlarm
set 7, [hl] ;enable low health alarm
ret
@@ -2102,36 +2179,49 @@ DisplayBattleMenu:
ld [wTextBoxID], a
call DisplayTextBoxID
ld a, [wBattleType]
- dec a
- jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial
-; the following happens for the old man tutorial
+ cp BATTLE_TYPE_OLD_MAN
+ jr z, .doSimulatedMenuInput ; simulate menu input if it's the old man or prof. oak pikachu battle
+ cp BATTLE_TYPE_PIKACHU
+ jr z, .doSimulatedMenuInput
+ jp .handleBattleMenuInput
+; the following happens for the old man tutorial and prof. oak pikachu battle
+.doSimulatedMenuInput
ld hl, wPlayerName
ld de, wGrassRate
ld bc, NAME_LENGTH
call CopyData ; temporarily save the player name in unused space,
; which is supposed to get overwritten when entering a
- ; map with wild Pokémon. Due to an oversight, the data
+ ; map with wild Pokémon.
+ ; In Red/Blue, due to an oversight, the data
; may not get overwritten (cinnabar) and the infamous
- ; Missingno. glitch can show up.
+ ; Missingno. glitch can show up. However,
+ ; this has been fixed in yellow
ld hl, .oldManName
+ ld a, [wBattleType]
+ dec a
+ jr z, .useOldManName
+ ld hl, .profOakName
+.useOldManName
ld de, wPlayerName
ld bc, NAME_LENGTH
call CopyData
; the following simulates the keystrokes by drawing menus on screen
coord hl, 9, 14
ld [hl], "▶"
- ld c, 80
+ ld c, 20
call DelayFrames
ld [hl], " "
coord hl, 9, 16
ld [hl], "▶"
- ld c, 50
+ ld c, 20
call DelayFrames
ld [hl], $ec
ld a, $2 ; select the "ITEM" menu
jp .upperLeftMenuItemWasNotSelected
.oldManName
db "OLD MAN@"
+.profOakName
+ db "PROF.OAK@"
.handleBattleMenuInput
ld a, [wBattleAndStartSavedMenuItem]
ld [wCurrentMenuItem], a
@@ -2214,6 +2304,9 @@ DisplayBattleMenu:
.AButtonPressed
call PlaceUnfilledArrowMenuCursor
ld a, [wBattleType]
+ cp BATTLE_TYPE_RUN
+ jr z, .handleUnusedBattle
+ ld a, [wBattleType]
cp BATTLE_TYPE_SAFARI
ld a, [wCurrentMenuItem]
ld [wBattleAndStartSavedMenuItem], a
@@ -2245,7 +2338,18 @@ DisplayBattleMenu:
.throwSafariBallWasSelected
ld a, SAFARI_BALL
ld [wcf91], a
- jr UseBagItem
+ jp UseBagItem
+.handleUnusedBattle
+ ld a, [wCurrentMenuItem]
+ cp $3
+ jp z, BattleMenu_RunWasSelected
+ ld hl, .RunAwayText
+ call PrintText
+ jp DisplayBattleMenu
+
+.RunAwayText ; 3d0df (f:50df)
+ TX_FAR _RunAwayText
+ db "@"
.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
cp $2
@@ -2282,19 +2386,23 @@ BagWasSelected:
call DrawHUDsAndHPBars
.next
ld a, [wBattleType]
- dec a ; is it the old man tutorial?
- jr nz, DisplayPlayerBag ; no, it is a normal battle
- ld hl, OldManItemList
+ cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial?
+ jr z, .simulatedInputBattle
+ cp BATTLE_TYPE_PIKACHU ; is it the prof oak battle with pikachu?
+ jr z, .simulatedInputBattle
+ jr DisplayPlayerBag
+.simulatedInputBattle
+ ld hl, SimulatedInputBattleItemList
ld a, l
ld [wListPointer], a
ld a, h
ld [wListPointer + 1], a
jr DisplayBagMenu
-OldManItemList:
- db 1 ; # items
- db POKE_BALL, 50
- db -1
+SimulatedInputBattleItemList:
+ db 1 ; # of items
+ db POKE_BALL, 1
+ db $ff
DisplayPlayerBag:
; get the pointer to player's bag when in a normal battle
@@ -2453,6 +2561,8 @@ PartyMenuOrRockOrRun:
predef StatusScreen
predef StatusScreen2
; now we need to reload the enemy mon pic
+ ld a, $1
+ ld [H_WHOSETURN], a
ld a, [wEnemyBattleStatus2]
bit HasSubstituteUp, a ; does the enemy mon have a substitute?
ld hl, AnimationSubstitute
@@ -2557,13 +2667,13 @@ MoveSelectionMenu:
.writemoves
ld de, wMovesString
- ld a, [hFlags_0xFFF6]
+ ld a, [hFlags_0xFFFA]
set 2, a
- ld [hFlags_0xFFF6], a
+ ld [hFlags_0xFFFA], a
call PlaceString
- ld a, [hFlags_0xFFF6]
+ ld a, [hFlags_0xFFFA]
res 2, a
- ld [hFlags_0xFFF6], a
+ ld [hFlags_0xFFFA], a
ret
.regularmenu
@@ -2572,9 +2682,9 @@ MoveSelectionMenu:
ld hl, wBattleMonMoves
call .loadmoves
coord hl, 4, 12
- ld b, $4
- ld c, $e
- di
+ lb bc, 4, 14
+ di ; out of pure coincidence, it is possible for vblank to occur between the di and ei
+ ; so it is necessary to put the di ei block to not cause tearing
call TextBoxBorder
coord hl, 4, 12
ld [hl], $7a
@@ -2590,8 +2700,7 @@ MoveSelectionMenu:
ld hl, wEnemyMonMoves
call .loadmoves
coord hl, 0, 7
- ld b, $4
- ld c, $e
+ lb bc, 4, 14
call TextBoxBorder
coord hl, 2, 8
call .writemoves
@@ -2605,8 +2714,7 @@ MoveSelectionMenu:
call AddNTimes
call .loadmoves
coord hl, 4, 7
- ld b, $4
- ld c, $e
+ lb bc, 4, 14
call TextBoxBorder
coord hl, 6, 8
call .writemoves
@@ -2620,8 +2728,6 @@ MoveSelectionMenu:
ld a, [wMoveMenuType]
cp $1
jr z, .selectedmoveknown
- ld a, $1
- jr nc, .selectedmoveknown
ld a, [wPlayerMoveListIndex]
inc a
.selectedmoveknown
@@ -2682,15 +2788,15 @@ SelectMenuItem:
call AddNTimes
ld [hl], $ec
.select
- ld hl, hFlags_0xFFF6
+ ld hl, hFlags_0xFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFF6
+ ld hl, hFlags_0xFFFA
res 1, [hl]
bit 6, a
- jp nz, CursorUp ; up
+ jp nz, SelectMenuItem_CursorUp ; up
bit 7, a
- jp nz, CursorDown ; down
+ jp nz, SelectMenuItem_CursorDown ; down
bit 2, a
jp nz, SwapMovesInMenu ; select
bit 1, a ; B, but was it reset above?
@@ -2703,10 +2809,10 @@ SelectMenuItem:
ld b, a
ld a, [wMoveMenuType]
dec a ; if not mimic
- jr nz, .nob
+ jr nz, .notB
pop af
ret
-.nob
+.notB
dec a
ld a, b
ld [wPlayerMoveListIndex], a
@@ -2723,7 +2829,7 @@ SelectMenuItem:
add hl, bc
ld a, [hl]
and $3f
- jr z, .nopp
+ jr z, .noPP
ld a, [wPlayerDisabledMove]
swap a
and $f
@@ -2746,7 +2852,7 @@ SelectMenuItem:
.disabled
ld hl, MoveDisabledText
jr .print
-.nopp
+.noPP
ld hl, MoveNoPPText
.print
call PrintText
@@ -2764,7 +2870,7 @@ MoveDisabledText:
WhichTechniqueString:
db "WHICH TECHNIQUE?@"
-CursorUp:
+SelectMenuItem_CursorUp:
ld a, [wCurrentMenuItem]
and a
jp nz, SelectMenuItem
@@ -2774,7 +2880,7 @@ CursorUp:
ld [wCurrentMenuItem], a
jp SelectMenuItem
-CursorDown:
+SelectMenuItem_CursorDown:
ld a, [wCurrentMenuItem]
ld b, a
ld a, [wNumMovesMinusOne]
@@ -2787,6 +2893,55 @@ CursorDown:
ld [wCurrentMenuItem], a
jp SelectMenuItem
+Func_3d4f5:
+ bit 3, a
+ ld a, $0
+ jr nz, .asm_3d4fd
+ ld a, $1
+.asm_3d4fd
+ ld [H_WHOSETURN], a
+ call LoadScreenTilesFromBuffer1
+ call Func_3d536
+ ld a, [wTestBattlePlayerSelectedMove]
+ and a
+ jp z, MoveSelectionMenu
+ ld [wAnimationID], a
+ xor a
+ ld [wAnimationType], a
+ predef MoveAnimation
+ callab Func_78e98
+ jp MoveSelectionMenu
+
+Func_3d523:
+ ld a, [wTestBattlePlayerSelectedMove]
+ dec a
+ jr asm_3d52d
+Func_3d529:
+ ld a, [wTestBattlePlayerSelectedMove]
+ inc a
+asm_3d52d:
+ ld [wTestBattlePlayerSelectedMove], a
+ call Func_3d536
+ jp MoveSelectionMenu
+
+Func_3d536:
+ coord hl, 10, 16
+ lb bc, 2, 10
+ call ClearScreenArea
+ coord hl, 10, 17
+ ld de, wTestBattlePlayerSelectedMove
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber
+ ld a, [wTestBattlePlayerSelectedMove]
+ and a
+ ret z
+ cp STRUGGLE
+ ret nc
+ ld [wd11e], a
+ call GetMoveName
+ coord hl, 13, 17
+ jp PlaceString
+
AnyMoveToSelect:
; return z and Struggle as the selected move if all moves have 0 PP and/or are disabled
ld a, STRUGGLE
@@ -2794,7 +2949,7 @@ AnyMoveToSelect:
ld a, [wPlayerDisabledMove]
and a
ld hl, wBattleMonPP
- jr nz, .asm_3d40e
+ jr nz, .handleDisabledMove
ld a, [hli]
or [hl]
inc hl
@@ -2803,26 +2958,29 @@ AnyMoveToSelect:
or [hl]
and $3f
ret nz
- jr .asm_3d423
-.asm_3d40e
+ jr .noMovesLeft
+.handleDisabledMove
swap a
- and $f
+ and $f ; get move disabled
ld b, a
- ld d, $5
+ ld d, NUM_MOVES + 1
xor a
-.asm_3d416
+.handleDisabledMovePPLoop
dec d
- jr z, .asm_3d421
- ld c, [hl]
+ jr z, .allMovesChecked
+ ld c, [hl] ; get move PP
inc hl
- dec b
- jr z, .asm_3d416
+ dec b ; is this the disabled move?
+ jr z, .handleDisabledMovePPLoop ; if so, ignore its PP value
or c
- jr .asm_3d416
-.asm_3d421
- and a
- ret nz
-.asm_3d423
+ jr .handleDisabledMovePPLoop
+.allMovesChecked
+; bugfix: only check PP value and not PP up bits
+; in case all other moves have no PP left and a move has a PP up used on it
+; and a non-PP up move is disabled
+ and $3f ; any PP left?
+ ret nz ; return if a move has PP left
+.noMovesLeft
ld hl, NoMovesLeftText
call PrintText
ld c, 60
@@ -2835,6 +2993,9 @@ NoMovesLeftText:
db "@"
SwapMovesInMenu:
+ ld a, [wPlayerBattleStatus3]
+ bit Transformed, a
+ jp nz, MoveSelectionMenu
ld a, [wMenuItemToSwap]
and a
jr z, .noMenuItemSelected
@@ -2914,8 +3075,7 @@ PrintMenuItem:
xor a
ld [H_AUTOBGTRANSFERENABLED], a
coord hl, 0, 8
- ld b, $3
- ld c, $9
+ lb bc, 3, 9
call TextBoxBorder
ld a, [wPlayerDisabledMove]
and a
@@ -2982,7 +3142,7 @@ PrintMenuItem:
jp Delay3
DisabledText:
- db "disabled!@"
+ db "Disabled!@"
TypeText:
db "TYPE@"
@@ -2997,7 +3157,7 @@ SelectEnemyMove:
call LoadScreenTilesFromBuffer1
ld a, [wSerialExchangeNybbleReceiveData]
cp $e
- jp z, .asm_3d601
+ jp z, .linkedOpponentUsedStruggle
cp $d
jr z, .unableToSelectMove
cp $4
@@ -3075,7 +3235,7 @@ SelectEnemyMove:
.done
ld [wEnemySelectedMove], a
ret
-.asm_3d601
+.linkedOpponentUsedStruggle
ld a, STRUGGLE
jr .done
@@ -3205,7 +3365,7 @@ PlayerCalcMoveDamage:
call RandomizeDamage
.moveHitTest
call MoveHitTest
-handleIfPlayerMoveMissed
+handleIfPlayerMoveMissed:
ld a,[wMoveMissed]
and a
jr z,getPlayerAnimationType
@@ -3213,13 +3373,13 @@ handleIfPlayerMoveMissed
sub a,EXPLODE_EFFECT
jr z,playPlayerMoveAnimation ; don't play any animation if the move missed, unless it was EXPLODE_EFFECT
jr playerCheckIfFlyOrChargeEffect
-getPlayerAnimationType
+getPlayerAnimationType:
ld a,[wPlayerMoveEffect]
and a
ld a,4 ; move has no effect other than dealing damage
jr z,playPlayerMoveAnimation
ld a,5 ; move has effect
-playPlayerMoveAnimation
+playPlayerMoveAnimation ; 3d890 (f:5890)
push af
ld a,[wPlayerBattleStatus2]
bit HasSubstituteUp,a
@@ -3238,7 +3398,7 @@ playPlayerMoveAnimation
ld b,BANK(ReshowSubstituteAnim)
call nz,Bankswitch
jr MirrorMoveCheck
-playerCheckIfFlyOrChargeEffect
+playerCheckIfFlyOrChargeEffect ; 3d8bd (f:58bd)
ld c,30
call DelayFrames
ld a,[wPlayerMoveEffect]
@@ -3252,7 +3412,7 @@ playerCheckIfFlyOrChargeEffect
ld [wAnimationType],a
ld a,STATUS_AFFECTED_ANIM
call PlayMoveAnimation
-MirrorMoveCheck
+MirrorMoveCheck:
ld a,[wPlayerMoveEffect]
cp a,MIRROR_MOVE_EFFECT
jr nz,.metronomeCheck
@@ -3785,10 +3945,10 @@ MonName1Text:
and a
ld a, [wPlayerMoveNum]
ld hl, wPlayerUsedMove
- jr z, .asm_3db11
+ jr z, .playerTurn
ld a, [wEnemyMoveNum]
ld hl, wEnemyUsedMove
-.asm_3db11
+.playerTurn
ld [hl], a
ld [wd11e], a
call DetermineExclamationPointTextNum
@@ -3902,11 +4062,13 @@ DetermineExclamationPointTextNum:
ret
ExclamationPointMoveSets:
+; a grammar mistake was fixed (only concerning japanese)
+; BIDE is in category 3, moved from category 2
db SWORDS_DANCE, GROWTH
db $00
- db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
+ db RECOVER, SELFDESTRUCT, AMNESIA
db $00
- db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
+ db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BIDE, BARRAGE
db $00
db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
@@ -3943,7 +4105,7 @@ PrintMoveFailureText:
ret nz
; if you get here, the mon used jump kick or hi jump kick and missed
- ld hl, wDamage ; since the move missed, wDamage will always contain 0 at this point.
+ ld hl, wDamage ; since the move missed, W_DAMAGE will always contain 0 at this point.
; Thus, recoil damage will always be equal to 1
; even if it was intended to be potential damage/8.
ld a, [hli]
@@ -4590,31 +4752,31 @@ CalculateDamage:
ld a, [H_QUOTIENT + 3]
add b
ld [H_QUOTIENT + 3], a
- jr nc, .asm_3dfd0
+ jr nc, .asm_3e142
ld a, [H_QUOTIENT + 2]
inc a
ld [H_QUOTIENT + 2], a
and a
- jr z, .asm_3e004
+ jr z, .asm_3e176
-.asm_3dfd0
+.asm_3e142
ld a, [H_QUOTIENT]
ld b, a
ld a, [H_QUOTIENT + 1]
or a
- jr nz, .asm_3e004
+ jr nz, .asm_3e176
ld a, [H_QUOTIENT + 2]
cp 998 / $100
- jr c, .asm_3dfe8
+ jr c, .asm_3e15a
cp 998 / $100 + 1
- jr nc, .asm_3e004
+ jr nc, .asm_3e176
ld a, [H_QUOTIENT + 3]
cp 998 % $100
- jr nc, .asm_3e004
+ jr nc, .asm_3e176
-.asm_3dfe8
+.asm_3e15a
inc hl
ld a, [H_QUOTIENT + 3]
ld b, [hl]
@@ -4625,26 +4787,26 @@ CalculateDamage:
ld b, [hl]
adc b
ld [hl], a
- jr c, .asm_3e004
+ jr c, .asm_3e176
ld a, [hl]
cp 998 / $100
- jr c, .asm_3e00a
+ jr c, .asm_3e17c
cp 998 / $100 + 1
- jr nc, .asm_3e004
+ jr nc, .asm_3e176
inc hl
ld a, [hld]
cp 998 % $100
- jr c, .asm_3e00a
+ jr c, .asm_3e17c
-.asm_3e004
+.asm_3e176
; cap at 997
ld a, 997 / $100
ld [hli], a
ld a, 997 % $100
ld [hld], a
-.asm_3e00a
+.asm_3e17c
; add 2
inc hl
ld a, [hl]
@@ -4675,7 +4837,7 @@ UnusedHighCriticalMoves:
; 3e023
; determines if attack is a critical hit
-; azure heights claims "the fastest pokémon (who are,not coincidentally,
+; azure heights claims "the fastest pokémon (who are, not coincidentally,
; among the most popular) tend to CH about 20 to 25% of the time."
CriticalHitTest:
xor a
@@ -4683,9 +4845,9 @@ CriticalHitTest:
ld a, [H_WHOSETURN]
and a
ld a, [wEnemyMonSpecies]
- jr nz, .asm_3e032
+ jr nz, .handleEnemy
ld a, [wBattleMonSpecies]
-.asm_3e032
+.handleEnemy
ld [wd0b5], a
call GetMonHeader
ld a, [wMonHBaseSpeed]
@@ -5052,7 +5214,7 @@ ApplyDamageToPlayerPokemon:
ld a,$01
ld [wHPBarType],a
predef UpdateHPBar2 ; animate the HP bar shortening
-ApplyAttackToPlayerPokemonDone
+ApplyAttackToPlayerPokemonDone:
jp DrawHUDsAndHPBars
AttackSubstitute:
@@ -5096,7 +5258,7 @@ AttackSubstitute:
ld a,[H_WHOSETURN]
xor a,$01
ld [H_WHOSETURN],a
- callab HideSubstituteShowMonAnim ; animate the substitute breaking
+ callab Func_79929 ; animate the substitute breaking
; flip the turn back to the way it was
ld a,[H_WHOSETURN]
xor a,$01
@@ -5393,32 +5555,26 @@ AdjustDamageForMoveType:
.done
ret
-; function to tell how effective the type of an enemy attack is on the player's current pokemon
-; this doesn't take into account the effects that dual types can have
-; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
-; the result is stored in [wTypeEffectiveness]
-; ($05 is not very effective, $10 is neutral, $14 is super effective)
-; as far is can tell, this is only used once in some AI code to help decide which move to use
AIGetTypeEffectiveness:
ld a,[wEnemyMoveType]
- ld d,a ; d = type of enemy move
+ ld d,a ; d = type of enemy move
ld hl,wBattleMonType
- ld b,[hl] ; b = type 1 of player's pokemon
+ ld b,[hl] ; b = type 1 of player's pokemon
inc hl
- ld c,[hl] ; c = type 2 of player's pokemon
+ ld c,[hl] ; c = type 2 of player's pokemon
ld a,$10
- ld [wTypeEffectiveness],a ; initialize to neutral effectiveness
+ ld [wd11e],a ; initialize [wd11e] to neutral effectiveness
ld hl,TypeEffects
.loop
ld a,[hli]
cp a,$ff
ret z
- cp d ; match the type of the move
+ cp d ; match the type of the move
jr nz,.nextTypePair1
ld a,[hli]
- cp b ; match with type 1 of pokemon
+ cp b ; match with type 1 of pokemon
jr z,.done
- cp c ; or match with type 2 of pokemon
+ cp c ; or match with type 2 of pokemon
jr z,.done
jr .nextTypePair2
.nextTypePair1
@@ -5426,9 +5582,21 @@ AIGetTypeEffectiveness:
.nextTypePair2
inc hl
jr .loop
+
.done
+ ld a, [wTrainerClass]
+ cp LORELEI
+ jr nz, .ok
+ ld a, [wEnemyMonSpecies]
+ cp DEWGONG
+ jr nz, .ok
+ call BattleRandom
+ cp $66 ; 40 percent
+ ret c
+.ok
+
ld a,[hl]
- ld [wTypeEffectiveness],a ; store damage multiplier
+ ld [wd11e],a ; store damage multiplier
ret
INCLUDE "data/type_effects.asm"
@@ -5752,12 +5920,12 @@ EnemyMoveHitTest:
handleIfEnemyMoveMissed:
ld a, [wMoveMissed]
and a
- jr z, .asm_3e791
+ jr z, .moveDidNotMiss
ld a, [wEnemyMoveEffect]
cp EXPLODE_EFFECT
- jr z, asm_3e7a0
+ jr z, handleExplosionMiss
jr EnemyCheckIfFlyOrChargeEffect
-.asm_3e791
+.moveDidNotMiss
call SwapPlayerAndEnemyLevels
GetEnemyAnimationType:
@@ -5767,7 +5935,7 @@ GetEnemyAnimationType:
jr z, playEnemyMoveAnimation
ld a, $2
jr playEnemyMoveAnimation
-asm_3e7a0:
+handleExplosionMiss:
call SwapPlayerAndEnemyLevels
xor a
playEnemyMoveAnimation:
@@ -5825,19 +5993,19 @@ EnemyCheckIfMirrorMoveEffect:
jp c, JumpMoveEffect
ld a, [wMoveMissed]
and a
- jr z, .asm_3e82b
+ jr z, .moveDidNotMiss
call PrintMoveFailureText
ld a, [wEnemyMoveEffect]
cp EXPLODE_EFFECT
- jr z, .asm_3e83e
+ jr z, .handleExplosionMiss
jp ExecuteEnemyMoveDone
-.asm_3e82b
+.moveDidNotMiss
call ApplyAttackToPlayerPokemon
call PrintCriticalOHKOText
callab DisplayEffectiveness
ld a, 1
ld [wMoveDidntMiss], a
-.asm_3e83e
+.handleExplosionMiss
ld a, [wEnemyMoveEffect]
ld hl, AlwaysHappenSideEffects
ld de, $1
@@ -5851,7 +6019,7 @@ EnemyCheckIfMirrorMoveEffect:
call HandleBuildingRage
ld hl, wEnemyBattleStatus1
bit AttackingMultipleTimes, [hl] ; is mon hitting multiple times? (example: double kick)
- jr z, .asm_3e873
+ jr z, .notMultiHitMove
push hl
ld hl, wEnemyNumAttacksLeft
dec [hl]
@@ -5862,7 +6030,7 @@ EnemyCheckIfMirrorMoveEffect:
call PrintText
xor a
ld [wEnemyNumHits], a
-.asm_3e873
+.notMultiHitMove
ld a, [wEnemyMoveEffect]
and a
jr z, ExecuteEnemyMoveDone
@@ -6407,10 +6575,13 @@ SwapPlayerAndEnemyLevels:
; (for use when scrolling the player sprite and enemy's silhouettes on screen)
LoadPlayerBackPic:
ld a, [wBattleType]
- dec a ; is it the old man tutorial?
- ld de, RedPicBack
- jr nz, .next
ld de, OldManPic
+ cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial?
+ jr z, .next
+ ld de, ProfOakPicBack
+ cp BATTLE_TYPE_PIKACHU ; is it the pikachu battle at the beginning of the game?
+ jr z, .next
+ ld de, RedPicBack
.next
ld a, BANK(RedPicBack)
call UncompressSpriteFromDE
@@ -6435,6 +6606,8 @@ LoadPlayerBackPic:
ld [hli], a ; OAM tile number
inc a ; increment tile number
ld [hOAMTile], a
+ ld a, $2
+ ld [hl], a
inc hl
dec c
jr nz, .innerLoop
@@ -6448,18 +6621,15 @@ LoadPlayerBackPic:
jr nz, .loop
ld de, vBackPic
call InterlaceMergeSpriteBuffers
- ld a, $a
- ld [$0], a
- xor a
- ld [$4000], a
+ ld a, $0
+ call SwitchSRAMBankAndLatchClockData
ld hl, vSprites
ld de, sSpriteBuffer1
ld a, [H_LOADEDROMBANK]
ld b, a
ld c, 7 * 7
call CopyVideoData
- xor a
- ld [$0], a
+ call PrepareRTCDataAndDisableSRAM
ld a, $31
ld [hStartTileID], a
coord hl, 1, 5
@@ -6802,16 +6972,16 @@ HandleExplodingAnimation:
ld hl, wEnemyMonType1
ld de, wEnemyBattleStatus1
ld a, [wPlayerMoveNum]
- jr z, .asm_3eeea
+ jr z, .player
ld hl, wBattleMonType1
ld de, wEnemyBattleStatus1
ld a, [wEnemyMoveNum]
-.asm_3eeea
+.player
cp SELFDESTRUCT
- jr z, .asm_3eef1
+ jr z, .isExplodingMove
cp EXPLOSION
ret nz
-.asm_3eef1
+.isExplodingMove
ld a, [de]
bit Invulnerable, a ; fly/dig
ret nz
@@ -6830,292 +7000,10 @@ HandleExplodingAnimation:
PlayMoveAnimation:
ld [wAnimationID],a
call Delay3
- predef_jump MoveAnimation
-
-InitBattle:
- ld a, [wCurOpponent]
- and a
- jr z, DetermineWildOpponent
-
-InitOpponent:
- ld a, [wCurOpponent]
- ld [wcf91], a
- ld [wEnemyMonSpecies2], a
- jr InitBattleCommon
-
-DetermineWildOpponent:
- ld a, [wd732]
- bit 1, a
- jr z, .asm_3ef2f
- ld a, [hJoyHeld]
- bit 1, a ; B button pressed?
- ret nz
-.asm_3ef2f
- ld a, [wNumberOfNoRandomBattleStepsLeft]
- and a
- ret nz
- callab TryDoWildEncounter
- ret nz
-InitBattleCommon:
- ld a, [wMapPalOffset]
- push af
- ld hl, wLetterPrintingDelayFlags
- ld a, [hl]
- push af
- res 1, [hl]
- callab InitBattleVariables
- ld a, [wEnemyMonSpecies2]
- sub 200
- jp c, InitWildBattle
- ld [wTrainerClass], a
- call GetTrainerInformation
- callab ReadTrainer
- call DoBattleTransitionAndInitBattleVariables
- call _LoadTrainerPic
- xor a
- ld [wEnemyMonSpecies2], a
- ld [hStartTileID], a
- dec a
- ld [wAICount], a
- coord hl, 12, 0
- predef CopyUncompressedPicToTilemap
- ld a, $ff
- ld [wEnemyMonPartyPos], a
- ld a, $2
- ld [wIsInBattle], a
- jp _InitBattleCommon
-
-InitWildBattle:
- ld a, $1
- ld [wIsInBattle], a
- call LoadEnemyMonData
- call DoBattleTransitionAndInitBattleVariables
- ld a, [wCurOpponent]
- cp MAROWAK
- jr z, .isGhost
- call IsGhostBattle
- jr nz, .isNoGhost
-.isGhost
- ld hl, wMonHSpriteDim
- ld a, $66
- ld [hli], a ; write sprite dimensions
- ld bc, GhostPic
- ld a, c
- ld [hli], a ; write front sprite pointer
- ld [hl], b
- ld hl, wEnemyMonNick ; set name to "GHOST"
- ld a, "G"
- ld [hli], a
- ld a, "H"
- ld [hli], a
- ld a, "O"
- ld [hli], a
- ld a, "S"
- ld [hli], a
- ld a, "T"
- ld [hli], a
- ld [hl], "@"
- ld a, [wcf91]
- push af
- ld a, MON_GHOST
- ld [wcf91], a
- ld de, vFrontPic
- call LoadMonFrontSprite ; load ghost sprite
- pop af
- ld [wcf91], a
- jr .spriteLoaded
-.isNoGhost
- ld de, vFrontPic
- call LoadMonFrontSprite ; load mon sprite
-.spriteLoaded
- xor a
- ld [wTrainerClass], a
- ld [hStartTileID], a
- coord hl, 12, 0
- predef CopyUncompressedPicToTilemap
-
-; common code that executes after init battle code specific to trainer or wild battles
-_InitBattleCommon:
- ld b, SET_PAL_BATTLE_BLACK
- call RunPaletteCommand
- call SlidePlayerAndEnemySilhouettesOnScreen
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld hl, .emptyString
- call PrintText
- call SaveScreenTilesToBuffer1
- call ClearScreen
- ld a, $98
- ld [H_AUTOBGTRANSFERDEST + 1], a
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- call Delay3
- ld a, $9c
- ld [H_AUTOBGTRANSFERDEST + 1], a
- call LoadScreenTilesFromBuffer1
- coord hl, 9, 7
- lb bc, 5, 10
- call ClearScreenArea
- coord hl, 1, 0
- lb bc, 4, 10
- call ClearScreenArea
- call ClearSprites
- ld a, [wIsInBattle]
- dec a ; is it a wild battle?
- call z, DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle
- call StartBattle
- callab EndOfBattle
- pop af
- ld [wLetterPrintingDelayFlags], a
- pop af
- ld [wMapPalOffset], a
- ld a, [wSavedTilesetType]
- ld [hTilesetType], a
- scf
- ret
-.emptyString
- db "@"
-
-_LoadTrainerPic:
-; wd033-wd034 contain pointer to pic
- ld a, [wTrainerPicPointer]
- ld e, a
- ld a, [wTrainerPicPointer + 1]
- ld d, a ; de contains pointer to trainer pic
- ld a, [wLinkState]
- and a
- ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
- jr z, .loadSprite
- ld a, Bank(RedPicFront)
-.loadSprite
- call UncompressSpriteFromDE
- ld de, vFrontPic
- ld a, $77
- ld c, a
- jp LoadUncompressedSpriteData
-
-; unreferenced
-ResetCryModifiers:
- xor a
- ld [wFrequencyModifier], a
- ld [wTempoModifier], a
- jp PlaySound
-
-; animates the mon "growing" out of the pokeball
-AnimateSendingOutMon:
- ld a, [wPredefRegisters]
- ld h, a
- ld a, [wPredefRegisters + 1]
- ld l, a
- ld a, [hStartTileID]
- ld [hBaseTileID], a
- ld b, $4c
- ld a, [wIsInBattle]
- and a
- jr z, .notInBattle
- add b
- ld [hl], a
- call Delay3
- ld bc, -(SCREEN_WIDTH * 2 + 1)
- add hl, bc
- ld a, 1
- ld [wDownscaledMonSize], a
- lb bc, 3, 3
- predef CopyDownscaledMonTiles
- ld c, 4
- call DelayFrames
- ld bc, -(SCREEN_WIDTH * 2 + 1)
- add hl, bc
- xor a
- ld [wDownscaledMonSize], a
- lb bc, 5, 5
- predef CopyDownscaledMonTiles
- ld c, 5
- call DelayFrames
- ld bc, -(SCREEN_WIDTH * 2 + 1)
- jr .next
-.notInBattle
- ld bc, -(SCREEN_WIDTH * 6 + 3)
-.next
- add hl, bc
- ld a, [hBaseTileID]
- add $31
- jr CopyUncompressedPicToHL
-
-CopyUncompressedPicToTilemap:
- ld a, [wPredefRegisters]
- ld h, a
- ld a, [wPredefRegisters + 1]
- ld l, a
- ld a, [hStartTileID]
-CopyUncompressedPicToHL:
- lb bc, 7, 7
- ld de, SCREEN_WIDTH
- push af
- ld a, [wSpriteFlipped]
- and a
- jr nz, .flipped
- pop af
-.loop
- push bc
- push hl
-.innerLoop
- ld [hl], a
- add hl, de
- inc a
- dec c
- jr nz, .innerLoop
- pop hl
- inc hl
- pop bc
- dec b
- jr nz, .loop
- ret
-
-.flipped
- push bc
- ld b, 0
- dec c
- add hl, bc
- pop bc
- pop af
-.flippedLoop
- push bc
- push hl
-.flippedInnerLoop
- ld [hl], a
- add hl, de
- inc a
- dec c
- jr nz, .flippedInnerLoop
- pop hl
- dec hl
- pop bc
- dec b
- jr nz, .flippedLoop
+ predef MoveAnimation
+ callab Func_78e98
ret
-LoadMonBackPic:
-; Assumes the monster's attributes have
-; been loaded with GetMonHeader.
- ld a, [wBattleMonSpecies2]
- ld [wcf91], a
- coord hl, 1, 5
- ld b, 7
- ld c, 8
- call ClearScreenArea
- ld hl, wMonHBackSprite - wMonHeader
- call UncompressMonSprite
- predef ScaleSpriteByTwo
- ld de, vBackPic
- call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
- ld hl, vSprites
- ld de, vBackPic
- ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
- ld a, [H_LOADEDROMBANK]
- ld b, a
- jp CopyVideoData
-
JumpMoveEffect:
call _JumpMoveEffect
ld b, $1
@@ -7264,6 +7152,16 @@ SleepEffect:
call BattleRandom
and $7
jr z, .setSleepCounter
+ ld b, a
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ jr z, .asm_3f1ba ; XXX stadium stuff?
+ ld a, b
+ and $3
+ jr z, .setSleepCounter
+ ld b, a
+.asm_3f1ba
+ ld a, b
ld [de], a
call PlayCurrentMoveAnimation2
ld hl, FellAsleepText
@@ -7275,7 +7173,7 @@ FellAsleepText:
TX_FAR _FellAsleepText
db "@"
-AlreadyAsleepText:
+AlreadyAsleepText: ; 3f1cd (f:71cds)
TX_FAR _AlreadyAsleepText
db "@"
@@ -7334,7 +7232,7 @@ PoisonEffect:
jr nz, .ok
ld b, ANIM_A9
ld hl, wEnemyBattleStatus3
- ld de, wEnemyToxcCounter
+ ld de, wEnemyToxicCounter
.ok
cp TOXIC
jr nz, .normalPoison ; done if move is not Toxic
@@ -7342,18 +7240,18 @@ PoisonEffect:
xor a
ld [de], a
ld hl, BadlyPoisonedText
- jr .asm_3f2c0
+ jr .continue
.normalPoison
ld hl, PoisonedText
-.asm_3f2c0
+.continue
pop de
ld a, [de]
cp POISON_EFFECT
- jr z, .asm_3f2cd
+ jr z, .regularPoisonEffect
ld a, b
call PlayBattleAnimation2
jp PrintText
-.asm_3f2cd
+.regularPoisonEffect
call PlayCurrentMoveAnimation2
jp PrintText
.noEffect
@@ -7402,7 +7300,7 @@ FreezeBurnParalyzeEffect:
ret nz ; return if they have a substitute, can't effect them
ld a, [H_WHOSETURN]
and a
- jp nz, opponentAttacker
+ jp nz, .opponentAttacker
ld a, [wEnemyMonStatus]
and a
jp nz, CheckDefrost ; can't inflict status if opponent is already statused
@@ -7415,6 +7313,16 @@ FreezeBurnParalyzeEffect:
cp b ; do target type 2 and move type match?
ret z ; return if they match
ld a, [wPlayerMoveEffect]
+ cp UNUSED_EFFECT_23 ; more stadium stuff
+ jr nz, .asm_3f2c7
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ ld a, FREEZE_SIDE_EFFECT
+ ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
+ jr z, .next1
+ ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
+ jr .next1
+.asm_3f2c7
cp a, PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those
ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
jr c, .next1 ; branch ahead if this is a 10% chance effect..
@@ -7428,9 +7336,9 @@ FreezeBurnParalyzeEffect:
ret nc ; do nothing if random value is >= 1A or 4D [no status applied]
ld a, b ; what type of effect is this?
cp a, BURN_SIDE_EFFECT1
- jr z, .burn
+ jr z, .burn1
cp a, FREEZE_SIDE_EFFECT
- jr z, .freeze
+ jr z, .freeze1
; .paralyze
ld a, 1 << PAR
ld [wEnemyMonStatus], a
@@ -7438,7 +7346,7 @@ FreezeBurnParalyzeEffect:
ld a, ANIM_A9
call PlayBattleAnimation
jp PrintMayNotAttackText ; print paralysis text
-.burn
+.burn1
ld a, 1 << BRN
ld [wEnemyMonStatus], a
call HalveAttackDueToBurn ; halve attack of affected mon
@@ -7446,7 +7354,7 @@ FreezeBurnParalyzeEffect:
call PlayBattleAnimation
ld hl, BurnedText
jp PrintText
-.freeze
+.freeze1
call ClearHyperBeam ; resets hyper beam (recharge) condition from target
ld a, 1 << FRZ
ld [wEnemyMonStatus], a
@@ -7454,7 +7362,7 @@ FreezeBurnParalyzeEffect:
call PlayBattleAnimation
ld hl, FrozenText
jp PrintText
-opponentAttacker:
+.opponentAttacker ; 3f382 (f:7382)
ld a, [wBattleMonStatus] ; mostly same as above with addresses swapped for opponent
and a
jp nz, CheckDefrost
@@ -7467,12 +7375,22 @@ opponentAttacker:
cp b
ret z
ld a, [wEnemyMoveEffect]
+ cp UNUSED_EFFECT_23 ; more stadium stuff
+ jr nz, .asm_3f341
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ ld a, FREEZE_SIDE_EFFECT
+ ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
+ jr z, .next2
+ ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
+ jr .next2
+.asm_3f341
cp a, PARALYZE_SIDE_EFFECT1 + 1
ld b, $1a
- jr c, .next1
+ jr c, .next2
ld b, $4d
sub a, $1e
-.next1
+.next2
push af
call BattleRandom
cp b
@@ -7480,23 +7398,29 @@ opponentAttacker:
ret nc
ld a, b
cp a, BURN_SIDE_EFFECT1
- jr z, .burn
+ jr z, .burn2
cp a, FREEZE_SIDE_EFFECT
- jr z, .freeze
+ jr z, .freeze2
ld a, 1 << PAR
ld [wBattleMonStatus], a
call QuarterSpeedDueToParalysis
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
jp PrintMayNotAttackText
-.burn
+.burn2
ld a, 1 << BRN
ld [wBattleMonStatus], a
call HalveAttackDueToBurn
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
ld hl, BurnedText
jp PrintText
-.freeze
+.freeze2
; hyper beam bits aren't reseted for opponent's side
ld a, 1 << FRZ
ld [wBattleMonStatus], a
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
ld hl, FrozenText
jp PrintText
@@ -7661,25 +7585,25 @@ UpdateStatDone:
ld bc, wPlayerMonMinimized
ld a, [H_WHOSETURN]
and a
- jr z, .asm_3f4e6
+ jr z, .playerTurn
ld hl, wEnemyBattleStatus2
ld de, wEnemyMoveNum
ld bc, wEnemyMonMinimized
-.asm_3f4e6
+.playerTurn
ld a, [de]
cp MINIMIZE
- jr nz, .asm_3f4f9
+ jr nz, .notMinimize
; if a substitute is up, slide off the substitute and show the mon pic before
; playing the minimize animation
bit HasSubstituteUp, [hl]
push af
push bc
+ push de
ld hl, HideSubstituteShowMonAnim
ld b, BANK(HideSubstituteShowMonAnim)
- push de
call nz, Bankswitch
pop de
-.asm_3f4f9
+.notMinimize
call PlayCurrentMoveAnimation
ld a, [de]
cp MINIMIZE
@@ -7718,9 +7642,9 @@ MonsStatsRoseText:
ld a, [H_WHOSETURN]
and a
ld a, [wPlayerMoveEffect]
- jr z, .asm_3f53b
+ jr z, .playerTurn
ld a, [wEnemyMoveEffect]
-.asm_3f53b
+.playerTurn
cp ATTACK_DOWN1_EFFECT
ret nc
ld hl, RoseText
@@ -7729,7 +7653,7 @@ MonsStatsRoseText:
GreatlyRoseText:
db $0a
TX_FAR _GreatlyRoseText
-
+; fallthrough
RoseText:
TX_FAR _RoseText
db "@"
@@ -7818,9 +7742,9 @@ StatModifierDownEffect:
ld a, c
add e
ld e, a
- jr nc, .asm_3f5e4
+ jr nc, .noCarry
inc d ; de = unmodified stat
-.asm_3f5e4
+.noCarry
pop bc
ld a, [hld]
sub $1 ; can't lower stat below 1 (-6)
@@ -7920,12 +7844,13 @@ MonsStatsFellText:
ld a, [H_WHOSETURN]
and a
ld a, [wPlayerMoveEffect]
- jr z, .asm_3f674
+ jr z, .playerTurn
ld a, [wEnemyMoveEffect]
-.asm_3f674
- cp $1a
+.playerTurn
+; check if the move's effect decreases a stat by 2
+ cp BIDE_EFFECT
ret c
- cp $44
+ cp ATTACK_DOWN_SIDE_EFFECT
ret nc
ld hl, GreatlyFellText
ret
@@ -7933,7 +7858,7 @@ MonsStatsFellText:
GreatlyFellText:
db $0a
TX_FAR _GreatlyFellText
-
+; fallthrough
FellText:
TX_FAR _FellText
db "@"
@@ -7941,15 +7866,15 @@ FellText:
PrintStatText:
ld hl, StatsTextStrings
ld c, "@"
-.asm_3f68d
+.findStatName_outer
dec b
- jr z, .asm_3f696
-.asm_3f690
+ jr z, .foundStatName
+.findStatName_inner
ld a, [hli]
cp c
- jr z, .asm_3f68d
- jr .asm_3f690
-.asm_3f696
+ jr z, .findStatName_outer
+ jr .findStatName_inner
+.foundStatName
ld de, wcf4b
ld bc, $a
jp CopyData
@@ -8027,41 +7952,42 @@ ThrashPetalDanceEffect:
SwitchAndTeleportEffect:
ld a, [H_WHOSETURN]
and a
- jr nz, .asm_3f791
+ jr nz, .handleEnemy
ld a, [wIsInBattle]
dec a
- jr nz, .asm_3f77e
+ jr nz, .notWildBattle1
ld a, [wCurEnemyLVL]
ld b, a
ld a, [wBattleMonLevel]
- cp b
- jr nc, .asm_3f76e
+ cp b ; is the player's level greater than the enemy's level?
+ jr nc, .playerMoveWasSuccessful ; if so, teleport will always succeed
add b
ld c, a
- inc c
-.asm_3f751
+ inc c ; c = sum of player level and enemy level
+.rejectionSampleLoop1
call BattleRandom
- cp c
- jr nc, .asm_3f751
- srl b
+ cp c ; get a random number between 0 and c
+ jr nc, .rejectionSampleLoop1
srl b
- cp b
- jr nc, .asm_3f76e
+ srl b ; b = enemy level * 4
+; bug: does not account for overflow, so levels above 63 can lead to erroneousness results
+ cp b ; is rand[0, playerLevel + enemyLevel] > enemyLevel?
+ jr nc, .playerMoveWasSuccessful ; if so, allow teleporting
ld c, 50
call DelayFrames
ld a, [wPlayerMoveNum]
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
-.asm_3f76e
+.playerMoveWasSuccessful
call ReadPlayerMonCurHPAndStatus
xor a
ld [wAnimationType], a
inc a
ld [wEscapedFromBattle], a
ld a, [wPlayerMoveNum]
- jr .asm_3f7e4
-.asm_3f77e
+ jr .playAnimAndPrintText
+.notWildBattle1
ld c, 50
call DelayFrames
ld hl, IsUnaffectedText
@@ -8069,41 +7995,41 @@ SwitchAndTeleportEffect:
cp TELEPORT
jp nz, PrintText
jp PrintButItFailedText_
-.asm_3f791
+.handleEnemy
ld a, [wIsInBattle]
dec a
- jr nz, .asm_3f7d1
+ jr nz, .notWildBattle2
ld a, [wBattleMonLevel]
ld b, a
ld a, [wCurEnemyLVL]
cp b
- jr nc, .asm_3f7c1
+ jr nc, .enemyMoveWasSuccessful
add b
ld c, a
inc c
-.asm_3f7a4
+.rejectionSampleLoop2
call BattleRandom
cp c
- jr nc, .asm_3f7a4
+ jr nc, .rejectionSampleLoop2
srl b
srl b
cp b
- jr nc, .asm_3f7c1
+ jr nc, .enemyMoveWasSuccessful
ld c, 50
call DelayFrames
ld a, [wEnemyMoveNum]
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
-.asm_3f7c1
+.enemyMoveWasSuccessful
call ReadPlayerMonCurHPAndStatus
xor a
ld [wAnimationType], a
inc a
ld [wEscapedFromBattle], a
ld a, [wEnemyMoveNum]
- jr .asm_3f7e4
-.asm_3f7d1
+ jr .playAnimAndPrintText
+.notWildBattle2
ld c, 50
call DelayFrames
ld hl, IsUnaffectedText
@@ -8111,7 +8037,7 @@ SwitchAndTeleportEffect:
cp TELEPORT
jp nz, PrintText
jp ConditionalPrintButItFailed
-.asm_3f7e4
+.playAnimAndPrintText
push af
call PlayBattleAnimation
ld c, 20
@@ -8119,12 +8045,12 @@ SwitchAndTeleportEffect:
pop af
ld hl, RanFromBattleText
cp TELEPORT
- jr z, .asm_3f7ff
+ jr z, .printText
ld hl, RanAwayScaredText
cp ROAR
- jr z, .asm_3f7ff
+ jr z, .printText
ld hl, WasBlownAwayText
-.asm_3f7ff
+.printText
jp PrintText
RanFromBattleText:
@@ -8169,10 +8095,11 @@ TwoToFiveAttacksEffect:
call BattleRandom
and $3
cp $2
- jr c, .asm_3f851
+ jr c, .gotNumHits
+; if the number of hits was greater than 2, re-roll again for a lower chance
call BattleRandom
and $3
-.asm_3f851
+.gotNumHits
inc a
inc a
.saveNumberOfHits
@@ -8195,6 +8122,9 @@ FlinchSideEffect:
ld hl, wPlayerBattleStatus1
ld de, wEnemyMoveEffect
.flinchSideEffect
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ call z, ClearHyperBeam
ld a, [de]
cp FLINCH_SIDE_EFFECT1
ld b, $1a ; ~10% chance of flinch
@@ -8236,10 +8166,27 @@ ChargeEffect:
set Invulnerable, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
ld b, ANIM_C0
.notDigOrFly
+ push de
+ push bc
+ inc hl ; battle status 2
+ push hl
+ ld a, [hl]
+ bit HasSubstituteUp, a
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ pop hl
+ pop bc
xor a
ld [wAnimationType], a
ld a, b
call PlayBattleAnimation
+ ld a, [hl]
+ bit HasSubstituteUp, a
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ call nz, Bankswitch
+ pop de
ld a, [de]
ld [wChargeMoveNum], a
ld hl, ChargeMoveEffectText
@@ -8251,22 +8198,22 @@ ChargeMoveEffectText:
ld a, [wChargeMoveNum]
cp RAZOR_WIND
ld hl, MadeWhirlwindText
- jr z, .asm_3f8f8
+ jr z, .gotText
cp SOLARBEAM
ld hl, TookInSunlightText
- jr z, .asm_3f8f8
+ jr z, .gotText
cp SKULL_BASH
ld hl, LoweredItsHeadText
- jr z, .asm_3f8f8
+ jr z, .gotText
cp SKY_ATTACK
ld hl, SkyAttackGlowingText
- jr z, .asm_3f8f8
+ jr z, .gotText
cp FLY
ld hl, FlewUpHighText
- jr z, .asm_3f8f8
+ jr z, .gotText
cp DIG
ld hl, DugAHoleText
-.asm_3f8f8
+.gotText
ret
MadeWhirlwindText:
@@ -8329,7 +8276,7 @@ RecoilEffect:
ConfusionSideEffect:
call BattleRandom
- cp $19
+ cp $19 ; ~10% chance
ret nc
jr ConfusionSideEffectSuccess
@@ -8399,9 +8346,9 @@ ClearHyperBeam:
ld hl, wEnemyBattleStatus2
ld a, [H_WHOSETURN]
and a
- jr z, .asm_3f9db
+ jr z, .playerTurn
ld hl, wPlayerBattleStatus2
-.asm_3f9db
+.playerTurn
res NeedsToRecharge, [hl] ; mon no longer needs to recharge
pop hl
ret
@@ -8422,21 +8369,21 @@ MimicEffect:
call MoveHitTest
ld a, [wMoveMissed]
and a
- jr nz, .asm_3fa74
+ jr nz, .mimicMissed
ld a, [H_WHOSETURN]
and a
ld hl, wBattleMonMoves
ld a, [wPlayerBattleStatus1]
- jr nz, .asm_3fa13
+ jr nz, .enemyTurn
ld a, [wLinkState]
cp LINK_STATE_BATTLING
- jr nz, .asm_3fa3a
+ jr nz, .letPlayerChooseMove
ld hl, wEnemyMonMoves
ld a, [wEnemyBattleStatus1]
-.asm_3fa13
+.enemyTurn
bit Invulnerable, a
- jr nz, .asm_3fa74
-.asm_3fa17
+ jr nz, .mimicMissed
+.getRandomMove
push hl
call BattleRandom
and $3
@@ -8446,20 +8393,20 @@ MimicEffect:
ld a, [hl]
pop hl
and a
- jr z, .asm_3fa17
+ jr z, .getRandomMove
ld d, a
ld a, [H_WHOSETURN]
and a
ld hl, wBattleMonMoves
ld a, [wPlayerMoveListIndex]
- jr z, .asm_3fa5f
+ jr z, .playerTurn
ld hl, wEnemyMonMoves
ld a, [wEnemyMoveListIndex]
- jr .asm_3fa5f
-.asm_3fa3a
+ jr .playerTurn
+.letPlayerChooseMove
ld a, [wEnemyBattleStatus1]
bit Invulnerable, a
- jr nz, .asm_3fa74
+ jr nz, .mimicMissed
ld a, [wCurrentMenuItem]
push af
ld a, $1
@@ -8474,7 +8421,7 @@ MimicEffect:
ld d, [hl]
pop af
ld hl, wBattleMonMoves
-.asm_3fa5f
+.playerTurn
ld c, a
ld b, $0
add hl, bc
@@ -8485,7 +8432,7 @@ MimicEffect:
call PlayCurrentMoveAnimation
ld hl, MimicLearnedMoveText
jp PrintText
-.asm_3fa74
+.mimicMissed
jp PrintButItFailedText_
MimicLearnedMoveText:
@@ -8709,6 +8656,7 @@ PlayBattleAnimationGotID:
push de
push bc
predef MoveAnimation
+ callab Func_78e98
pop bc
pop de
pop hl
diff --git a/engine/battle/decrement_pp.asm b/engine/battle/decrement_pp.asm
index 984af087..fd1a3184 100644
--- a/engine/battle/decrement_pp.asm
+++ b/engine/battle/decrement_pp.asm
@@ -33,7 +33,7 @@ DecrementPP:
ld a, [wPlayerMonNumber] ; which mon in party is active
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes ; calculate address of the mon to modify
-.DecrementPP
+.DecrementPP ; f4301 (3d:4301)
ld a, [wPlayerMoveListIndex] ; which move (0, 1, 2, 3) did we use?
ld c, a
ld b, 0
diff --git a/engine/battle/draw_hud_pokeball_gfx.asm b/engine/battle/draw_hud_pokeball_gfx.asm
index d477ffdf..8f9dce46 100644
--- a/engine/battle/draw_hud_pokeball_gfx.asm
+++ b/engine/battle/draw_hud_pokeball_gfx.asm
@@ -27,6 +27,8 @@ SetupOwnPartyPokeballs:
ld [hl], a
ld a, 8
ld [wHUDPokeballGfxOffsetX], a
+ xor a
+ ld [wdef5], a
ld hl, wOAMBuffer
jp WritePokeballOAMData
@@ -41,10 +43,12 @@ SetupEnemyPartyPokeballs:
ld [hl], $20
ld a, -8
ld [wHUDPokeballGfxOffsetX], a
+ ld a, $1
+ ld [wdef5], a
ld hl, wOAMBuffer + PARTY_LENGTH * 4
jp WritePokeballOAMData
-SetupPokeballs: ; 0x3a8a6
+SetupPokeballs:
ld a, [de]
push af
ld de, wBuffer
@@ -104,7 +108,7 @@ WritePokeballOAMData:
ld [hli], a
ld a, [de]
ld [hli], a
- xor a
+ ld a, [wdef5]
ld [hli], a
ld a, [wBaseCoordX]
ld b, a
@@ -174,6 +178,8 @@ SetupPlayerAndEnemyPokeballs:
ld [hl], $40
ld a, 8
ld [wHUDPokeballGfxOffsetX], a
+ xor a
+ ld [wdef5], a
ld hl, wOAMBuffer
call WritePokeballOAMData
ld hl, wEnemyMons
@@ -183,6 +189,8 @@ SetupPlayerAndEnemyPokeballs:
ld a, $50
ld [hli], a
ld [hl], $68
+ ld a, $1
+ ld [wdef5], a
ld hl, wOAMBuffer + $18
jp WritePokeballOAMData
diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm
index 2d6ab2e9..47c9fa5d 100755
--- a/engine/battle/end_of_battle.asm
+++ b/engine/battle/end_of_battle.asm
@@ -10,6 +10,8 @@ EndOfBattle:
ld a, [wEnemyMonStatus]
ld [hl], a
call ClearScreen
+ ld b, SET_PAL_OVERWORLD
+ call RunPaletteCommand
callab DisplayLinkBattleVersusTextBox
ld a, [wBattleResult]
cp $1
@@ -43,6 +45,8 @@ EndOfBattle:
xor a
ld [wForceEvolution], a
predef EvolutionAfterBattle
+ ld d, $82
+ callab UpdatePikachuMoodAfterBattle
.resetVariables
xor a
ld [wLowHealthAlarm], a ;disable low health alarm
diff --git a/engine/battle/experience.asm b/engine/battle/experience.asm
index c1914806..9946c6c6 100644
--- a/engine/battle/experience.asm
+++ b/engine/battle/experience.asm
@@ -43,17 +43,17 @@ GainExperience:
inc de
jr .nextBaseStat
.maxStatExp ; if the upper byte also overflowed, then we have hit the max stat exp
- ld a, $ff
+ dec a ; a is 0 from previous check
ld [de], a
inc de
ld [de], a
.nextBaseStat
dec c
- jr z, .asm_552a1
+ jr z, .statExpDone
inc de
inc de
jr .gainStatExpLoop
-.asm_552a1
+.statExpDone
xor a
ld [H_MULTIPLICAND], a
ld [H_MULTIPLICAND + 1], a
@@ -233,13 +233,19 @@ GainExperience:
.recalcStatChanges
xor a ; battle mon
ld [wCalculateWhoseStats], a
- callab CalculateModifiedStats
- callab ApplyBurnAndParalysisPenaltiesToPlayer
- callab ApplyBadgeStatBoosts
- callab DrawPlayerHUDAndHPBar
- callab PrintEmptyString
+ ld hl, CalculateModifiedStats
+ call Bankswitch15ToF
+ ld hl, ApplyBurnAndParalysisPenaltiesToPlayer
+ call Bankswitch15ToF
+ ld hl, ApplyBadgeStatBoosts
+ call Bankswitch15ToF
+ ld hl, DrawPlayerHUDAndHPBar
+ call Bankswitch15ToF
+ ld hl, PrintEmptyString
+ call Bankswitch15ToF
call SaveScreenTilesToBuffer1
.printGrewLevelText
+ callabd_ModifyPikachuHappiness PIKAHAPPY_LEVELUP
ld hl, GrewLevelText
call PrintText
xor a ; PLAYER_PARTY_DATA
@@ -339,6 +345,10 @@ BoostExp:
ld [H_QUOTIENT + 2], a
ret
+Bankswitch15ToF:
+ ld b, BANK(BattleCore)
+ jp Bankswitch
+
GainedText:
TX_FAR _GainedText
TX_ASM
diff --git a/engine/battle/get_trainer_name.asm b/engine/battle/get_trainer_name.asm
index deed8e95..e051a02a 100644
--- a/engine/battle/get_trainer_name.asm
+++ b/engine/battle/get_trainer_name.asm
@@ -2,15 +2,15 @@ GetTrainerName_:
ld hl, wGrassRate
ld a, [wLinkState]
and a
- jr nz, .rival
+ jr nz, .foundName
ld hl, wRivalName
ld a, [wTrainerClass]
cp SONY1
- jr z, .rival
+ jr z, .foundName
cp SONY2
- jr z, .rival
+ jr z, .foundName
cp SONY3
- jr z, .rival
+ jr z, .foundName
ld [wd0b5], a
ld a, TRAINER_NAME
ld [wNameListType], a
@@ -18,6 +18,7 @@ GetTrainerName_:
ld [wPredefBank], a
call GetName
ld hl, wcd6d
+.foundName
.rival
ld de, wTrainerName
ld bc, $d
diff --git a/engine/battle/ghost_marowak_anim.asm b/engine/battle/ghost_marowak_anim.asm
index 7adb20d8..5bb3e308 100644
--- a/engine/battle/ghost_marowak_anim.asm
+++ b/engine/battle/ghost_marowak_anim.asm
@@ -2,6 +2,7 @@ MarowakAnim:
; animate the ghost being unveiled as a Marowak
ld a, $e4
ld [rOBP1], a
+ call UpdateGBCPal_OBP1
call CopyMonPicFromBGToSpriteVRAM ; cover the BG ghost pic with a sprite ghost pic that looks the same
; now that the ghost pic is being displayed using sprites, clear the ghost pic from the BG tilemap
coord hl, 12, 0
@@ -27,6 +28,7 @@ MarowakAnim:
sla a
sla a
ld [rOBP1], a
+ call UpdateGBCPal_OBP1
jr nz, .fadeOutGhostLoop
call ClearSprites
call CopyMonPicFromBGToSpriteVRAM ; copy Marowak pic from BG to sprite VRAM
@@ -40,6 +42,7 @@ MarowakAnim:
srl b
rra
ld [rOBP1], a
+ call UpdateGBCPal_OBP1
ld a, b
and a
jr nz, .fadeInMarowakLoop
@@ -74,7 +77,7 @@ CopyMonPicFromBGToSpriteVRAM:
ld [hli], a
ld a, d
ld [hli], a
- ld a, $10 ; use OBP1
+ ld a, $14 ; use OBP1
ld [hli], a
inc d
dec c
diff --git a/engine/battle/link_battle_versus_text.asm b/engine/battle/link_battle_versus_text.asm
index 57e7f1bb..5edf13e6 100644
--- a/engine/battle/link_battle_versus_text.asm
+++ b/engine/battle/link_battle_versus_text.asm
@@ -2,8 +2,7 @@
DisplayLinkBattleVersusTextBox:
call LoadTextBoxTilePatterns
coord hl, 3, 4
- ld b, $7
- ld c, $c
+ ld bc, $70c
call TextBoxBorder
coord hl, 4, 5
ld de, wPlayerName
diff --git a/engine/battle/moveEffects/heal_effect.asm b/engine/battle/moveEffects/heal_effect.asm
index b7d8283f..377c14c4 100644
--- a/engine/battle/moveEffects/heal_effect.asm
+++ b/engine/battle/moveEffects/heal_effect.asm
@@ -86,7 +86,7 @@ HealEffect_:
ld [wHPBarNewHP], a
.playAnim
ld hl, PlayCurrentMoveAnimation
- call BankswitchEtoF
+ call Bankswitch3DtoF
ld a, [H_WHOSETURN]
and a
coord hl, 10, 9
@@ -98,14 +98,14 @@ HealEffect_:
ld [wHPBarType], a
predef UpdateHPBar2
ld hl, DrawHUDsAndHPBars
- call BankswitchEtoF
+ call Bankswitch3DtoF
ld hl, RegainedHealthText
jp PrintText
.failed
ld c, 50
call DelayFrames
ld hl, PrintButItFailedText_
- jp BankswitchEtoF
+ jp Bankswitch3DtoF
StartedSleepingEffect:
TX_FAR _StartedSleepingEffect
diff --git a/engine/battle/moveEffects/reflect_light_screen_effect.asm b/engine/battle/moveEffects/reflect_light_screen_effect.asm
index b45fbe20..f2165956 100644
--- a/engine/battle/moveEffects/reflect_light_screen_effect.asm
+++ b/engine/battle/moveEffects/reflect_light_screen_effect.asm
@@ -23,14 +23,14 @@ ReflectLightScreenEffect_:
.playAnim
push hl
ld hl, PlayCurrentMoveAnimation
- call BankswitchEtoF
+ call Bankswitch3DtoF
pop hl
jp PrintText
.moveFailed
ld c, 50
call DelayFrames
ld hl, PrintButItFailedText_
- jp BankswitchEtoF
+ jp Bankswitch3DtoF
LightScreenProtectedText:
TX_FAR _LightScreenProtectedText
@@ -40,6 +40,6 @@ ReflectGainedArmorText:
TX_FAR _ReflectGainedArmorText
db "@"
-BankswitchEtoF:
+Bankswitch3DtoF:
ld b, BANK(BattleCore)
jp Bankswitch
diff --git a/engine/battle/moveEffects/transform_effect.asm b/engine/battle/moveEffects/transform_effect.asm
index 45f8c910..2906de11 100644
--- a/engine/battle/moveEffects/transform_effect.asm
+++ b/engine/battle/moveEffects/transform_effect.asm
@@ -100,18 +100,11 @@ TransformEffect_:
and a
jr z, .lessThanFourMoves
ld a, $5
- ld [de], a
- inc de
- dec b
- jr nz, .copyPPLoop
- jr .copyStats
.lessThanFourMoves
-; 0 PP for blank moves
- xor a
ld [de], a
inc de
dec b
- jr nz, .lessThanFourMoves
+ jr nz, .copyPPLoop
.copyStats
; original (unmodified) stats and stat mods
pop hl
@@ -141,7 +134,7 @@ TransformEffect_:
.failed
ld hl, PrintButItFailedText_
- jp BankswitchEtoF
+ jp Bankswitch3DtoF
TransformedText:
TX_FAR _TransformedText
diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm
index 3672d8dc..3f10a85d 100755
--- a/engine/battle/read_trainer_party.asm
+++ b/engine/battle/read_trainer_party.asm
@@ -15,9 +15,9 @@ ReadTrainer:
ld [hl],a
; get the pointer to trainer data for this class
- ld a,[wCurOpponent]
- sub $C9 ; convert value from pokemon to trainer
- add a,a
+ ld a,[wTrainerClass] ; get trainer class
+ dec a
+ add a
ld hl,TrainerDataPointers
ld c,a
ld b,0
@@ -53,7 +53,7 @@ ReadTrainer:
.LoopTrainerData
ld a,[hli]
and a ; have we reached the end of the trainer data?
- jr z,.FinishUp
+ jp z, .AddAdditionalMoveData
ld [wcf91],a ; write species somewhere (XXX why?)
ld a,ENEMY_PARTY_DATA
ld [wMonDataLocation],a
@@ -68,7 +68,7 @@ ReadTrainer:
; - if [wLoneAttackNo] != 0, one pokemon on the team has a special move
ld a,[hli]
and a ; have we reached the end of the trainer data?
- jr z,.AddLoneMove
+ jr z,.AddAdditionalMoveData
ld [wCurEnemyLVL],a
ld a,[hli]
ld [wcf91],a
@@ -78,69 +78,48 @@ ReadTrainer:
call AddPartyMon
pop hl
jr .SpecialTrainer
-.AddLoneMove
-; does the trainer have a single monster with a different move
- ld a,[wLoneAttackNo] ; Brock is 01, Misty is 02, Erika is 04, etc
+.AddAdditionalMoveData
+; does the trainer have additional move data?
+ ld a, [wTrainerClass]
+ ld b, a
+ ld a, [wTrainerNo]
+ ld c, a
+ ld hl, SpecialTrainerMoves
+.loopAdditionalMoveData
+ ld a, [hli]
+ cp $ff
+ jr z, .FinishUp
+ cp b
+ jr nz, .asm_39c46
+ ld a, [hli]
+ cp c
+ jr nz, .asm_39c46
+ ld d, h
+ ld e, l
+.writeAdditionalMoveDataLoop
+ ld a, [de]
+ inc de
and a
- jr z,.AddTeamMove
+ jp z, .FinishUp
dec a
- add a,a
- ld c,a
- ld b,0
- ld hl,LoneMoves
- add hl,bc
- ld a,[hli]
- ld d,[hl]
- ld hl,wEnemyMon1Moves + 2
- ld bc,wEnemyMon2 - wEnemyMon1
+ ld hl, wEnemyMon1Moves
+ ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
- ld [hl],d
- jr .FinishUp
-.AddTeamMove
-; check if our trainer's team has special moves
-
-; get trainer class number
- ld a,[wCurOpponent]
- sub 200
- ld b,a
- ld hl,TeamMoves
-
-; iterate through entries in TeamMoves, checking each for our trainer class
-.IterateTeamMoves
- ld a,[hli]
- cp b
- jr z,.GiveTeamMoves ; is there a match?
- inc hl ; if not, go to the next entry
- inc a
- jr nz,.IterateTeamMoves
-
-; no matches found. is this trainer champion rival?
- ld a,b
- cp SONY3
- jr z,.ChampionRival
- jr .FinishUp ; nope
-.GiveTeamMoves
- ld a,[hl]
- ld [wEnemyMon5Moves + 2],a
- jr .FinishUp
-.ChampionRival ; give moves to his team
-
-; pidgeot
- ld a,SKY_ATTACK
- ld [wEnemyMon1Moves + 2],a
-
-; starter
- ld a,[wRivalStarter]
- cp STARTER3
- ld b,MEGA_DRAIN
- jr z,.GiveStarterMove
- cp STARTER1
- ld b,FIRE_BLAST
- jr z,.GiveStarterMove
- ld b,BLIZZARD ; must be squirtle
-.GiveStarterMove
- ld a,b
- ld [wEnemyMon6Moves + 2],a
+ ld a, [de]
+ inc de
+ dec a
+ ld c, a
+ ld b, 0
+ add hl,bc
+ ld a, [de]
+ inc de
+ ld [hl], a
+ jr .writeAdditionalMoveDataLoop
+.asm_39c46
+ ld a, [hli]
+ and a
+ jr nz, .asm_39c46
+ jr .loopAdditionalMoveData
.FinishUp
; clear wAmountMoneyWon addresses
xor a
diff --git a/engine/battle/safari_zone.asm b/engine/battle/safari_zone.asm
index 1eb1a615..c6c0fa80 100755
--- a/engine/battle/safari_zone.asm
+++ b/engine/battle/safari_zone.asm
@@ -2,18 +2,18 @@ PrintSafariZoneBattleText:
ld hl, wSafariBaitFactor
ld a, [hl]
and a
- jr z, .asm_4284
+ jr z, .asm_411e
dec [hl]
ld hl, SafariZoneEatingText
- jr .asm_429f
-.asm_4284
+ jr .asm_4138
+.asm_411e
dec hl
ld a, [hl]
and a
ret z
dec [hl]
ld hl, SafariZoneAngryText
- jr nz, .asm_429f
+ jr nz, .asm_4138
push hl
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
@@ -21,7 +21,7 @@ PrintSafariZoneBattleText:
ld a, [wMonHCatchRate]
ld [wEnemyMonCatchRate], a
pop hl
-.asm_429f
+.asm_4138
push hl
call LoadScreenTilesFromBuffer1
pop hl
diff --git a/engine/battle/scale_sprites.asm b/engine/battle/scale_sprites.asm
index 98521528..c614d638 100644
--- a/engine/battle/scale_sprites.asm
+++ b/engine/battle/scale_sprites.asm
@@ -2,6 +2,13 @@
; assumes that input sprite chunks are 4x4 tiles, and the rightmost and bottommost 4 pixels will be ignored
; resulting in a 7*7 tile output sprite chunk
ScaleSpriteByTwo:
+ ld a, $0
+ call SwitchSRAMBankAndLatchClockData
+ call ScaleSpriteByTwo_
+ call PrepareRTCDataAndDisableSRAM
+ ret
+
+ScaleSpriteByTwo_:
ld de, sSpriteBuffer1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
ld hl, sSpriteBuffer0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
call ScaleLastSpriteColumnByTwo ; last tile column is special case
diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm
index 385cdd1b..3624f5ea 100644
--- a/engine/battle/trainer_ai.asm
+++ b/engine/battle/trainer_ai.asm
@@ -145,7 +145,7 @@ AIMoveChoiceModification1:
ld [hl], a
jr .nextMove
-StatusAilmentMoveEffects: ; 57e2
+StatusAilmentMoveEffects:
db $01 ; unused sleep effect
db SLEEP_EFFECT
db POISON_EFFECT
@@ -182,7 +182,7 @@ AIMoveChoiceModification2:
jr c, .preferMove
jr .nextMove
.preferMove
- dec [hl] ; sligthly encourage this move
+ dec [hl] ; slightly encourage this move
jr .nextMove
; encourages moves that are effective against the player's mon (even if non-damaging).
@@ -295,7 +295,7 @@ TrainerClassMoveChoiceModifications:
db 1,0 ; GAMBLER
db 1,3,0 ; BEAUTY
db 1,2,0 ; PSYCHIC_TR
- db 1,3,0 ; ROCKER
+ db 1,0 ; ROCKER
db 1,0 ; JUGGLER
db 1,0 ; TAMER
db 1,0 ; BIRD_KEEPER
@@ -311,11 +311,11 @@ TrainerClassMoveChoiceModifications:
db 1,0 ; BRUNO
db 1,0 ; BROCK
db 1,3,0 ; MISTY
- db 1,3,0 ; LT_SURGE
+ db 1,0 ; LT_SURGE
db 1,3,0 ; ERIKA
db 1,3,0 ; KOGA
- db 1,3,0 ; BLAINE
- db 1,3,0 ; SABRINA
+ db 1,0 ; BLAINE
+ db 1,0 ; SABRINA
db 1,2,0 ; GENTLEMAN
db 1,3,0 ; SONY2
db 1,3,0 ; SONY3
@@ -337,13 +337,19 @@ INCLUDE "data/trainer_moves.asm"
INCLUDE "data/trainer_parties.asm"
TrainerAI:
- and a
ld a,[wIsInBattle]
dec a
- ret z ; if not a trainer, we're done here
+ jr z, .done ; if not a trainer, we're done here
ld a,[wLinkState]
cp LINK_STATE_BATTLING
- ret z
+ jr z, .done ; if in a link battle, we're done as well
+ ld a, [wEnemyBattleStatus1]
+ and 1 << ChargingUp | 1 << ThrashingAbout | 1 << StoringEnergy ; %10011
+ jr nz, .done ; don't follow trainer ai if opponent is in a locked state
+ ld a, [wEnemyBattleStatus2]
+ and 1 << UsingRage ; %1000000
+ jr nz, .done ; don't follow trainer ai if opponent is locked in rage
+ ; note that this doesn't check for hyper beam recharge which can cause problems
ld a,[wTrainerClass] ; what trainer class is this?
dec a
ld c,a
@@ -354,7 +360,7 @@ TrainerAI:
add hl,bc
ld a,[wAICount]
and a
- ret z ; if no AI uses left, we're done here
+ jr z, .done; if no AI uses left, we're done here
inc hl
inc a
jr nz,.getpointer
@@ -367,6 +373,9 @@ TrainerAI:
ld l,a
call Random
jp [hl]
+.done
+ and a
+ ret
TrainerAIPointers:
; one entry per trainer class
@@ -476,22 +485,22 @@ ErikaAI:
jp AIUseSuperPotion
KogaAI:
- cp $40
+ cp $20
ret nc
jp AIUseXAttack
BlaineAI:
cp $40
ret nc
+ ld a,$A
+ call AICheckIfHPBelowFraction
+ ret nc
jp AIUseSuperPotion
SabrinaAI:
cp $40
ret nc
- ld a,$A
- call AICheckIfHPBelowFraction
- ret nc
- jp AIUseHyperPotion
+ jp AIUseXDefend
Sony2AI:
cp $20
@@ -731,7 +740,8 @@ AICureStatus:
res 0,[hl]
ret
-AIUseXAccuracy: ; 0x3a7a8 unused
+AIUseXAccuracy:
+; unused
call AIPlayRestoringSFX
ld hl,wEnemyBattleStatus2
set 0,[hl]
@@ -745,7 +755,8 @@ AIUseGuardSpec:
ld a,GUARD_SPEC
jp AIPrintItemUse
-AIUseDireHit: ; 0x3a7c2 unused
+AIUseDireHit:
+; unused
call AIPlayRestoringSFX
ld hl,wEnemyBattleStatus2
set 2,[hl]
diff --git a/engine/battle/wild_encounters.asm b/engine/battle/wild_encounters.asm
index 231c46e7..0285346e 100644
--- a/engine/battle/wild_encounters.asm
+++ b/engine/battle/wild_encounters.asm
@@ -24,8 +24,9 @@ TryDoWildEncounter:
ld [wRepelRemainingSteps], a
.next
; determine if wild pokemon can appear in the half-block we're standing in
-; is the bottom right tile (9,9) of the half-block we're standing in a grass/water tile?
- coord hl, 9, 9
+; is the bottom left tile (8,9) of the half-block we're standing in a grass/water tile?
+; note that by using the bottom left tile, this prevents the "left-shore" tiles from generating grass encounters
+ coord hl, 8, 9
ld c, [hl]
ld a, [wGrassTile]
cp c
@@ -68,8 +69,6 @@ TryDoWildEncounter:
cp $14 ; is the bottom left tile (8,9) of the half-block we're standing in a water tile?
jr nz, .gotWildEncounterType ; else, it's treated as a grass tile by default
ld hl, wWaterMons
-; since the bottom right tile of a "left shore" half-block is $14 but the bottom left tile is not,
-; "left shore" half-blocks (such as the one in the east coast of Cinnabar) load grass encounters.
.gotWildEncounterType
ld b, 0
add hl, bc