shithub: pokecrystal

Download patch

ref: c5f16c86c80b1b486c534ec855e46d455721c813
parent: 2137f0be09d8ad5ff2d995725dee273b55dbcc04
parent: 354fefaefbba77a3408fa9edb5cc4393b9c702ab
author: Jacob Moody <[email protected]>
date: Fri Apr 28 02:45:20 EDT 2023

merge from upstream

--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -69,9 +69,8 @@
 
       - name: Update symbols
         if: ${{ github.event_name == 'push' && github.repository_owner == 'pret' }}
-        uses: EndBug/add-and-commit@v7
+        uses: EndBug/add-and-commit@v9
         with:
-          branch: symbols
           cwd: "./symbols"
           add: "*.sym"
           message: ${{ github.event.commits[0].message }}
--- a/constants/item_data_constants.asm
+++ b/constants/item_data_constants.asm
@@ -59,6 +59,14 @@
 DEF MAIL_STRUCT_LENGTH    EQU $2f ; mailmsg struct
 DEF MAIL_STRUCT_LENGTH_JP EQU $2a ; mailmsg_jp struct
 
+; mail languages
+	const_def
+	const MAIL_LANG_ENGLISH
+	const MAIL_LANG_FRENCH
+	const MAIL_LANG_GERMAN
+	const MAIL_LANG_ITALIAN
+	const MAIL_LANG_SPANISH
+
 ; held item effects
 	const_def
 	const HELD_NONE
--- a/constants/serial_constants.asm
+++ b/constants/serial_constants.asm
@@ -19,8 +19,10 @@
 DEF USING_INTERNAL_CLOCK       EQU $02
 DEF CONNECTION_NOT_ESTABLISHED EQU $ff
 
-; length of a patch list (less than any of the signal bytes)
-DEF SERIAL_PATCH_LIST_LENGTH          EQU $fc
+; length of a patch list
+DEF SERIAL_PATCH_LIST_LENGTH          EQU 200
+; size of the patch area (offsets into this area may not have special values)
+DEF SERIAL_PATCH_DATA_SIZE            EQU $fc
 ; signals the start of an array of bytes transferred over the link cable
 DEF SERIAL_PREAMBLE_BYTE              EQU $fd
 ; this byte is used when there is no data to send
@@ -30,15 +32,17 @@
 ; used to replace SERIAL_NO_DATA_BYTE
 DEF SERIAL_PATCH_REPLACEMENT_BYTE     EQU $ff
 
-DEF SERIAL_PREAMBLE_LENGTH            EQU 6
-DEF SERIAL_RN_PREAMBLE_LENGTH         EQU 7
-DEF SERIAL_RNS_LENGTH                 EQU 10
+DEF SERIAL_PREAMBLE_LENGTH       EQU 6
+DEF SERIAL_RN_PREAMBLE_LENGTH    EQU 7
+DEF SERIAL_PATCH_PREAMBLE_LENGTH EQU 3
+DEF SERIAL_RNS_LENGTH            EQU 10
 
-DEF SERIAL_MAIL_PREAMBLE_BYTE         EQU $20
-DEF SERIAL_MAIL_REPLACEMENT_BYTE      EQU $21
-DEF SERIAL_MAIL_PREAMBLE_LENGTH       EQU 5
+DEF SERIAL_MAIL_PREAMBLE_BYTE    EQU $20
+DEF SERIAL_MAIL_PREAMBLE_LENGTH  EQU 5
+; used to replace SERIAL_NO_DATA_BYTE
+DEF SERIAL_MAIL_REPLACEMENT_BYTE EQU $21
 
 ; timeout duration after exchanging a byte
-DEF SERIAL_LINK_BYTE_TIMEOUT          EQU $5000
+DEF SERIAL_LINK_BYTE_TIMEOUT EQU $5000
 
