diff options
Diffstat (limited to 'engine/link/link.asm')
-rwxr-xr-x | engine/link/link.asm | 2589 |
1 files changed, 2589 insertions, 0 deletions
diff --git a/engine/link/link.asm b/engine/link/link.asm new file mode 100755 index 000000000..86af41c01 --- /dev/null +++ b/engine/link/link.asm @@ -0,0 +1,2589 @@ +LinkCommunications: ; 28000 + call ClearBGPalettes + ld c, 80 + call DelayFrames + call ClearScreen + call ClearSprites + call UpdateSprites + xor a + ld [hSCX], a + ld [hSCY], a + ld c, 80 + call DelayFrames + call ClearScreen + call UpdateSprites + call LoadStandardFont + call LoadFontsBattleExtra + farcall LinkComms_LoadPleaseWaitTextboxBorderGFX + call WaitBGMap2 + hlcoord 3, 8 + ld b, 2 + ld c, 12 + ld d, h + ld e, l + farcall LinkTextbox2 + hlcoord 4, 10 + ld de, String_PleaseWait + call PlaceString + call SetTradeRoomBGPals + call WaitBGMap2 + ld hl, wcf5d + xor a ; LOW($5000) + ld [hli], a + ld [hl], HIGH($5000) + ld a, [wLinkMode] + cp LINK_TIMECAPSULE + jp nz, Gen2ToGen2LinkComms + +Gen2ToGen1LinkComms: ; 2805d + call ClearLinkData + call Link_PrepPartyData_Gen1 + call FixDataForLinkTransfer + xor a + ld [wPlayerLinkAction], a + call WaitLinkTransfer + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr nz, .player_1 + + ld c, 3 + call DelayFrames + xor a + ld [hSerialSend], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + + call DelayFrame + xor a + ld [hSerialSend], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + +.player_1 + ld de, MUSIC_NONE + call PlayMusic + ld c, 3 + call DelayFrames + xor a + ld [rIF], a + ld a, $8 + ld [rIE], a + ld hl, wd1f3 + ld de, wEnemyMonSpecies + ld bc, $11 + call Serial_ExchangeBytes + ld a, SERIAL_NO_DATA_BYTE + ld [de], a + ld hl, wLinkData + ld de, wOTPlayerName + ld bc, $1a8 + call Serial_ExchangeBytes + ld a, SERIAL_NO_DATA_BYTE + ld [de], a + ld hl, wMisc + ld de, wPlayerTrademonSpecies + ld bc, wPlayerTrademonSpecies - wMisc + call Serial_ExchangeBytes + xor a + ld [rIF], a + ld a, $1d + ld [rIE], a + call Link_CopyRandomNumbers + ld hl, wOTPlayerName + call Link_FindFirstNonControlCharacter_SkipZero + push hl + ld bc, NAME_LENGTH + add hl, bc + ld a, [hl] + pop hl + and a + jp z, Function28b22 + cp $7 + jp nc, Function28b22 + ld de, wLinkData + ld bc, $1a2 + call Link_CopyOTData + ld de, wPlayerTrademonSpecies + ld hl, wTimeCapsulePartyMon1Species + ld c, 2 +.loop + ld a, [de] + inc de + and a + jr z, .loop + cp SERIAL_PREAMBLE_BYTE + jr z, .loop + cp SERIAL_NO_DATA_BYTE + jr z, .loop + cp SERIAL_PATCH_LIST_PART_TERMINATOR + jr z, .next + push hl + push bc + ld b, 0 + dec a + ld c, a + add hl, bc + ld a, SERIAL_NO_DATA_BYTE + ld [hl], a + pop bc + pop hl + jr .loop + +.next + ld hl, wc90f + dec c + jr nz, .loop + ld hl, wLinkPlayerName + ld de, wOTPlayerName + ld bc, NAME_LENGTH + call CopyBytes + ld de, wOTPartyCount + ld a, [hli] + ld [de], a + inc de +.party_loop + ld a, [hli] + cp -1 + jr z, .done_party + ld [wd265], a + push hl + push de + callfar ConvertMon_1to2 + pop de + pop hl + ld a, [wd265] + ld [de], a + inc de + jr .party_loop + +.done_party + ld [de], a + ld hl, wTimeCapsulePartyMon1Species + call Function2868a + ld a, LOW(wOTPartyMonOT) + ld [wUnusedD102], a + ld a, HIGH(wOTPartyMonOT) + ld [wUnusedD102 + 1], a + ld de, MUSIC_NONE + call PlayMusic + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + ld c, 66 + call z, DelayFrames + ld de, MUSIC_ROUTE_30 + call PlayMusic + jp InitTradeMenuDisplay +; 28177 + +Gen2ToGen2LinkComms: ; 28177 + call ClearLinkData + call Link_PrepPartyData_Gen2 + call FixDataForLinkTransfer + call Function29dba + ld a, [wScriptVar] + and a + jp z, LinkTimeout + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr nz, .Player1 + + ld c, 3 + call DelayFrames + xor a + ld [hSerialSend], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + + call DelayFrame + xor a + ld [hSerialSend], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + +.Player1: + ld de, MUSIC_NONE + call PlayMusic + ld c, 3 + call DelayFrames + xor a + ld [rIF], a + ld a, $8 + ld [rIE], a + ld hl, wd1f3 + ld de, wEnemyMonSpecies + ld bc, $11 + call Serial_ExchangeBytes + ld a, SERIAL_NO_DATA_BYTE + ld [de], a + ld hl, wLinkData + ld de, wOTPlayerName + ld bc, $1c2 + call Serial_ExchangeBytes + ld a, SERIAL_NO_DATA_BYTE + ld [de], a + ld hl, wMisc + ld de, wPlayerTrademonSpecies + ld bc, $c8 + call Serial_ExchangeBytes + ld a, [wLinkMode] + cp LINK_TRADECENTER + jr nz, .not_trading + ld hl, wc9f4 + ld de, wcb84 + ld bc, $186 + call ExchangeBytes + +.not_trading + xor a + ld [rIF], a + ld a, $1d + ld [rIE], a + ld de, MUSIC_NONE + call PlayMusic + call Link_CopyRandomNumbers + ld hl, wOTPlayerName + call Link_FindFirstNonControlCharacter_SkipZero + ld de, wLinkData + ld bc, $1b9 + call Link_CopyOTData + ld de, wPlayerTrademonSpecies + ld hl, wLinkPlayerPartyMon1Species + ld c, 2 +.loop1 + ld a, [de] + inc de + and a + jr z, .loop1 + cp SERIAL_PREAMBLE_BYTE + jr z, .loop1 + cp SERIAL_NO_DATA_BYTE + jr z, .loop1 + cp SERIAL_PATCH_LIST_PART_TERMINATOR + jr z, .next1 + push hl + push bc + ld b, 0 + dec a + ld c, a + add hl, bc + ld a, SERIAL_NO_DATA_BYTE + ld [hl], a + pop bc + pop hl + jr .loop1 + +.next1 + ld hl, wc90f + dec c + jr nz, .loop1 + ld a, [wLinkMode] + cp LINK_TRADECENTER + jp nz, .skip_mail + ld hl, wcb84 +.loop2 + ld a, [hli] + cp MAIL_MSG_LENGTH + jr nz, .loop2 +.loop3 + ld a, [hli] + cp SERIAL_NO_DATA_BYTE + jr z, .loop3 + cp MAIL_MSG_LENGTH + jr z, .loop3 + dec hl + ld de, wcb84 + ld bc, $190 ; 400 + call CopyBytes + ld hl, wcb84 + ld bc, $c6 ; 198 +.loop4 + ld a, [hl] + cp MAIL_MSG_LENGTH + 1 + jr nz, .okay1 + ld [hl], SERIAL_NO_DATA_BYTE +.okay1 + inc hl + dec bc + ld a, b + or c + jr nz, .loop4 + ld de, wcc9e +.loop5 + ld a, [de] + inc de + cp SERIAL_PATCH_LIST_PART_TERMINATOR + jr z, .start_copying_mail + ld hl, wcc4a + dec a + ld b, $0 + ld c, a + add hl, bc + ld [hl], SERIAL_NO_DATA_BYTE + jr .loop5 + +.start_copying_mail + ld hl, wcb84 + ld de, wc9f4 + ld b, PARTY_LENGTH +.copy_mail_loop + push bc + ld bc, MAIL_MSG_LENGTH + 1 + call CopyBytes + ld a, LOW(MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1)) + add e + ld e, a + ld a, HIGH(MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1)) + adc d + ld d, a + pop bc + dec b + jr nz, .copy_mail_loop + ld de, wc9f4 + ld b, PARTY_LENGTH +.copy_author_loop + push bc + ld a, LOW(MAIL_MSG_LENGTH + 1) + add e + ld e, a + ld a, HIGH(MAIL_MSG_LENGTH + 1) + adc d + ld d, a + ld bc, MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1) + call CopyBytes + pop bc + dec b + jr nz, .copy_author_loop + ld b, PARTY_LENGTH + ld de, wc9f4 +.fix_mail_loop + push bc + push de + farcall IsMailEuropean + ld a, c + or a + jr z, .next + sub $3 + jr nc, .skip + farcall DeutenEnglischenPost + jr .next + +.skip + cp $2 + jr nc, .next + farcall HandleSpanishItalianMail + +.next + pop de + ld hl, MAIL_STRUCT_LENGTH + add hl, de + ld d, h + ld e, l + pop bc + dec b + jr nz, .fix_mail_loop + ld de, wcb0e + xor a + ld [de], a + +.skip_mail + ld hl, wLinkPlayerName + ld de, wOTPlayerName + ld bc, NAME_LENGTH + call CopyBytes + ld de, wOTPartyCount + ld bc, 1 + PARTY_LENGTH + 1 + call CopyBytes + ld de, wOTPlayerID + ld bc, 2 + call CopyBytes + ld de, wOTPartyMons + ld bc, wOTPartyDataEnd - wOTPartyMons + call CopyBytes + ld a, LOW(wOTPartyMonOT) + ld [wUnusedD102], a + ld a, HIGH(wOTPartyMonOT) + ld [wUnusedD102 + 1], a + ld de, MUSIC_NONE + call PlayMusic + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + ld c, 66 + call z, DelayFrames + ld a, [wLinkMode] + cp LINK_COLOSSEUM + jr nz, .ready_to_trade + ld a, CAL + ld [wOtherTrainerClass], a + call ClearScreen + farcall Link_WaitBGMap + ld hl, wOptions + ld a, [hl] + push af + and 1 << STEREO + or TEXT_DELAY_MED + ld [hl], a + ld hl, wOTPlayerName + ld de, wOTClassName + ld bc, NAME_LENGTH + call CopyBytes + call ReturnToMapFromSubmenu + + ; LET'S DO THIS + ld a, [wDisableTextAcceleration] + push af + ld a, 1 + ld [wDisableTextAcceleration], a + ld a, [rIE] + push af + ld a, [rIF] + push af + xor a + ld [rIF], a + ld a, [rIE] + set 1, a + ld [rIE], a + pop af + ld [rIF], a + + predef StartBattle + + ld a, [rIF] + ld h, a + xor a + ld [rIF], a + pop af + ld [rIE], a + ld a, h + ld [rIF], a + pop af + ld [wDisableTextAcceleration], a + pop af + ld [wOptions], a + farcall LoadPokemonData + jp Function28b22 + +.ready_to_trade + ld de, MUSIC_ROUTE_30 + call PlayMusic + jp InitTradeMenuDisplay +; 283b2 + +LinkTimeout: ; 283b2 + ld de, .TooMuchTimeHasElapsed + ld b, 10 +.loop + call DelayFrame + call LinkDataReceived + dec b + jr nz, .loop + xor a + ld [hld], a + ld [hl], a + ld [hVBlank], a + push de + hlcoord 0, 12 + ld b, 4 + ld c, 18 + push de + ld d, h + ld e, l + farcall LinkTextbox2 + pop de + pop hl + bccoord 1, 14 + call PlaceHLTextAtBC + call RotateThreePalettesRight + call ClearScreen + ld b, SCGB_DIPLOMA + call GetSGBLayout + call WaitBGMap2 + ret +; 283ed + +.TooMuchTimeHasElapsed: ; 0x283ed + ; Too much time has elapsed. Please try again. + text_jump UnknownText_0x1c4183 + db "@" +; 0x283f2 + +ExchangeBytes: ; 283f2 + ld a, TRUE + ld [hSerialIgnoringInitialData], a +.loop + ld a, [hl] + ld [hSerialSend], a + call Serial_ExchangeByte + push bc + ld b, a + inc hl + ld a, 48 +.delay_cycles + dec a + jr nz, .delay_cycles + ld a, [hSerialIgnoringInitialData] + and a + ld a, b + pop bc + jr z, .load + dec hl + xor a + ld [hSerialIgnoringInitialData], a + jr .loop + +.load + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .loop + ret +; 28419 + +String_PleaseWait: ; 28419 + db "PLEASE WAIT!@" +; 28426 + +ClearLinkData: ; 28426 + ld hl, wLinkData + ld bc, wLinkDataEnd - wLinkData +.loop + xor a + ld [hli], a + dec bc + ld a, b + or c + jr nz, .loop + ret +; 28434 + +FixDataForLinkTransfer: ; 28434 + ld hl, wd1f3 + ld a, SERIAL_PREAMBLE_BYTE + ld b, wLinkBattleRNs - wd1f3 +.loop1 + ld [hli], a + dec b + jr nz, .loop1 + ld b, wTempEnemyMonSpecies - wLinkBattleRNs +.loop2 + call Random + cp SERIAL_PREAMBLE_BYTE + jr nc, .loop2 + ld [hli], a + dec b + jr nz, .loop2 + ld hl, wMisc + ld a, SERIAL_PREAMBLE_BYTE + ld [hli], a + ld [hli], a + ld [hli], a + ld b, $c8 + xor a +.loop3 + ld [hli], a + dec b + jr nz, .loop3 + ld hl, wTimeCapsulePartyMon1 - 1 + 6 + ld de, wc612 + lb bc, 0, 0 +.loop4 + inc c + ld a, c + cp SERIAL_PREAMBLE_BYTE + jr z, .next1 + ld a, b + dec a + jr nz, .next2 + push bc + ld a, [wLinkMode] + cp LINK_TIMECAPSULE + ld b, $d + jr z, .got_value + ld b, $27 +.got_value + ld a, c + cp b + pop bc + jr z, .done +.next2 + inc hl + ld a, [hl] + cp SERIAL_NO_DATA_BYTE + jr nz, .loop4 + ld a, c + ld [de], a + inc de + ld [hl], SERIAL_PATCH_LIST_PART_TERMINATOR + jr .loop4 + +.next1 + ld a, SERIAL_PATCH_LIST_PART_TERMINATOR + ld [de], a + inc de + lb bc, 1, 0 + jr .loop4 + +.done + ld a, SERIAL_PATCH_LIST_PART_TERMINATOR + ld [de], a + ret +; 28499 + +Link_PrepPartyData_Gen1: ; 28499 + ld de, wLinkData + ld a, SERIAL_PREAMBLE_BYTE + ld b, PARTY_LENGTH +.loop1 + ld [de], a + inc de + dec b + jr nz, .loop1 + ld hl, wPlayerName + ld bc, NAME_LENGTH + call CopyBytes + push de + ld hl, wPartyCount + ld a, [hli] + ld [de], a + inc de +.loop2 + ld a, [hli] + cp -1 + jr z, .done_party + ld [wd265], a + push hl + push de + callfar ConvertMon_2to1 + pop de + pop hl + ld a, [wd265] + ld [de], a + inc de + jr .loop2 + +.done_party + ld [de], a + pop de + ld hl, 1 + PARTY_LENGTH + 1 + add hl, de + ld d, h + ld e, l + ld hl, wPartyMon1Species + ld c, PARTY_LENGTH +.mon_loop + push bc + call .ConvertPartyStruct2to1 + ld bc, PARTYMON_STRUCT_LENGTH + add hl, bc + pop bc + dec c + jr nz, .mon_loop + ld hl, wPartyMonOT + call .copy_ot_nicks + ld hl, wPartyMonNicknames +.copy_ot_nicks + ld bc, PARTY_LENGTH * NAME_LENGTH + jp CopyBytes +; 284f6 + +.ConvertPartyStruct2to1: ; 284f6 + ld b, h + ld c, l + push de + push bc + ld a, [hl] + ld [wd265], a + callfar ConvertMon_2to1 + pop bc + pop de + ld a, [wd265] + ld [de], a + inc de + ld hl, MON_HP + add hl, bc + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + inc de + xor a + ld [de], a + inc de + ld hl, MON_STATUS + add hl, bc + ld a, [hl] + ld [de], a + inc de + ld a, [bc] + cp MAGNEMITE + jr z, .steel_type + cp MAGNETON + jr nz, .skip_steel + +.steel_type + ld a, ELECTRIC + ld [de], a + inc de + ld [de], a + inc de + jr .done_steel + +.skip_steel + push bc + dec a + ld hl, BaseData + BASE_TYPES + ld bc, BASE_DATA_SIZE + call AddNTimes + ld bc, BASE_CATCH_RATE - BASE_TYPES + ld a, BANK(BaseData) + call FarCopyBytes + pop bc + +.done_steel + push bc + ld hl, MON_ITEM + add hl, bc + ld bc, MON_HAPPINESS - MON_ITEM + call CopyBytes + pop bc + + ld hl, MON_LEVEL + add hl, bc + ld a, [hl] + ld [de], a + ld [wCurPartyLevel], a + inc de + + push bc + ld hl, MON_MAXHP + add hl, bc + ld bc, MON_SAT - MON_MAXHP + call CopyBytes + pop bc + + push de + push bc + + ld a, [bc] + dec a + push bc + ld b, 0 + ld c, a + ld hl, KantoMonSpecials + add hl, bc + ld a, BANK(KantoMonSpecials) + call GetFarByte + ld [wBaseSpecialAttack], a + pop bc + + ld hl, MON_STAT_EXP - 1 + add hl, bc + ld c, STAT_SATK + ld b, TRUE + predef CalcMonStatC + + pop bc + pop de + + ld a, [hQuotient + 1] + ld [de], a + inc de + ld a, [hQuotient + 2] + ld [de], a + inc de + ld h, b + ld l, c + ret +; 28595 + +Link_PrepPartyData_Gen2: ; 28595 + ld de, wLinkData + ld a, SERIAL_PREAMBLE_BYTE + ld b, PARTY_LENGTH +.loop1 + ld [de], a + inc de + dec b + jr nz, .loop1 + ld hl, wPlayerName + ld bc, NAME_LENGTH + call CopyBytes + ld hl, wPartyCount + ld bc, 1 + PARTY_LENGTH + 1 + call CopyBytes + ld hl, wPlayerID + ld bc, 2 + call CopyBytes + ld hl, wPartyMon1Species + ld bc, PARTY_LENGTH * PARTYMON_STRUCT_LENGTH + call CopyBytes + ld hl, wPartyMonOT + ld bc, PARTY_LENGTH * NAME_LENGTH + call CopyBytes + ld hl, wPartyMonNicknames + ld bc, PARTY_LENGTH * MON_NAME_LENGTH + call CopyBytes + +; Okay, we did all that. Now, are we in the trade center? + ld a, [wLinkMode] + cp LINK_TRADECENTER + ret nz + +; Fill 5 bytes at wc9f4 with $20 + ld de, wc9f4 + ld a, $20 + call Function28682 + +; Copy all the mail messages to wc9f9 + ld a, BANK(sPartyMail) + call GetSRAMBank + ld hl, sPartyMail + ld b, PARTY_LENGTH +.loop2 + push bc + ld bc, MAIL_MSG_LENGTH + 1 + call CopyBytes + ld bc, sPartyMon1MailEnd - sPartyMon1MailAuthor + add hl, bc + pop bc + dec b + jr nz, .loop2 +; Copy the mail data to wcabf + ld hl, sPartyMail + ld b, PARTY_LENGTH +.loop3 + push bc + ld bc, MAIL_MSG_LENGTH + 1 + add hl, bc + ld bc, sPartyMon1MailEnd - sPartyMon1MailAuthor + call CopyBytes + pop bc + dec b + jr nz, .loop3 + + ld b, PARTY_LENGTH + ld de, sPartyMail + ld hl, wc9f9 +.loop4 + push bc + push hl + push de + push hl + farcall IsMailEuropean + pop de + ld a, c + or a + jr z, .next + sub $3 + jr nc, .italian_spanish + farcall HandleFrenchGermanMail + jr .next + +.italian_spanish + cp $2 + jr nc, .next + farcall HandleSpanishItalianMail + +.next + pop de + ld hl, MAIL_STRUCT_LENGTH + add hl, de + ld d, h + ld e, l + pop hl + ld bc, sPartyMon1MailAuthor - sPartyMon1Mail + add hl, bc + pop bc + dec b + jr nz, .loop4 + call CloseSRAM + ld hl, wc9f9 + ld bc, PARTY_LENGTH * (sPartyMon1MailAuthor - sPartyMon1Mail) +.loop5 + ld a, [hl] + cp SERIAL_NO_DATA_BYTE + jr nz, .skip2 + ld [hl], sPartyMon1MailAuthor - sPartyMon1Mail + +.skip2 + inc hl + dec bc + ld a, b + or c + jr nz, .loop5 + ld hl, wcabf + ld de, wcb13 + ld b, PARTY_LENGTH * (sPartyMon1MailEnd - sPartyMon1MailAuthor) + ld c, $0 +.loop6 + inc c + ld a, [hl] + cp SERIAL_NO_DATA_BYTE + jr nz, .skip3 + ld [hl], SERIAL_PATCH_LIST_PART_TERMINATOR + ld a, c + ld [de], a + inc de + +.skip3 + inc hl + dec b + jr nz, .loop6 + ld a, SERIAL_PATCH_LIST_PART_TERMINATOR + ld [de], a + ret +; 28682 + +Function28682: ; 28682 + ld c, 5 +.loop + ld [de], a + inc de + dec c + jr nz, .loop + ret +; 2868a + +Function2868a: ; 2868a + push hl + ld d, h + ld e, l + ld bc, wLinkOTPartyMonTypes + ld hl, wcbe8 + ld a, c + ld [hli], a + ld [hl], b + ld hl, wOTPartyMon1Species + ld c, PARTY_LENGTH +.loop + push bc + call .ConvertToGen2 + pop bc + dec c + jr nz, .loop + pop hl + ld bc, PARTY_LENGTH * REDMON_STRUCT_LENGTH + add hl, bc + ld de, wOTPartyMonOT + ld bc, PARTY_LENGTH * NAME_LENGTH + call CopyBytes + ld de, wOTPartyMonNicknames + ld bc, PARTY_LENGTH * MON_NAME_LENGTH + jp CopyBytes +; 286ba + +.ConvertToGen2: ; 286ba + ld b, h + ld c, l + ld a, [de] + inc de + push bc + push de + ld [wd265], a + callfar ConvertMon_1to2 + pop de + pop bc + ld a, [wd265] + ld [bc], a + ld [wCurSpecies], a + ld hl, MON_HP + add hl, bc + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hl], a + inc de + ld hl, MON_STATUS + add hl, bc + ld a, [de] + inc de + ld [hl], a + ld hl, wcbe8 + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [de] + ld [hli], a + inc de + ld a, [de] + ld [hli], a + inc de + ld a, l + ld [wcbe8], a + ld a, h + ld [wcbe8 + 1], a + push bc + ld hl, MON_ITEM + add hl, bc + push hl + ld h, d + ld l, e + pop de + push bc + ld a, [hli] + ld b, a + call TimeCapsule_ReplaceTeruSama + ld a, b + ld [de], a + inc de + pop bc + ld bc, $19 + call CopyBytes + pop bc + ld d, h + ld e, l + ld hl, $1f + add hl, bc + ld a, [de] + inc de + ld [hl], a + ld [wCurPartyLevel], a + push bc + ld hl, $24 + add hl, bc + push hl + ld h, d + ld l, e + pop de + ld bc, 8 + call CopyBytes + pop bc + call GetBaseData + push de + push bc + ld d, h + ld e, l + ld hl, MON_STAT_EXP - 1 + add hl, bc + ld c, STAT_SATK + ld b, TRUE + predef CalcMonStatC + pop bc + pop hl + ld a, [hQuotient + 1] + ld [hli], a + ld a, [hQuotient + 2] + ld [hli], a + push hl + push bc + ld hl, MON_STAT_EXP - 1 + add hl, bc + ld c, STAT_SDEF + ld b, TRUE + predef CalcMonStatC + pop bc + pop hl + ld a, [hQuotient + 1] + ld [hli], a + ld a, [hQuotient + 2] + ld [hli], a + push hl + ld hl, $1b + add hl, bc + ld a, $46 + ld [hli], a + xor a + ld [hli], a + ld [hli], a + ld [hl], a + pop hl + inc de + inc de + ret +; 28771 + +TimeCapsule_ReplaceTeruSama: ; 28771 + ld a, b + and a + ret z + push hl + ld hl, TimeCapsule_CatchRateItems +.loop + ld a, [hli] + and a + jr z, .end + cp b + jr z, .found + inc hl + jr .loop + +.found + ld b, [hl] + +.end + pop hl + ret + + +INCLUDE "data/items/catch_rate_items.asm" + + +Link_CopyOTData: ; 2879e +.loop + ld a, [hli] + cp SERIAL_NO_DATA_BYTE + jr z, .loop + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .loop + ret +; 287ab + +Link_CopyRandomNumbers: ; 287ab + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + ret z + ld hl, wEnemyMonSpecies + call Link_FindFirstNonControlCharacter_AllowZero + ld de, wLinkBattleRNs + ld c, 10 +.loop + ld a, [hli] + cp SERIAL_NO_DATA_BYTE + jr z, .loop + cp SERIAL_PREAMBLE_BYTE + jr z, .loop + ld [de], a + inc de + dec c + jr nz, .loop + ret +; 287ca + +Link_FindFirstNonControlCharacter_SkipZero: ; 287ca +.loop + ld a, [hli] + and a + jr z, .loop + cp SERIAL_PREAMBLE_BYTE + jr z, .loop + cp SERIAL_NO_DATA_BYTE + jr z, .loop + dec hl + ret +; 287d8 + +Link_FindFirstNonControlCharacter_AllowZero: ; 287d8 +.loop + ld a, [hli] + cp SERIAL_PREAMBLE_BYTE + jr z, .loop + cp SERIAL_NO_DATA_BYTE + jr z, .loop + dec hl + ret +; 287e3 + +InitTradeMenuDisplay: ; 287e3 + call ClearScreen + call LoadTradeScreenBorder + farcall InitTradeSpeciesList + xor a + ld hl, wOtherPlayerLinkMode + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld a, 1 + ld [wMenuCursorY], a + inc a + ld [wPlayerLinkAction], a + jp LinkTrade_PlayerPartyMenu +; 28803 + +LinkTrade_OTPartyMenu: ; 28803 + ld a, OTPARTYMON + ld [wMonType], a + ld a, A_BUTTON | D_UP | D_DOWN + ld [wMenuJoypadFilter], a + ld a, [wOTPartyCount] + ld [w2DMenuNumRows], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 9 + ld [w2DMenuCursorInitY], a + ld a, 6 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [wMenuCursorX], a + ln a, 1, 0 + ld [w2DMenuCursorOffsets], a + ld a, MENU_UNUSED_3 + ld [w2DMenuFlags1], a + xor a + ld [w2DMenuFlags2], a + +LinkTradeOTPartymonMenuLoop: ; 28835 + farcall LinkTradeMenu + ld a, d + and a + jp z, LinkTradePartiesMenuMasterLoop + bit A_BUTTON_F, a + jr z, .not_a_button + ld a, INIT_ENEMYOT_LIST + ld [wInitListType], a + callfar InitList + ld hl, wOTPartyMon1Species + farcall LinkMonStatsScreen + jp LinkTradePartiesMenuMasterLoop + +.not_a_button + bit D_UP_F, a + jr z, .not_d_up + ld a, [wMenuCursorY] + ld b, a + ld a, [wOTPartyCount] + cp b + jp nz, LinkTradePartiesMenuMasterLoop + xor a + ld [wMonType], a + call HideCursor + push hl + push bc + ld bc, NAME_LENGTH + add hl, bc + ld [hl], " " + pop bc + pop hl + ld a, [wPartyCount] + ld [wMenuCursorY], a + jr LinkTrade_PlayerPartyMenu + +.not_d_up + bit D_DOWN_F, a + jp z, LinkTradePartiesMenuMasterLoop + jp Function28ac9 +; 2888b + +LinkTrade_PlayerPartyMenu: ; 2888b + farcall InitMG_Mobile_LinkTradePalMap + xor a + ld [wMonType], a + ld a, A_BUTTON | D_UP | D_DOWN + ld [wMenuJoypadFilter], a + ld a, [wPartyCount] + ld [w2DMenuNumRows], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 1 + ld [w2DMenuCursorInitY], a + ld a, 6 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [wMenuCursorX], a + ln a, 1, 0 + ld [w2DMenuCursorOffsets], a + ld a, MENU_UNUSED_3 + ld [w2DMenuFlags1], a + xor a + ld [w2DMenuFlags2], a + call WaitBGMap2 + +LinkTradePartymonMenuLoop: ; 288c5 + farcall LinkTradeMenu + ld a, d + and a + jr nz, .check_joypad + jp LinkTradePartiesMenuMasterLoop + +.check_joypad + bit A_BUTTON_F, a + jr z, .not_a_button + jp Function28926 + +.not_a_button + bit D_DOWN_F, a + jr z, .not_d_down + ld a, [wMenuCursorY] + dec a + jp nz, LinkTradePartiesMenuMasterLoop + ld a, OTPARTYMON + ld [wMonType], a + call HideCursor + push hl + push bc + ld bc, NAME_LENGTH + add hl, bc + ld [hl], " " + pop bc + pop hl + ld a, 1 + ld [wMenuCursorY], a + jp LinkTrade_OTPartyMenu + +.not_d_down + bit D_UP_F, a + jr z, LinkTradePartiesMenuMasterLoop + ld a, [wMenuCursorY] + ld b, a + ld a, [wPartyCount] + cp b + jr nz, LinkTradePartiesMenuMasterLoop + call HideCursor + push hl + push bc + ld bc, NAME_LENGTH + add hl, bc + ld [hl], " " + pop bc + pop hl + jp Function28ade +; 2891c + +LinkTradePartiesMenuMasterLoop: ; 2891c + ld a, [wMonType] + and a + jp z, LinkTradePartymonMenuLoop ; PARTYMON + jp LinkTradeOTPartymonMenuLoop ; OTPARTYMON +; 28926 + +Function28926: ; 28926 + call LoadTileMapToTempTileMap + ld a, [wMenuCursorY] + push af + hlcoord 0, 15 + ld b, 1 + ld c, 18 + call LinkTextboxAtHL + hlcoord 2, 16 + ld de, .String_Stats_Trade + call PlaceString + farcall Link_WaitBGMap + +.joy_loop + ld a, " " + ldcoord_a 11, 16 + ld a, A_BUTTON | B_BUTTON | D_RIGHT + ld [wMenuJoypadFilter], a + ld a, 1 + ld [w2DMenuNumRows], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 16 + ld [w2DMenuCursorInitY], a + ld a, 1 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [wMenuCursorY], a + ld [wMenuCursorX], a + ln a, 2, 0 + ld [w2DMenuCursorOffsets], a + xor a + ld [w2DMenuFlags1], a + ld [w2DMenuFlags2], a + call ScrollingMenuJoypad + bit D_RIGHT_F, a + jr nz, .d_right + bit B_BUTTON_F, a + jr z, .show_stats +.b_button + pop af + ld [wMenuCursorY], a + call Call_LoadTempTileMapToTileMap + jp LinkTrade_PlayerPartyMenu + +.d_right + ld a, " " + ldcoord_a 1, 16 + ld a, A_BUTTON | B_BUTTON | D_LEFT + ld [wMenuJoypadFilter], a + ld a, 1 + ld [w2DMenuNumRows], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 16 + ld [w2DMenuCursorInitY], a + ld a, 11 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [wMenuCursorY], a + ld [wMenuCursorX], a + ln a, 2, 0 + ld [w2DMenuCursorOffsets], a + xor a + ld [w2DMenuFlags1], a + ld [w2DMenuFlags2], a + call ScrollingMenuJoypad + bit D_LEFT_F, a + jp nz, .joy_loop + bit B_BUTTON_F, a + jr nz, .b_button + jr .try_trade + +.show_stats + pop af + ld [wMenuCursorY], a + ld a, INIT_PLAYEROT_LIST + ld [wInitListType], a + callfar InitList + farcall LinkMonStatsScreen + call Call_LoadTempTileMapToTileMap + hlcoord 6, 1 + lb bc, 6, 1 + ld a, " " + call LinkEngine_FillBox + hlcoord 17, 1 + lb bc, 6, 1 + ld a, " " + call LinkEngine_FillBox + jp LinkTrade_PlayerPartyMenu + +.try_trade + call PlaceHollowCursor + pop af + ld [wMenuCursorY], a + dec a + ld [wd002], a + ld [wPlayerLinkAction], a + farcall Function16d6ce + ld a, [wOtherPlayerLinkMode] + cp $f + jp z, InitTradeMenuDisplay + ld [wd003], a + call Function28b68 + ld c, 100 + call DelayFrames + farcall ValidateOTTrademon + jr c, .abnormal + farcall Functionfb5dd + jp nc, LinkTrade + xor a + ld [wcf57], a + ld [wOtherPlayerLinkAction], a + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + farcall Link_WaitBGMap + ld hl, .Text_CantTradeLastMon + bccoord 1, 14 + call PlaceHLTextAtBC + jr .cancel_trade + +.abnormal + xor a + ld [wcf57], a + ld [wOtherPlayerLinkAction], a + ld a, [wd003] + ld hl, wOTPartySpecies + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wd265], a + call GetPokemonName + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + farcall Link_WaitBGMap + ld hl, .Text_Abnormal + bccoord 1, 14 + call PlaceHLTextAtBC + +.cancel_trade + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + hlcoord 1, 14 + ld de, String_TooBadTheTradeWasCanceled + call PlaceString + ld a, $1 + ld [wPlayerLinkAction], a + farcall Function16d6ce + ld c, 100 + call DelayFrames + jp InitTradeMenuDisplay +; 28aaf + + +.Text_CantTradeLastMon: ; 0x28aaf + ; If you trade that #MON, you won't be able to battle. + text_jump UnknownText_0x1c41b1 + db "@" +; 0x28ab4 + +.String_Stats_Trade: ; 28ab4 + db "STATS TRADE@" + +.Text_Abnormal: ; 0x28ac4 + ; Your friend's @ appears to be abnormal! + text_jump UnknownText_0x1c41e6 + db "@" +; 0x28ac9 + + +Function28ac9: ; 28ac9 + ld a, [wMenuCursorY] + cp 1 + jp nz, LinkTradePartiesMenuMasterLoop + call HideCursor + push hl + push bc + ld bc, NAME_LENGTH + add hl, bc + ld [hl], " " + pop bc + pop hl +Function28ade: ; 28ade +.loop1 + ld a, "▶" + ldcoord_a 9, 17 +.loop2 + call JoyTextDelay + ld a, [hJoyLast] + and a + jr z, .loop2 + bit A_BUTTON_F, a + jr nz, .a_button + push af + ld a, " " + ldcoord_a 9, 17 + pop af + bit D_UP_F, a + jr z, .d_up + ld a, [wOTPartyCount] + ld [wMenuCursorY], a + jp LinkTrade_OTPartyMenu + +.d_up + ld a, $1 + ld [wMenuCursorY], a + jp LinkTrade_PlayerPartyMenu + +.a_button + ld a, "▷" + ldcoord_a 9, 17 + ld a, $f + ld [wPlayerLinkAction], a + farcall Function16d6ce + ld a, [wOtherPlayerLinkMode] + cp $f + jr nz, .loop1 +Function28b22: ; 28b22 + call RotateThreePalettesRight + call ClearScreen + ld b, SCGB_DIPLOMA + call GetSGBLayout + call WaitBGMap2 + xor a + ld [wcfbb], a + xor a + ld [rSB], a + ld [hSerialSend], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + ret +; 28b42 + +Unreferenced_Function28b42: ; 28b42 + hlcoord 0, 16 + ld a, "┘" + ld bc, 2 * SCREEN_WIDTH + call ByteFill + hlcoord 1, 16 + ld a, " " + ld bc, SCREEN_WIDTH - 2 + call ByteFill + hlcoord 2, 16 + ld de, .Cancel + jp PlaceString +; 28b61 + +.Cancel: ; 28b61 + db "CANCEL@" +; 28b68 + +Function28b68: ; 28b68 + ld a, [wOtherPlayerLinkMode] + hlcoord 6, 9 + ld bc, SCREEN_WIDTH + call AddNTimes + ld [hl], "▷" + ret +; 28b77 + +LinkEngine_FillBox: ; 28b77 +.row + push bc + push hl +.col + ld [hli], a + dec c + jr nz, .col + pop hl + ld bc, SCREEN_WIDTH + add hl, bc + pop bc + dec b + jr nz, .row + ret +; 28b87 + +LinkTrade: ; 28b87 + xor a + ld [wcf57], a + ld [wOtherPlayerLinkAction], a + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + farcall Link_WaitBGMap + ld a, [wd002] + ld hl, wPartySpecies + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wd265], a + call GetPokemonName + ld hl, wStringBuffer1 + ld de, wd004 + ld bc, MON_NAME_LENGTH + call CopyBytes + ld a, [wd003] + ld hl, wOTPartySpecies + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wd265], a + call GetPokemonName + ld hl, UnknownText_0x28eb8 + bccoord 1, 14 + call PlaceHLTextAtBC + call LoadStandardMenuHeader + hlcoord 10, 7 + ld b, 3 + ld c, 7 + call LinkTextboxAtHL + ld de, String28eab + hlcoord 12, 8 + call PlaceString + ld a, 8 + ld [w2DMenuCursorInitY], a + ld a, 11 + ld [w2DMenuCursorInitX], a + ld a, 1 + ld [w2DMenuNumCols], a + ld a, 2 + ld [w2DMenuNumRows], a + xor a + ld [w2DMenuFlags1], a + ld [w2DMenuFlags2], a + ld a, $20 + ld [w2DMenuCursorOffsets], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuJoypadFilter], a + ld a, 1 + ld [wMenuCursorY], a + ld [wMenuCursorX], a + farcall Link_WaitBGMap + call ScrollingMenuJoypad + push af + call Call_ExitMenu + call WaitBGMap2 + pop af + bit 1, a + jr nz, .asm_28c33 + ld a, [wMenuCursorY] + dec a + jr z, .asm_28c54 + +.asm_28c33 + ld a, $1 + ld [wPlayerLinkAction], a + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + hlcoord 1, 14 + ld de, String_TooBadTheTradeWasCanceled + call PlaceString + farcall Function16d6ce + jp Function28ea3 + +.asm_28c54 + ld a, $2 + ld [wPlayerLinkAction], a + farcall Function16d6ce + ld a, [wOtherPlayerLinkMode] + dec a + jr nz, .asm_28c7b + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + hlcoord 1, 14 + ld de, String_TooBadTheTradeWasCanceled + call PlaceString + jp Function28ea3 + +.asm_28c7b + ld hl, sPartyMail + ld a, [wd002] + ld bc, MAIL_STRUCT_LENGTH + call AddNTimes + ld a, BANK(sPartyMail) + call GetSRAMBank + ld d, h + ld e, l + ld bc, MAIL_STRUCT_LENGTH + add hl, bc + ld a, [wd002] + ld c, a +.asm_28c96 + inc c + ld a, c + cp PARTY_LENGTH + jr z, .asm_28ca6 + push bc + ld bc, MAIL_STRUCT_LENGTH + call CopyBytes + pop bc + jr .asm_28c96 + +.asm_28ca6 + ld hl, sPartyMail + ld a, [wPartyCount] + dec a + ld bc, MAIL_STRUCT_LENGTH + call AddNTimes + push hl + ld hl, wc9f4 + ld a, [wd003] + ld bc, MAIL_STRUCT_LENGTH + call AddNTimes + pop de + ld bc, MAIL_STRUCT_LENGTH + call CopyBytes + call CloseSRAM + ld hl, wPlayerName + ld de, wPlayerTrademonSenderName + ld bc, NAME_LENGTH + call CopyBytes + ld a, [wd002] + ld hl, wPartySpecies + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + ld [wPlayerTrademonSpecies], a + push af + ld a, [wd002] + ld hl, wPartyMonOT + call SkipNames + ld de, wPlayerTrademonOTName + ld bc, NAME_LENGTH + call CopyBytes + ld hl, wPartyMon1ID + ld a, [wd002] + call GetPartyLocation + ld a, [hli] + ld [wPlayerTrademonID], a + ld a, [hl] + ld [wPlayerTrademonID + 1], a + ld hl, wPartyMon1DVs + ld a, [wd002] + call GetPartyLocation + ld a, [hli] + ld [wPlayerTrademonDVs], a + ld a, [hl] + ld [wPlayerTrademonDVs + 1], a + ld a, [wd002] + ld hl, wPartyMon1Species + call GetPartyLocation + ld b, h + ld c, l + farcall GetCaughtGender + ld a, c + ld [wPlayerTrademonCaughtData], a + ld hl, wOTPlayerName + ld de, wOTTrademonSenderName + ld bc, NAME_LENGTH + call CopyBytes + ld a, [wd003] + ld hl, wOTPartySpecies + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + ld [wOTTrademonSpecies], a + ld a, [wd003] + ld hl, wOTPartyMonOT + call SkipNames + ld de, wOTTrademonOTName + ld bc, NAME_LENGTH + call CopyBytes + ld hl, wOTPartyMon1ID + ld a, [wd003] + call GetPartyLocation + ld a, [hli] + ld [wOTTrademonID], a + ld a, [hl] + ld [wOTTrademonID + 1], a + ld hl, wOTPartyMon1DVs + ld a, [wd003] + call GetPartyLocation + ld a, [hli] + ld [wOTTrademonDVs], a + ld a, [hl] + ld [wOTTrademonDVs + 1], a + ld a, [wd003] + ld hl, wOTPartyMon1Species + call GetPartyLocation + ld b, h + ld c, l + farcall GetCaughtGender + ld a, c + ld [wOTTrademonCaughtData], a + ld a, [wd002] + ld [wCurPartyMon], a + ld hl, wPartySpecies + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + ld [wd002], a + xor a ; REMOVE_PARTY + ld [wPokemonWithdrawDepositParameter], a + callfar RemoveMonFromPartyOrBox + ld a, [wPartyCount] + dec a + ld [wCurPartyMon], a + ld a, TRUE + ld [wForceEvolution], a + ld a, [wd003] + push af + ld hl, wOTPartySpecies + ld b, 0 + ld c, a + add hl, bc + ld a, [hl] + ld [wd003], a + ld c, 100 + call DelayFrames + call ClearTileMap + call LoadFontsBattleExtra + ld b, SCGB_DIPLOMA + call GetSGBLayout + ld a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + jr z, .player_2 + predef TradeAnimation + jr .done_animation + +.player_2 + predef TradeAnimationPlayer2 + +.done_animation + pop af + ld c, a + ld [wCurPartyMon], a + ld hl, wOTPartySpecies + ld d, 0 + ld e, a + add hl, de + ld a, [hl] + ld [wCurPartySpecies], a + ld hl, wOTPartyMon1Species + ld a, c + call GetPartyLocation + ld de, wTempMonSpecies + ld bc, PARTYMON_STRUCT_LENGTH + call CopyBytes + predef AddTempmonToParty + ld a, [wPartyCount] + dec a + ld [wCurPartyMon], a + callfar EvolvePokemon + call ClearScreen + call LoadTradeScreenBorder + call SetTradeRoomBGPals + farcall Link_WaitBGMap + ld b, $1 + pop af + ld c, a + cp MEW + jr z, .loop + ld a, [wCurPartySpecies] + cp MEW + jr z, .loop + ld b, $2 + ld a, c + cp CELEBI + jr z, .loop + ld a, [wCurPartySpecies] + cp CELEBI + jr z, .loop + ld b, $0 + +.loop + ld a, b + ld [wPlayerLinkAction], a + push bc + call Serial_PrintWaitingTextAndSyncAndExchangeNybble + pop bc + ld a, [wLinkMode] + cp LINK_TIMECAPSULE + jr z, .save + ld a, b + and a + jr z, .save + ld a, [wOtherPlayerLinkAction] + cp b + jr nz, .loop + +.save + farcall SaveAfterLinkTrade + farcall StubbedTrainerRankings_Trades + farcall BackupMobileEventIndex + ld c, 40 + call DelayFrames + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call LinkTextboxAtHL + hlcoord 1, 14 + ld de, String28ebd + call PlaceString + farcall Link_WaitBGMap + ld c, 50 + call DelayFrames + ld a, [wLinkMode] + cp LINK_TIMECAPSULE + jp z, Gen2ToGen1LinkComms + jp Gen2ToGen2LinkComms +; 28ea3 + +Function28ea3: ; 28ea3 + ld c, 100 + call DelayFrames + jp InitTradeMenuDisplay +; 28eab + +String28eab: ; 28eab + db "TRADE" + next "CANCEL@" + +UnknownText_0x28eb8: ; 0x28eb8 + ; Trade @ for @ ? + text_jump UnknownText_0x1c4212 + db "@" +; 0x28ebd + +String28ebd: ; 28ebd + db "Trade completed!@" + +String_TooBadTheTradeWasCanceled: ; 28ece + db "Too bad! The trade" + next "was canceled!@" + + +LinkTextboxAtHL: ; 28eef + ld d, h + ld e, l + farcall LinkTextbox + ret +; 28ef8 + +LoadTradeScreenBorder: ; 28ef8 + farcall _LoadTradeScreenBorder + ret +; 28eff + +SetTradeRoomBGPals: ; 28eff + farcall LoadTradeRoomBGPals_ ; just a nested farcall; so wasteful + call SetPalettes + ret +; 28f09 + +Unreferenced_Function28f09: ; 28f09 + hlcoord 0, 0 + ld b, 6 + ld c, 18 + call LinkTextboxAtHL + hlcoord 0, 8 + ld b, 6 + ld c, 18 + call LinkTextboxAtHL + farcall PlaceTradePartnerNamesAndParty + ret +; 28f24 + +INCLUDE "engine/gfx/trade_animation.asm" + +CheckTimeCapsuleCompatibility: ; 29bfb +; Checks to see if your party is compatible with the Gen 1 games. +; Returns the following in wScriptVar: +; 0: Party is okay +; 1: At least one Pokémon was introduced in Gen 2 +; 2: At least one Pokémon has a move that was introduced in Gen 2 +; 3: At least one Pokémon is holding mail + +; If any party Pokémon was introduced in the Gen 2 games, don't let it in. + ld hl, wPartySpecies + ld b, PARTY_LENGTH +.loop + ld a, [hli] + cp -1 + jr z, .checkitem + cp JOHTO_POKEMON + jr nc, .mon_too_new + dec b + jr nz, .loop + +; If any party Pokémon is holding mail, don't let it in. +.checkitem + ld a, [wPartyCount] + ld b, a + ld hl, wPartyMon1Item +.itemloop + push hl + push bc + ld d, [hl] + farcall ItemIsMail + pop bc + pop hl + jr c, .mon_has_mail + ld de, PARTYMON_STRUCT_LENGTH + add hl, de + dec b + jr nz, .itemloop + +; If any party Pokémon has a move that was introduced in the Gen 2 games, don't let it in. + ld hl, wPartyMon1Moves + ld a, [wPartyCount] + ld b, a +.move_loop + ld c, NUM_MOVES +.move_next + ld a, [hli] + cp STRUGGLE + 1 + jr nc, .move_too_new + dec c + jr nz, .move_next + ld de, wPartyMon2 - (wPartyMon1 + NUM_MOVES) + add hl, de + dec b + jr nz, .move_loop + xor a + jr .done + +.mon_too_new + ld [wd265], a + call GetPokemonName + ld a, $1 + jr .done + +.move_too_new + push bc + ld [wd265], a + call GetMoveName + call CopyName1 + pop bc + call Function29c67 + ld a, $2 + jr .done + +.mon_has_mail + call Function29c67 + ld a, $3 + +.done + ld [wScriptVar], a + ret +; 29c67 + +Function29c67: ; 29c67 + ld a, [wPartyCount] + sub b + ld c, a + inc c + ld b, 0 + ld hl, wPartyCount + add hl, bc + ld a, [hl] + ld [wd265], a + call GetPokemonName + ret +; 29c7b + +EnterTimeCapsule: ; 29c7b + ld c, 10 + call DelayFrames + ld a, $4 + call Link_EnsureSync + ld c, 40 + call DelayFrames + xor a + ld [hVBlank], a + inc a + ld [wLinkMode], a + ret +; 29c92 + +WaitForOtherPlayerToExit: ; 29c92 + ld c, 3 + call DelayFrames + ld a, CONNECTION_NOT_ESTABLISHED + ld [hSerialConnectionStatus], a + xor a + ld [rSB], a + ld [hSerialReceive], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + ld c, 3 + call DelayFrames + xor a + ld [rSB], a + ld [hSerialReceive], a + ld a, (0 << rSC_ON) | 0 + ld [rSC], a + ld a, (1 << rSC_ON) | 0 + ld [rSC], a + ld c, 3 + call DelayFrames + xor a + ld [rSB], a + ld [hSerialReceive], a + ld [rSC], a + ld c, 3 + call DelayFrames + ld a, CONNECTION_NOT_ESTABLISHED + ld [hSerialConnectionStatus], a + ld a, [rIF] + push af + xor a + ld [rIF], a + ld a, $f + ld [rIE], a + pop af + ld [rIF], a + ld hl, wLinkTimeoutFrames + xor a + ld [hli], a + ld [hl], a + ld [hVBlank], a + ld [wLinkMode], a + ret +; 29ce8 + +SetBitsForLinkTradeRequest: ; 29ce8 + ld a, LINK_TRADECENTER - 1 + ld [wPlayerLinkAction], a + ld [wd265], a + ret +; 29cf1 + +SetBitsForBattleRequest: ; 29cf1 + ld a, LINK_COLOSSEUM - 1 + ld [wPlayerLinkAction], a + ld [wd265], a + ret +; 29cfa + +SetBitsForTimeCapsuleRequest: ; 29cfa + ld a, $2 + ld [rSB], a + xor a + ld [hSerialReceive], a + ld a, (0 << rSC_ON) | 0 + ld [rSC], a + ld a, (1 << rSC_ON) | 0 + ld [rSC], a + xor a ; LINK_TIMECAPSULE - 1 + ld [wPlayerLinkAction], a + ld [wd265], a + ret +; 29d11 + +WaitForLinkedFriend: ; 29d11 + ld a, [wPlayerLinkAction] + and a + jr z, .no_link_action + ld a, $2 + ld [rSB], a + xor a + ld [hSerialReceive], a + ld a, (0 << rSC_ON) | 0 + ld [rSC], a + ld a, (1 << rSC_ON) | 0 + ld [rSC], a + call DelayFrame + call DelayFrame + call DelayFrame + +.no_link_action + ld a, $2 + ld [wLinkTimeoutFrames + 1], a + ld a, $ff + ld [wLinkTimeoutFrames], a +.loop + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .connected + cp USING_EXTERNAL_CLOCK + jr z, .connected + ld a, CONNECTION_NOT_ESTABLISHED + ld [hSerialConnectionStatus], a + ld a, $2 + ld [rSB], a + xor a + ld [hSerialReceive], a + ld a, (0 << rSC_ON) | 0 + ld [rSC], a + ld a, (1 << rSC_ON) | 0 + ld [rSC], a + ld a, [wLinkTimeoutFrames] + dec a + ld [wLinkTimeoutFrames], a + jr nz, .not_done + ld a, [wLinkTimeoutFrames + 1] + dec a + ld [wLinkTimeoutFrames + 1], a + jr z, .done + +.not_done + ld a, $1 + ld [rSB], a + ld a, (0 << rSC_ON) | 1 + ld [rSC], a + ld a, (1 << rSC_ON) | 1 + ld [rSC], a + call DelayFrame + jr .loop + +.connected + call LinkDataReceived + call DelayFrame + call LinkDataReceived + ld c, 50 + call DelayFrames + ld a, $1 + ld [wScriptVar], a + ret + +.done + xor a + ld [wScriptVar], a + ret +; 29d92 + +CheckLinkTimeout: ; 29d92 + ld a, $1 + ld [wPlayerLinkAction], a + ld hl, wLinkTimeoutFrames + ld a, $3 + ld [hli], a + xor a + ld [hl], a + call WaitBGMap + ld a, $2 + ld [hVBlank], a + call DelayFrame + call DelayFrame + call Link_CheckCommunicationError + xor a + ld [hVBlank], a + ld a, [wScriptVar] + and a + ret nz + jp Link_ResetSerialRegistersAfterLinkClosure +; 29dba + +Function29dba: ; 29dba + ld a, $5 + ld [wPlayerLinkAction], a + ld hl, wLinkTimeoutFrames + ld a, $3 + ld [hli], a + xor a + ld [hl], a + call WaitBGMap + ld a, $2 + ld [hVBlank], a + call DelayFrame + call DelayFrame + call Link_CheckCommunicationError + ld a, [wScriptVar] + and a + jr z, .vblank + ld bc, -1 +.wait + dec bc + ld a, b + or c + jr nz, .wait + ld a, [wOtherPlayerLinkMode] + cp $5 + jr nz, .script_var + ld a, $6 + ld [wPlayerLinkAction], a + ld hl, wLinkTimeoutFrames + ld a, $1 + ld [hli], a + ld [hl], $32 + call Link_CheckCommunicationError + ld a, [wOtherPlayerLinkMode] + cp $6 + jr z, .vblank + +.script_var + xor a + ld [wScriptVar], a + ret + +.vblank + xor a + ld [hVBlank], a + ret +; 29e0c + +Link_CheckCommunicationError: ; 29e0c + xor a + ld [hSerialReceivedNewData], a + ld a, [wLinkTimeoutFrames] + ld h, a + ld a, [wLinkTimeoutFrames + 1] + ld l, a + push hl + call .CheckConnected + pop hl + jr nz, .load_true + call .AcknowledgeSerial + call .ConvertDW + call .CheckConnected + jr nz, .load_true + call .AcknowledgeSerial + xor a + jr .load_scriptvar + +.load_true + ld a, $1 + +.load_scriptvar + ld [wScriptVar], a + ld hl, wLinkTimeoutFrames + xor a + ld [hli], a + ld [hl], a + ret +; 29e3b + +.CheckConnected: ; 29e3b + call WaitLinkTransfer + ld hl, wLinkTimeoutFrames + ld a, [hli] + inc a + ret nz + ld a, [hl] + inc a + ret +; 29e47 + +.AcknowledgeSerial: ; 29e47 + ld b, 10 +.loop + call DelayFrame + call LinkDataReceived + dec b + jr nz, .loop + ret +; 29e53 + +.ConvertDW: ; 29e53 + ; [wLinkTimeoutFrames] = ((hl - $100) / 4) + $100 + ; = (hl / 4) + $c0 + dec h + srl h + rr l + srl h + rr l + inc h + ld a, h + ld [wLinkTimeoutFrames], a + ld a, l + ld [wLinkTimeoutFrames + 1], a + ret +; 29e66 + +TryQuickSave: ; 29e66 + ld a, [wd265] + push af + farcall Link_SaveGame + ld a, TRUE + jr nc, .return_result + xor a ; FALSE +.return_result + ld [wScriptVar], a + ld c, 30 + call DelayFrames + pop af + ld [wd265], a + ret +; 29e82 + +CheckBothSelectedSameRoom: ; 29e82 + ld a, [wd265] + call Link_EnsureSync + push af + call LinkDataReceived + call DelayFrame + call LinkDataReceived + pop af + ld b, a + ld a, [wd265] + cp b + jr nz, .fail + ld a, [wd265] + inc a + ld [wLinkMode], a + xor a + ld [hVBlank], a + ld a, TRUE + ld [wScriptVar], a + ret + +.fail + xor a ; FALSE + ld [wScriptVar], a + ret +; 29eaf + +TimeCapsule: ; 29eaf + ld a, LINK_TIMECAPSULE + ld [wLinkMode], a + call DisableSpriteUpdates + callfar LinkCommunications + call EnableSpriteUpdates + xor a + ld [hVBlank], a + ret +; 29ec4 + +TradeCenter: ; 29ec4 + ld a, LINK_TRADECENTER + ld [wLinkMode], a + call DisableSpriteUpdates + callfar LinkCommunications + call EnableSpriteUpdates + xor a + ld [hVBlank], a + ret +; 29ed9 + +Colosseum: ; 29ed9 + ld a, LINK_COLOSSEUM + ld [wLinkMode], a + call DisableSpriteUpdates + callfar LinkCommunications + call EnableSpriteUpdates + xor a + ld [hVBlank], a + ret +; 29eee + +CloseLink: ; 29eee + xor a + ld [wLinkMode], a + ld c, 3 + call DelayFrames + jp Link_ResetSerialRegistersAfterLinkClosure +; 29efa + +FailedLinkToPast: ; 29efa + ld c, 40 + call DelayFrames + ld a, $e + jp Link_EnsureSync +; 29f04 + +Link_ResetSerialRegistersAfterLinkClosure: ; 29f04 + ld c, 3 + call DelayFrames + ld a, CONNECTION_NOT_ESTABLISHED + ld [hSerialConnectionStatus], a + ld a, $2 + ld [rSB], a + xor a + ld [hSerialReceive], a + ld [rSC], a + ret +; 29f17 + +Link_EnsureSync: ; 29f17 + add $d0 + ld [wPlayerLinkAction], a + ld [wcf57], a + ld a, $2 + ld [hVBlank], a + call DelayFrame + call DelayFrame +.receive_loop + call Serial_ExchangeLinkMenuSelection + ld a, [wOtherPlayerLinkMode] + ld b, a + and $f0 + cp $d0 + jr z, .done + ld a, [wOtherPlayerLinkAction] + ld b, a + and $f0 + cp $d0 + jr nz, .receive_loop + +.done + xor a + ld [hVBlank], a + ld a, b + and $f + ret +; 29f47 + +CableClubCheckWhichChris: ; 29f47 + ld a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + ld a, TRUE + jr z, .yes + dec a ; FALSE + +.yes + ld [wScriptVar], a + ret +; 29f54 + +Unreferenced_Gen1LinkCommsBorderGFX: ; 29f54 +INCBIN "gfx/trade/unused_gen_1_border_tiles.2bpp" +; 29fe4 + +Unreferenced_Function29fe4: + ld a, BANK(sPartyMail) + call GetSRAMBank + ld d, FALSE + ld b, CHECK_FLAG + predef SmallFarFlagAction + call CloseSRAM + ld a, c + and a + ret |