ref: bb1bf5e6a7536378dffc2b995384d6dc8692bea8
dir: /engine/trade.asm/
InternalClockTradeAnim: ; Do the trading animation with the player's gameboy on the left. ; In-game trades and internally clocked link cable trades use this. ld a, [wTradedPlayerMonSpecies] ld [wLeftGBMonSpecies], a ld a, [wTradedEnemyMonSpecies] ld [wRightGBMonSpecies], a ld de, InternalClockTradeFuncSequence jr TradeAnimCommon ExternalClockTradeAnim: ; Do the trading animation with the player's gameboy on the right. ; Externally clocked link cable trades use this. ld a, [wTradedEnemyMonSpecies] ld [wLeftGBMonSpecies], a ld a, [wTradedPlayerMonSpecies] ld [wRightGBMonSpecies], a ld de, ExternalClockTradeFuncSequence TradeAnimCommon: ld a, [wOptions] push af ld a, [hSCY] push af ld a, [hSCX] push af xor a ld [wOptions], a ld [hSCY], a ld [hSCX], a push de .loop pop de ld a, [de] cp $ff jr z, .done inc de push de ld hl, TradeFuncPointerTable add a ld c, a ld b, $0 add hl, bc ld a, [hli] ld h, [hl] ld l, a ld de, .loop push de jp [hl] ; call trade func, which will return to the top of the loop .done pop af ld [hSCX], a pop af ld [hSCY], a pop af ld [wOptions], a ret addtradefunc: MACRO \1TradeFunc:: dw \1 ENDM tradefunc: MACRO db (\1TradeFunc - TradeFuncPointerTable) / 2 ENDM ; The functions in the sequences below are executed in order by TradeFuncCommon. ; They are from opposite perspectives. The external clock one makes use of ; Trade_SwapNames to swap the player and enemy names for some functions. InternalClockTradeFuncSequence: tradefunc LoadTradingGFXAndMonNames tradefunc Trade_ShowPlayerMon tradefunc Trade_DrawOpenEndOfLinkCable tradefunc Trade_AnimateBallEnteringLinkCable tradefunc Trade_AnimLeftToRight tradefunc Trade_Delay100 tradefunc Trade_ShowClearedWindow tradefunc PrintTradeWentToText tradefunc PrintTradeForSendsText tradefunc PrintTradeFarewellText tradefunc Trade_AnimRightToLeft tradefunc Trade_ShowClearedWindow tradefunc Trade_DrawOpenEndOfLinkCable tradefunc Trade_ShowEnemyMon tradefunc Trade_Delay100 tradefunc Trade_Cleanup db $FF ExternalClockTradeFuncSequence: tradefunc LoadTradingGFXAndMonNames tradefunc Trade_ShowClearedWindow tradefunc PrintTradeWillTradeText tradefunc PrintTradeFarewellText tradefunc Trade_SwapNames tradefunc Trade_AnimLeftToRight tradefunc Trade_SwapNames tradefunc Trade_ShowClearedWindow tradefunc Trade_DrawOpenEndOfLinkCable tradefunc Trade_ShowEnemyMon tradefunc Trade_SlideTextBoxOffScreen tradefunc Trade_ShowPlayerMon tradefunc Trade_DrawOpenEndOfLinkCable tradefunc Trade_AnimateBallEnteringLinkCable tradefunc Trade_SwapNames tradefunc Trade_AnimRightToLeft tradefunc Trade_SwapNames tradefunc Trade_Delay100 tradefunc Trade_ShowClearedWindow tradefunc PrintTradeWentToText tradefunc Trade_Cleanup db $FF TradeFuncPointerTable: addtradefunc LoadTradingGFXAndMonNames addtradefunc Trade_ShowPlayerMon addtradefunc Trade_DrawOpenEndOfLinkCable addtradefunc Trade_AnimateBallEnteringLinkCable addtradefunc Trade_ShowEnemyMon addtradefunc Trade_AnimLeftToRight addtradefunc Trade_AnimRightToLeft addtradefunc Trade_Delay100 addtradefunc Trade_ShowClearedWindow addtradefunc PrintTradeWentToText addtradefunc PrintTradeForSendsText addtradefunc PrintTradeFarewellText addtradefunc PrintTradeTakeCareText addtradefunc PrintTradeWillTradeText addtradefunc Trade_Cleanup addtradefunc Trade_SlideTextBoxOffScreen addtradefunc Trade_SwapNames Trade_Delay100: ld c, 100 jp DelayFrames Trade_CopyTileMapToVRAM: ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call Delay3 xor a ld [H_AUTOBGTRANSFERENABLED], a ret Trade_Delay80: ld c, 80 jp DelayFrames Trade_ClearTileMap: coord hl, 0, 0 ld bc, SCREEN_WIDTH * SCREEN_HEIGHT ld a, " " jp FillMemory LoadTradingGFXAndMonNames: call Trade_ClearTileMap call DisableLCD ld hl, TradingAnimationGraphics ld de, vChars2 + $310 ld bc, TradingAnimationGraphicsEnd - TradingAnimationGraphics ld a, BANK(TradingAnimationGraphics) call FarCopyData2 ld hl, TradingAnimationGraphics2 ld de, vSprites + $7c0 ld bc, TradingAnimationGraphics2End - TradingAnimationGraphics2 ld a, BANK(TradingAnimationGraphics2) call FarCopyData2 ld hl, vBGMap0 ld bc, $800 ld a, " " call FillMemory call ClearSprites ld a, $ff ld [wUpdateSpritesEnabled], a ld hl, wd730 set 6, [hl] ; turn on instant text printing ld a, [wOnSGB] and a ld a, $e4 ; non-SGB OBP0 jr z, .next ld a, $f0 ; SGB OBP0 .next ld [rOBP0], a call EnableLCD xor a ld [H_AUTOBGTRANSFERENABLED], a ld a, [wTradedPlayerMonSpecies] ld [wd11e], a call GetMonName ld hl, wcd6d ld de, wcf4b ld bc, NAME_LENGTH call CopyData ld a, [wTradedEnemyMonSpecies] ld [wd11e], a jp GetMonName Trade_LoadMonPartySpriteGfx: ld a, %11010000 ld [rOBP1], a jpba LoadMonPartySpriteGfx Trade_SwapNames: ld hl, wPlayerName ld de, wBuffer ld bc, NAME_LENGTH call CopyData ld hl, wLinkEnemyTrainerName ld de, wPlayerName ld bc, NAME_LENGTH call CopyData ld hl, wBuffer ld de, wLinkEnemyTrainerName ld bc, NAME_LENGTH jp CopyData Trade_Cleanup: xor a call LoadGBPal ld hl, wd730 res 6, [hl] ; turn off instant text printing ret Trade_ShowPlayerMon: ld a, %10101011 ld [rLCDC], a ld a, $50 ld [hWY], a ld a, $86 ld [rWX], a ld [hSCX], a xor a ld [H_AUTOBGTRANSFERENABLED], a coord hl, 4, 0 ld b, 6 ld c, 10 call TextBoxBorder call Trade_PrintPlayerMonInfoText ld b, vBGMap0 / $100 call CopyScreenTileBufferToVRAM call ClearScreen ld a, [wTradedPlayerMonSpecies] call Trade_LoadMonSprite ld a, $7e .slideScreenLoop push af call DelayFrame pop af ld [rWX], a ld [hSCX], a dec a dec a and a jr nz, .slideScreenLoop call Trade_Delay80 ld a, TRADE_BALL_POOF_ANIM call Trade_ShowAnimation ld a, TRADE_BALL_DROP_ANIM call Trade_ShowAnimation ; clears mon pic ld a, [wTradedPlayerMonSpecies] call PlayCry xor a ld [H_AUTOBGTRANSFERENABLED], a ret Trade_DrawOpenEndOfLinkCable: call Trade_ClearTileMap ld b, vBGMap0 / $100 call CopyScreenTileBufferToVRAM ld b, SET_PAL_GENERIC call RunPaletteCommand ; This function call is pointless. It just copies blank tiles to VRAM that was ; already filled with blank tiles. ld hl, vBGMap1 + $8c call Trade_CopyCableTilesOffScreen ld a, $a0 ld [hSCX], a call DelayFrame ld a, %10001011 ld [rLCDC], a coord hl, 6, 2 ld b, $7 ; open end of link cable tile ID list index call CopyTileIDsFromList_ZeroBaseTileID call Trade_CopyTileMapToVRAM ld a, SFX_HEAL_HP call PlaySound ld c, 20 .loop ld a, [hSCX] add 4 ld [hSCX], a dec c jr nz, .loop ret Trade_AnimateBallEnteringLinkCable: ld a, TRADE_BALL_SHAKE_ANIM call Trade_ShowAnimation ld c, 10 call DelayFrames ld a, %11100100 ld [rOBP0], a xor a ld [wLinkCableAnimBulgeToggle], a lb bc, $20, $60 .moveBallInsideLinkCableLoop push bc xor a ld de, Trade_BallInsideLinkCableOAM call WriteOAMBlock ld a, [wLinkCableAnimBulgeToggle] xor $1 ld [wLinkCableAnimBulgeToggle], a add $7e ld hl, wOAMBuffer + $02 ld de, 4 ld c, e .cycleLinkCableBulgeTile ld [hl], a add hl, de dec c jr nz, .cycleLinkCableBulgeTile call Delay3 pop bc ld a, c add $4 ld c, a cp $a0 jr nc, .ballSpriteReachedEdgeOfScreen ld a, SFX_TINK call PlaySound jr .moveBallInsideLinkCableLoop .ballSpriteReachedEdgeOfScreen call ClearSprites ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call ClearScreen ld b, $98 call CopyScreenTileBufferToVRAM call Delay3 xor a ld [H_AUTOBGTRANSFERENABLED], a ret Trade_BallInsideLinkCableOAM: db $7E,$00,$7E,$20 db $7E,$40,$7E,$60 Trade_ShowEnemyMon: ld a, TRADE_BALL_TILT_ANIM call Trade_ShowAnimation call Trade_ShowClearedWindow coord hl, 4, 10 ld b, 6 ld c, 10 call TextBoxBorder call Trade_PrintEnemyMonInfoText call Trade_CopyTileMapToVRAM ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a ld a, [wTradedEnemyMonSpecies] call Trade_LoadMonSprite ld a, TRADE_BALL_POOF_ANIM call Trade_ShowAnimation ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a ld a, [wTradedEnemyMonSpecies] call PlayCry call Trade_Delay100 coord hl, 4, 10 lb bc, 8, 12 call ClearScreenArea jp PrintTradeTakeCareText Trade_AnimLeftToRight: ; Animates the mon moving from the left GB to the right one. call Trade_InitGameboyTransferGfx ld a, $1 ld [wTradedMonMovingRight], a ld a, %11100100 ld [rOBP0], a ld a, $54 ld [wBaseCoordX], a ld a, $1c ld [wBaseCoordY], a ld a, [wLeftGBMonSpecies] ld [wMonPartySpriteSpecies], a call Trade_WriteCircledMonOAM call Trade_DrawLeftGameboy call Trade_CopyTileMapToVRAM call Trade_DrawCableAcrossScreen ld hl, vBGMap1 + $8c call Trade_CopyCableTilesOffScreen ld b, $6 call Trade_AnimMonMoveHorizontal ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call Trade_DrawCableAcrossScreen ld b, $4 call Trade_AnimMonMoveHorizontal call Trade_DrawRightGameboy ld b, $6 call Trade_AnimMonMoveHorizontal xor a ld [H_AUTOBGTRANSFERENABLED], a call Trade_AnimMonMoveVertical jp ClearSprites Trade_AnimRightToLeft: ; Animates the mon moving from the right GB to the left one. call Trade_InitGameboyTransferGfx xor a ld [wTradedMonMovingRight], a ld a, $64 ld [wBaseCoordX], a ld a, $44 ld [wBaseCoordY], a ld a, [wRightGBMonSpecies] ld [wMonPartySpriteSpecies], a call Trade_WriteCircledMonOAM call Trade_DrawRightGameboy call Trade_CopyTileMapToVRAM call Trade_DrawCableAcrossScreen ld hl, vBGMap1 + $94 call Trade_CopyCableTilesOffScreen call Trade_AnimMonMoveVertical ld b, $6 call Trade_AnimMonMoveHorizontal ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call Trade_DrawCableAcrossScreen ld b, $4 call Trade_AnimMonMoveHorizontal call Trade_DrawLeftGameboy ld b, $6 call Trade_AnimMonMoveHorizontal xor a ld [H_AUTOBGTRANSFERENABLED], a jp ClearSprites Trade_InitGameboyTransferGfx: ; Initialises the graphics for showing a mon moving between gameboys. ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call ClearScreen xor a ld [H_AUTOBGTRANSFERENABLED], a call Trade_LoadMonPartySpriteGfx call DelayFrame ld a, %10101011 ld [rLCDC], a xor a ld [hSCX], a ld a, $90 ld [hWY], a ret Trade_DrawLeftGameboy: call Trade_ClearTileMap ; draw link cable coord hl, 11, 4 ld a, $5d ld [hli], a ld a, $5e ld c, 8 .loop ld [hli], a dec c jr nz, .loop ; draw gameboy pic coord hl, 5, 3 ld b, $6 call CopyTileIDsFromList_ZeroBaseTileID ; draw text box with player name below gameboy pic coord hl, 4, 12 ld b, 2 ld c, 7 call TextBoxBorder coord hl, 5, 14 ld de, wPlayerName call PlaceString jp DelayFrame Trade_DrawRightGameboy: call Trade_ClearTileMap ; draw horizontal segment of link cable coord hl, 0, 4 ld a, $5e ld c, $e .loop ld [hli], a dec c jr nz, .loop ; draw vertical segment of link cable ld a, $5f ld [hl], a ld de, SCREEN_WIDTH add hl, de ld a, $61 ld [hl], a add hl, de ld [hl], a add hl, de ld [hl], a add hl, de ld [hl], a add hl, de ld a, $60 ld [hld], a ld a, $5d ld [hl], a ; draw gameboy pic coord hl, 7, 8 ld b, $6 call CopyTileIDsFromList_ZeroBaseTileID ; draw text box with enemy name above link cable coord hl, 6, 0 ld b, 2 ld c, 7 call TextBoxBorder coord hl, 7, 2 ld de, wLinkEnemyTrainerName call PlaceString jp DelayFrame Trade_DrawCableAcrossScreen: ; Draws the link cable across the screen. call Trade_ClearTileMap coord hl, 0, 4 ld a, $5e ld c, SCREEN_WIDTH .loop ld [hli], a dec c jr nz, .loop ret Trade_CopyCableTilesOffScreen: ; This is used to copy the link cable tiles off screen so that the cable ; continues when the screen is scrolled. push hl coord hl, 0, 4 call CopyToRedrawRowOrColumnSrcTiles pop hl ld a, h ld [hRedrawRowOrColumnDest + 1], a ld a, l ld [hRedrawRowOrColumnDest], a ld a, REDRAW_ROW ld [hRedrawRowOrColumnMode], a ld c, 10 jp DelayFrames Trade_AnimMonMoveHorizontal: ; Animates the mon going through the link cable horizontally over a distance of ; b 16-pixel units. ld a, [wTradedMonMovingRight] ld e, a ld d, $8 .scrollLoop ld a, e dec a jr z, .movingRight ; moving left ld a, [hSCX] sub $2 jr .next .movingRight ld a, [hSCX] add $2 .next ld [hSCX], a call DelayFrame dec d jr nz, .scrollLoop call Trade_AnimCircledMon dec b jr nz, Trade_AnimMonMoveHorizontal ret Trade_AnimCircledMon: ; Cycles between the two animation frames of the mon party sprite, cycles ; between a circle and an oval around the mon sprite, and makes the cable flash. push de push bc push hl ld a, [rBGP] xor $3c ; make link cable flash ld [rBGP], a ld hl, wOAMBuffer + $02 ld de, $4 ld c, $14 .loop ld a, [hl] xor $40 ld [hl], a add hl, de dec c jr nz, .loop pop hl pop bc pop de ret Trade_WriteCircledMonOAM: callba WriteMonPartySpriteOAMBySpecies call Trade_WriteCircleOAM Trade_AddOffsetsToOAMCoords: ld hl, wOAMBuffer ld c, $14 .loop ld a, [wBaseCoordY] add [hl] ld [hli], a ld a, [wBaseCoordX] add [hl] ld [hli], a inc hl inc hl dec c jr nz, .loop ret Trade_AnimMonMoveVertical: ; Animates the mon going through the link cable vertically as well as ; horizontally for a bit. The last bit of horizontal movement (when moving ; right) or the first bit of horizontal movement (when moving left) are done ; here instead of Trade_AnimMonMoveHorizontal because this function moves the ; sprite itself rather than scrolling the screen around the sprite. Moving the ; sprite itself is necessary because the vertical segment of the link cable is ; to the right of the screen position that the mon sprite has when ; Trade_AnimMonMoveHorizontal is executing. ld a, [wTradedMonMovingRight] and a jr z, .movingLeft ; moving right lb bc, 4, 0 ; move right call .doAnim lb bc, 0, 10 ; move down jr .doAnim .movingLeft lb bc, 0, -10 ; move up call .doAnim lb bc, -4, 0 ; move left .doAnim ld a, b ld [wBaseCoordX], a ld a, c ld [wBaseCoordY], a ld d, $4 .loop call Trade_AddOffsetsToOAMCoords call Trade_AnimCircledMon ld c, 8 call DelayFrames dec d jr nz, .loop ret Trade_WriteCircleOAM: ; Writes the OAM blocks for the circle around the traded mon as it passes ; the link cable. ld hl, Trade_CircleOAMPointers ld c, $4 xor a .loop push bc ld e, [hl] inc hl ld d, [hl] inc hl ld c, [hl] inc hl ld b, [hl] inc hl push hl inc a push af call WriteOAMBlock pop af pop hl pop bc dec c jr nz, .loop ret Trade_CircleOAMPointers: dw Trade_CircleOAM0 db $08,$08 dw Trade_CircleOAM1 db $18,$08 dw Trade_CircleOAM2 db $08,$18 dw Trade_CircleOAM3 db $18,$18 Trade_CircleOAM0: db $38,$10,$39,$10 db $3A,$10,$3B,$10 Trade_CircleOAM1: db $39,$30,$38,$30 db $3B,$30,$3A,$30 Trade_CircleOAM2: db $3A,$50,$3B,$50 db $38,$50,$39,$50 Trade_CircleOAM3: db $3B,$70,$3A,$70 db $39,$70,$38,$70 ; a = species Trade_LoadMonSprite: ld [wcf91], a ld [wd0b5], a ld [wWholeScreenPaletteMonSpecies], a ld b, SET_PAL_POKEMON_WHOLE_SCREEN ld c, 0 call RunPaletteCommand ld a, [H_AUTOBGTRANSFERENABLED] xor $1 ld [H_AUTOBGTRANSFERENABLED], a call GetMonHeader coord hl, 7, 2 call LoadFlippedFrontSpriteByMonIndex ld c, 10 jp DelayFrames Trade_ShowClearedWindow: ; clears the window and covers the BG entirely with the window ld a, $1 ld [H_AUTOBGTRANSFERENABLED], a call ClearScreen ld a, %11100011 ld [rLCDC], a ld a, $7 ld [rWX], a xor a ld [hWY], a ld a, $90 ld [hSCX], a ret Trade_SlideTextBoxOffScreen: ; Slides the window right until it's off screen. The window usually just has ; a text box at the bottom when this is called. However, when this is called ; after Trade_ShowEnemyMon in the external clock sequence, there is a mon pic ; above the text box and it is also scrolled off the screen. ld c, 50 call DelayFrames .loop call DelayFrame ld a, [rWX] inc a inc a ld [rWX], a cp $a1 jr nz, .loop call Trade_ClearTileMap ld c, 10 call DelayFrames ld a, $7 ld [rWX], a ret PrintTradeWentToText: ld hl, TradeWentToText call PrintText ld c, 200 call DelayFrames jp Trade_SlideTextBoxOffScreen TradeWentToText: TX_FAR _TradeWentToText db "@" PrintTradeForSendsText: ld hl, TradeForText call PrintText call Trade_Delay80 ld hl, TradeSendsText call PrintText jp Trade_Delay80 TradeForText: TX_FAR _TradeForText db "@" TradeSendsText: TX_FAR _TradeSendsText db "@" PrintTradeFarewellText: ld hl, TradeWavesFarewellText call PrintText call Trade_Delay80 ld hl, TradeTransferredText call PrintText call Trade_Delay80 jp Trade_SlideTextBoxOffScreen TradeWavesFarewellText: TX_FAR _TradeWavesFarewellText db "@" TradeTransferredText: TX_FAR _TradeTransferredText db "@" PrintTradeTakeCareText: ld hl, TradeTakeCareText call PrintText jp Trade_Delay80 TradeTakeCareText: TX_FAR _TradeTakeCareText db "@" PrintTradeWillTradeText: ld hl, TradeWillTradeText call PrintText call Trade_Delay80 ld hl, TradeforText call PrintText jp Trade_Delay80 TradeWillTradeText: TX_FAR _TradeWillTradeText db "@" TradeforText: TX_FAR _TradeforText db "@" Trade_ShowAnimation: ld [wAnimationID], a xor a ld [wAnimationType], a predef_jump MoveAnimation