-DEF MAX_MYSTERY_GIFT_PARTNERS         EQU 5
+DEF MAX_MYSTERY_GIFT_PARTNERS EQU 5
--- a/docs/bugs_and_glitches.md
+++ b/docs/bugs_and_glitches.md
@@ -614,10 +614,15 @@
 ```diff
  CheckHiddenOpponent:
 -; BUG: Lock-On and Mind Reader don't always bypass Fly and Dig (see docs/bugs_and_glitches.md)
--	ld a, BATTLE_VARS_SUBSTATUS3_OPP
--	call GetBattleVar
--	and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
-+	xor a
++	ld a, BATTLE_VARS_SUBSTATUS5_OPP
++	call GetBattleVar
++	cpl
++	and 1 << SUBSTATUS_LOCK_ON
++	ret z
++
+ 	ld a, BATTLE_VARS_SUBSTATUS3_OPP
+ 	call GetBattleVar
+ 	and 1 << SUBSTATUS_FLYING | 1 << SUBSTATUS_UNDERGROUND
  	ret
 ```
 
--- a/engine/link/link.asm
+++ b/engine/link/link.asm
@@ -90,7 +90,7 @@
 
 	ld hl, wLinkData
 	ld de, wOTPartyData
-	ld bc, SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + 1 + PARTY_LENGTH + 1 + (REDMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
+	ld bc, SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + (1 + PARTY_LENGTH + 1) + (REDMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
 	vc_hook Wireless_ExchangeBytes_Gen2toGen1_party_structs
 	call Serial_ExchangeBytes
 	ld a, SERIAL_NO_DATA_BYTE
@@ -98,7 +98,7 @@
 
 	ld hl, wPlayerPatchLists
 	ld de, wOTPatchLists
-	ld bc, 200
+	ld bc, SERIAL_PATCH_LIST_LENGTH
 	vc_hook Wireless_ExchangeBytes_Gen2toGen1_patch_lists
 	call Serial_ExchangeBytes
 
@@ -122,11 +122,11 @@
 	jp nc, ExitLinkCommunications
 
 	ld de, wLinkData
-	ld bc, NAME_LENGTH + 1 + PARTY_LENGTH + 1 + (REDMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
+	ld bc, NAME_LENGTH + (1 + PARTY_LENGTH + 1) + (REDMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
 	call Link_CopyOTData
 
 	ld de, wOTPatchLists
-	ld hl, wLinkPatchList1
+	ld hl, wTimeCapsulePlayerData
 	ld c, 2
 .loop
 	ld a, [de]
@@ -152,11 +152,11 @@
 	jr .loop
 
 .next
-	ld hl, wLinkPatchList2
+	ld hl, wTimeCapsulePlayerData + SERIAL_PATCH_DATA_SIZE
 	dec c
 	jr nz, .loop
 
-	ld hl, wLinkPlayerName
+	ld hl, wLinkData
 	ld de, wOTPlayerName
 	ld bc, NAME_LENGTH
 	call CopyBytes
@@ -247,7 +247,7 @@
 	ldh [rIE], a
 
 	ld hl, wLinkBattleRNPreamble
-	ld de, wEnemyMon
+	ld de, wOTLinkBattleRNData
 	ld bc, SERIAL_RN_PREAMBLE_LENGTH + SERIAL_RNS_LENGTH
 	vc_hook Wireless_ExchangeBytes_RNG_state
 	call Serial_ExchangeBytes
@@ -256,7 +256,7 @@
 
 	ld hl, wLinkData
 	ld de, wOTPartyData
-	ld bc, SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + 1 + PARTY_LENGTH + 1 + 2 + (PARTYMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
+	ld bc, SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + (1 + PARTY_LENGTH + 1) + 2 + (PARTYMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH + 3
 	vc_hook Wireless_ExchangeBytes_party_structs
 	call Serial_ExchangeBytes
 	ld a, SERIAL_NO_DATA_BYTE
@@ -264,7 +264,7 @@
 
 	ld hl, wPlayerPatchLists
 	ld de, wOTPatchLists
-	ld bc, 200
+	ld bc, SERIAL_PATCH_LIST_LENGTH
 	vc_hook Wireless_ExchangeBytes_patch_lists
 	call Serial_ExchangeBytes
 
@@ -276,8 +276,8 @@
 	ld bc, wLinkPlayerMailEnd - wLinkPlayerMail
 	vc_hook Wireless_ExchangeBytes_mail
 	call ExchangeBytes
-
 .not_trading
+
 	xor a
 	ldh [rIF], a
 	ld a, (1 << JOYPAD) | (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK)
@@ -293,8 +293,8 @@
 	ld bc, NAME_LENGTH + 1 + PARTY_LENGTH + 1 + 2 + (PARTYMON_STRUCT_LENGTH + NAME_LENGTH * 2) * PARTY_LENGTH
 	call Link_CopyOTData
 
-	ld de, wPlayerTrademon
-	ld hl, wLinkPatchList1
+	ld de, wOTPatchLists
+	ld hl, wLinkPlayerData
 	ld c, 2
 .loop1
 	ld a, [de]
@@ -320,7 +320,7 @@
 	jr .loop1
 
 .next1
-	ld hl, wLinkPatchList2
+	ld hl, wLinkPlayerData + SERIAL_PATCH_DATA_SIZE
 	dec c
 	jr nz, .loop1
 
@@ -339,10 +339,14 @@
 	cp SERIAL_MAIL_PREAMBLE_BYTE
 	jr z, .loop3
 	dec hl
+
 	ld de, wLinkOTMail
 	ld bc, wLinkDataEnd - wLinkOTMail ; should be wLinkOTMailEnd - wLinkOTMail
 	call CopyBytes
-	ld hl, wLinkOTMail
+
+; Replace SERIAL_MAIL_REPLACEMENT_BYTE with SERIAL_NO_DATA_BYTE across all mail
+; message bodies.
+	ld hl, wLinkOTMailMessages
 	ld bc, (MAIL_MSG_LENGTH + 1) * PARTY_LENGTH
 .loop4
 	ld a, [hl]
@@ -355,7 +359,8 @@
 	ld a, b
 	or c
 	jr nz, .loop4
-	ld de, wOTPlayerMailPatchSet
+
+	ld de, wLinkOTMailPatchSet
 .loop5
 	ld a, [de]
 	inc de
@@ -406,7 +411,7 @@
 .fix_mail_loop
 	push bc
 	push de
-	farcall IsMailEuropean
+	farcall ParseMailLanguage
 	ld a, c
 	or a
 	jr z, .next
@@ -434,7 +439,7 @@
 	ld [de], a
 
 .skip_mail
-	ld hl, wLinkPlayerName
+	ld hl, wLinkData
 	ld de, wOTPlayerName
 	ld bc, NAME_LENGTH
 	call CopyBytes
@@ -615,6 +620,7 @@
 	dec b
 	jr nz, .preamble_loop
 
+; Initialize random seed, making sure special bytes are omitted
 	assert wLinkBattleRNPreamble + SERIAL_RN_PREAMBLE_LENGTH == wLinkBattleRNs
 	ld b, SERIAL_RNS_LENGTH
 .rn_loop
@@ -625,60 +631,66 @@
 	dec b
 	jr nz, .rn_loop
 
+; Clear the patch list
 	ld hl, wPlayerPatchLists
 	ld a, SERIAL_PREAMBLE_BYTE
+rept SERIAL_PATCH_PREAMBLE_LENGTH
 	ld [hli], a
-	ld [hli], a
-	ld [hli], a
-
-	ld b, 200
+endr
+	ld b, SERIAL_PATCH_LIST_LENGTH
 	xor a
-.loop1
+.clear_loop
 	ld [hli], a
 	dec b
-	jr nz, .loop1
+	jr nz, .clear_loop
 
-	ld hl, (wLinkData + SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + 1 + PARTY_LENGTH + 1) - 1
-	ld de, wPlayerPatchLists + 10 ; ???
+; Loop through all the patchable link data
+	ld hl, wLinkData + SERIAL_PREAMBLE_LENGTH + NAME_LENGTH + (1 + PARTY_LENGTH + 1) - 1
+	ld de, wPlayerPatchLists + SERIAL_RNS_LENGTH ; ???
 	lb bc, 0, 0
-.loop2
+.patch_loop
+; Check if we've gone over the entire area
 	inc c
 	ld a, c
-	cp SERIAL_PATCH_LIST_LENGTH + 1
-	jr z, .next1
+	cp SERIAL_PATCH_DATA_SIZE + 1
+	jr z, .data1_done
+
+; If we're processing the second patch area, check if we've reached the end
 	ld a, b
 	dec a
-	jr nz, .next2
+	jr nz, .process
 	push bc
 	ld a, [wLinkMode]
 	cp LINK_TIMECAPSULE
-	ld b, REDMON_STRUCT_LENGTH * PARTY_LENGTH - SERIAL_PATCH_LIST_LENGTH + 1
-	jr z, .got_value
-	ld b, 2 + PARTYMON_STRUCT_LENGTH * PARTY_LENGTH - SERIAL_PATCH_LIST_LENGTH + 1
-.got_value
+	ld b, REDMON_STRUCT_LENGTH * PARTY_LENGTH - SERIAL_PATCH_DATA_SIZE + 1
+	jr z, .got_size
+	ld b, 2 + PARTYMON_STRUCT_LENGTH * PARTY_LENGTH - SERIAL_PATCH_DATA_SIZE + 1
+.got_size
 	ld a, c
 	cp b
 	pop bc
-	jr z, .done
-.next2
+	jr z, .data2_done
+
+.process
+; Replace the "no data" byte, and record it in the array
 	inc hl
 	ld a, [hl]
 	cp SERIAL_NO_DATA_BYTE
-	jr nz, .loop2
+	jr nz, .patch_loop
 	ld a, c
 	ld [de], a
 	inc de
 	ld [hl], SERIAL_PATCH_REPLACEMENT_BYTE
-	jr .loop2
+	jr .patch_loop
 
-.next1
+.data1_done
 	ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
 	ld [de], a
 	inc de
 	lb bc, 1, 0
-	jr .loop2
+	jr .patch_loop
 
-.done
+.data2_done
 	ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
 	ld [de], a
 	ret
@@ -857,11 +869,11 @@
 	ld de, wLinkData
 	ld a, SERIAL_PREAMBLE_BYTE
 	ld b, SERIAL_PREAMBLE_LENGTH
-.loop1
+.preamble_loop
 	ld [de], a
 	inc de
 	dec b
-	jr nz, .loop1
+	jr nz, .preamble_loop
 
 	ld hl, wPlayerName
 	ld bc, NAME_LENGTH
@@ -893,7 +905,7 @@
 	ret nz
 
 ; Fill 5 bytes at wLinkPlayerMailPreamble with $20
-	ld de, wLinkPlayerMailPreamble
+	ld de, wLinkPlayerMail
 	ld a, SERIAL_MAIL_PREAMBLE_BYTE
 	call Link_CopyMailPreamble
 
@@ -902,7 +914,7 @@
 	call OpenSRAM
 	ld hl, sPartyMail
 	ld b, PARTY_LENGTH
-.loop2
+.message_loop
 	push bc
 	ld bc, MAIL_MSG_LENGTH + 1
 	call CopyBytes
@@ -910,11 +922,12 @@
 	add hl, bc
 	pop bc
 	dec b
-	jr nz, .loop2
+	jr nz, .message_loop
+
 ; Copy the mail data to wLinkPlayerMailMetadata
 	ld hl, sPartyMail
 	ld b, PARTY_LENGTH
-.loop3
+.metadata_loop
 	push bc
 	ld bc, MAIL_MSG_LENGTH + 1
 	add hl, bc
@@ -922,29 +935,31 @@
 	call CopyBytes
 	pop bc
 	dec b
-	jr nz, .loop3
+	jr nz, .metadata_loop
+
+; Translate the messages if necessary
 	ld b, PARTY_LENGTH
 	ld de, sPartyMail
 	ld hl, wLinkPlayerMailMessages
-.loop4
+.translate_loop
 	push bc
 	push hl
 	push de
 	push hl
-	farcall IsMailEuropean
+	farcall ParseMailLanguage
 	pop de
 	ld a, c
-	or a
-	jr z, .next
-	sub $3
+	or a ; MAIL_LANG_ENGLISH
+	jr z, .translate_next
+	sub MAIL_LANG_ITALIAN
 	jr nc, .italian_spanish
 	farcall ConvertFrenchGermanMailToEnglish
-	jr .next
+	jr .translate_next
 .italian_spanish
-	cp $2
-	jr nc, .next
+	cp (MAIL_LANG_SPANISH + 1) - MAIL_LANG_ITALIAN
+	jr nc, .translate_next
 	farcall ConvertSpanishItalianMailToEnglish
-.next
+.translate_next
 	pop de
 	ld hl, MAIL_STRUCT_LENGTH
 	add hl, de
@@ -955,41 +970,42 @@
 	add hl, bc
 	pop bc
 	dec b
-	jr nz, .loop4
+	jr nz, .translate_loop
 	call CloseSRAM
 
+; The SERIAL_NO_DATA_BYTE value isn't allowed anywhere in message text
 	ld hl, wLinkPlayerMailMessages
 	ld bc, (MAIL_MSG_LENGTH + 1) * PARTY_LENGTH
-.loop5
+.message_patch_loop
 	ld a, [hl]
 	cp SERIAL_NO_DATA_BYTE
-	jr nz, .skip2
+	jr nz, .message_patch_skip
 	ld [hl], SERIAL_MAIL_REPLACEMENT_BYTE
-.skip2
+.message_patch_skip
 	inc hl
 	dec bc
 	ld a, b
 	or c
-	jr nz, .loop5
+	jr nz, .message_patch_loop
 
+; Calculate the patch offsets for the mail metadata
 	ld hl, wLinkPlayerMailMetadata
 	ld de, wLinkPlayerMailPatchSet
 	ld b, (MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1)) * PARTY_LENGTH
 	ld c, 0
-.loop6
+.metadata_patch_loop
 	inc c
 	ld a, [hl]
 	cp SERIAL_NO_DATA_BYTE
-	jr nz, .skip3
+	jr nz, .metadata_patch_skip
 	ld [hl], SERIAL_PATCH_REPLACEMENT_BYTE
 	ld a, c
 	ld [de], a
 	inc de
-.skip3
+.metadata_patch_skip
 	inc hl
 	dec b
-	jr nz, .loop6
-
+	jr nz, .metadata_patch_loop
 	ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
 	ld [de], a
 	ret
@@ -1193,7 +1209,7 @@
 	ldh a, [hSerialConnectionStatus]
 	cp USING_INTERNAL_CLOCK
 	ret z
-	ld hl, wEnemyMonSpecies
+	ld hl, wOTLinkBattleRNData
 	call Link_FindFirstNonControlCharacter_AllowZero
 	ld de, wLinkBattleRNs
 	ld c, 10
--- a/engine/link/mystery_gift.asm
+++ b/engine/link/mystery_gift.asm
@@ -76,7 +76,7 @@
 	jp z, .LinkCanceled
 	cp MG_OKAY
 	jp nz, .CommunicationError
-	ld a, [wMysteryGiftGameVersion]
+	ld a, [wMysteryGiftPartnerGameVersion]
 	cp POKEMON_PIKACHU_2_VERSION
 	jr z, .skip_checks
 	call .CheckAlreadyGotFiveGiftsToday
@@ -92,11 +92,11 @@
 	ld a, [wMysteryGiftPartnerBackupItem]
 	and a
 	jp nz, .FriendNotReady
-	ld a, [wMysteryGiftGameVersion]
+	ld a, [wMysteryGiftPartnerGameVersion]
 	cp POKEMON_PIKACHU_2_VERSION
 	jr z, .skip_append_save
 	call .AddMysteryGiftPartnerID
-	ld a, [wMysteryGiftGameVersion]
+	ld a, [wMysteryGiftPartnerGameVersion]
 	cp RESERVED_GAME_VERSION
 	jr z, .skip_append_save
 	call .SaveMysteryGiftTrainerName
@@ -307,7 +307,7 @@
 	ldh a, [hMGRole]
 	cp IR_SENDER
 	jr z, SenderExchangeMysteryGiftDataPayloads
-; receiver
+
 	ld hl, hMGExchangedByte
 	ld b, 1
 	call TryReceivingIRDataBlock
@@ -522,7 +522,7 @@
 	ldh a, [hMGRole]
 	cp IR_SENDER
 	jr z, .sender
-; receiver
+
 	call BeginReceivingIRCommunication
 	jr nz, EndOrContinueMysteryGiftIRCommunication
 	jp ReceiverExchangeMysteryGiftDataPayloads
@@ -563,7 +563,7 @@
 	ldh a, [hMGRole]
 	cp IR_SENDER
 	jr z, .sender
-; receiver
+
 	; Receive the data payload
 	call ReceiveNameCardDataPayload
 	jp nz, EndNameCardIRCommunication
--- a/engine/pokemon/european_mail.asm
+++ b/engine/pokemon/european_mail.asm
@@ -1,10 +1,5 @@
-IsMailEuropean:
-; return 1 if French
-; return 2 if German
-; return 3 if Italian
-; return 4 if Spanish
-; return 0 if none of the above
-	ld c, $0
+ParseMailLanguage:
+	ld c, MAIL_LANG_ENGLISH
 	ld hl, sPartyMon1MailNationality - sPartyMon1Mail
 	add hl, de
 	ld a, [hli]
@@ -11,19 +6,19 @@
 	cp "E"
 	ret nz
 	ld a, [hli]
-	inc c
+	inc c ; MAIL_LANG_FRENCH
 	cp "F"
 	ret z
-	inc c
+	inc c ; MAIL_LANG_GERMAN
 	cp "G"
 	ret z
-	inc c
+	inc c ; MAIL_LANG_ITALIAN
 	cp "I"
 	ret z
-	inc c
+	inc c ; MAIL_LANG_SPANISH
 	cp "S"
 	ret z
-	ld c, $0
+	ld c, MAIL_LANG_ENGLISH
 	ret
 
 ; The regular font.
--- a/engine/pokemon/mail_2.asm
+++ b/engine/pokemon/mail_2.asm
@@ -31,14 +31,14 @@
 	push de
 	ld a, BANK(sPartyMail)
 	call OpenSRAM
-	farcall IsMailEuropean
+	farcall ParseMailLanguage
 	call CloseSRAM
 	ld a, c
 	ld de, StandardEnglishFont
-	or a
+	or a ; MAIL_LANG_ENGLISH
 	jr z, .got_font
 	ld de, FrenchGermanFont
-	sub $3
+	sub MAIL_LANG_ITALIAN
 	jr c, .got_font
 	ld de, SpanishItalianFont
 
--- a/home/serial.asm
+++ b/home/serial.asm
@@ -114,7 +114,7 @@
 	dec hl
 	cp SERIAL_PREAMBLE_BYTE
 	jr nz, .loop
-	xor a
+	xor a ; FALSE
 	ldh [hSerialIgnoringInitialData], a
 	jr .loop
 
--- a/ram/wram.asm
+++ b/ram/wram.asm
@@ -617,8 +617,8 @@
 SECTION UNION "Miscellaneous", WRAM0
 
 ; link patch lists
-wPlayerPatchLists:: ds 200
-wOTPatchLists:: ds 200
+wPlayerPatchLists:: ds SERIAL_PATCH_LIST_LENGTH
+wOTPatchLists:: ds SERIAL_PATCH_LIST_LENGTH
 
 
 SECTION UNION "Miscellaneous", WRAM0
@@ -1006,10 +1006,6 @@
 wTimeCapsulePartyMon{d:n}Nickname:: ds MON_NAME_LENGTH
 endr
 
-NEXTU
-; link patch lists
-wLinkPatchList1:: ds SERIAL_PATCH_LIST_LENGTH
-wLinkPatchList2:: ds SERIAL_PATCH_LIST_LENGTH
 ENDU
 
 
@@ -1034,13 +1030,14 @@
 wLinkPlayerMailPreamble:: ds SERIAL_MAIL_PREAMBLE_LENGTH
 wLinkPlayerMailMessages:: ds (MAIL_MSG_LENGTH + 1) * PARTY_LENGTH
 wLinkPlayerMailMetadata:: ds (MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1)) * PARTY_LENGTH
-wLinkPlayerMailPatchSet:: ds 103
+wLinkPlayerMailPatchSet:: ds 100 + SERIAL_PATCH_PREAMBLE_LENGTH
 wLinkPlayerMailEnd::
 	ds 10
 wLinkOTMail::
 wLinkOTMailMessages:: ds (MAIL_MSG_LENGTH + 1) * PARTY_LENGTH
 wLinkOTMailMetadata:: ds (MAIL_STRUCT_LENGTH - (MAIL_MSG_LENGTH + 1)) * PARTY_LENGTH
-wOTPlayerMailPatchSet:: ds 103 + SERIAL_MAIL_PREAMBLE_LENGTH
+wLinkOTMailPatchSet:: ds 100 + SERIAL_PATCH_PREAMBLE_LENGTH
+wLinkOTMailPadding:: ds SERIAL_MAIL_PREAMBLE_LENGTH
 wLinkOTMailEnd::
 	ds 10
 
@@ -1073,7 +1070,7 @@
 	ds 138
 
 wMysteryGiftPartnerData::
-wMysteryGiftGameVersion:: db
+wMysteryGiftPartnerGameVersion:: db
 wMysteryGiftPartnerID:: dw
 wMysteryGiftPartnerName:: ds NAME_LENGTH
 wMysteryGiftPartnerDexCaught:: db
@@ -1087,7 +1084,7 @@
 	ds 60
 
 wMysteryGiftPlayerData::
-	ds 1
+wMysteryGiftPlayerGameVersion:: db
 wMysteryGiftPlayerID:: dw
 wMysteryGiftPlayerName:: ds NAME_LENGTH
 wMysteryGiftPlayerDexCaught:: db
@@ -2002,8 +1999,15 @@
 SECTION UNION "Miscellaneous WRAM 1", WRAMX
 
 ; switching pokemon in party
-; may store NAME_LENGTH, PARTYMON_STRUCT_LENGTH, or MAIL_STRUCT_LENGTH bytes
-wSwitchMonBuffer:: ds 48
+; may store a name, partymon, or mail
+wSwitchMonBuffer::
+UNION
+	ds NAME_LENGTH
+NEXTU
+	ds PARTYMON_STRUCT_LENGTH
+NEXTU
+	ds MAIL_STRUCT_LENGTH
+ENDU
 
 
 SECTION UNION "Miscellaneous WRAM 1", WRAMX
@@ -2624,11 +2628,15 @@
 wTempEnemyMonSpecies::  db
 wTempBattleMonSpecies:: db
 
+UNION
+wOTLinkBattleRNData:: ds SERIAL_RN_PREAMBLE_LENGTH + SERIAL_RNS_LENGTH
+NEXTU
 wEnemyMon:: battle_struct wEnemyMon
 wEnemyMonBaseStats:: ds NUM_EXP_STATS
 wEnemyMonCatchRate:: db
 wEnemyMonBaseExp::   db
 wEnemyMonEnd::
+ENDU
 
 wBattleMode::
 ; 0: overworld