diff options
Diffstat (limited to 'engine/battle')
-rwxr-xr-x | engine/battle/animations.asm | 1808 | ||||
-rw-r--r-- | engine/battle/bank3d_battle.asm | 291 | ||||
-rwxr-xr-x | engine/battle/bank_e_misc.asm | 19 | ||||
-rw-r--r-- | engine/battle/battle_transitions.asm | 14 | ||||
-rw-r--r-- | engine/battle/common_text.asm | 20 | ||||
-rwxr-xr-x | engine/battle/core.asm | 984 | ||||
-rw-r--r-- | engine/battle/decrement_pp.asm | 2 | ||||
-rw-r--r-- | engine/battle/draw_hud_pokeball_gfx.asm | 12 | ||||
-rwxr-xr-x | engine/battle/end_of_battle.asm | 4 | ||||
-rw-r--r-- | engine/battle/experience.asm | 26 | ||||
-rw-r--r-- | engine/battle/get_trainer_name.asm | 9 | ||||
-rw-r--r-- | engine/battle/ghost_marowak_anim.asm | 5 | ||||
-rw-r--r-- | engine/battle/link_battle_versus_text.asm | 3 | ||||
-rw-r--r-- | engine/battle/moveEffects/heal_effect.asm | 6 | ||||
-rw-r--r-- | engine/battle/moveEffects/reflect_light_screen_effect.asm | 6 | ||||
-rw-r--r-- | engine/battle/moveEffects/transform_effect.asm | 11 | ||||
-rwxr-xr-x | engine/battle/read_trainer_party.asm | 109 | ||||
-rwxr-xr-x | engine/battle/safari_zone.asm | 10 | ||||
-rw-r--r-- | engine/battle/scale_sprites.asm | 7 | ||||
-rw-r--r-- | engine/battle/trainer_ai.asm | 45 | ||||
-rw-r--r-- | engine/battle/wild_encounters.asm | 7 |
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 |