shithub: pokecrystal

Download patch

ref: 172dba3c0b38eeea09342efe297ccc7ea9b4d3d3
parent: c4a18b13295cd9f2777bfa27a37aafc09eb31684
author: Remy Oukaour <remy.oukaour@gmail.com>
date: Tue Dec 26 17:57:19 EST 2017

Rename some sections
engine/battle_tower.asm fits better in events/

--- a/engine/battle_tower.asm
+++ /dev/null
@@ -1,210 +1,0 @@
-Function_LoadOpponentTrainerAndPokemons: ; 1f8000
-	ld a, [rSVBK]
-	push af
-	ld a, BANK(BT_OTTrainer)
-	ld [rSVBK], a
-
-	; Fill BT_OTTrainer with zeros
-	xor a
-	ld hl, BT_OTTrainer
-	ld bc, BT_OTTrainerEnd - BT_OTTrainer
-	call ByteFill
-
-	; Write $ff into the Item-Slots
-	ld a, $ff
-	ld [BT_OTPkmn1Item], a
-	ld [BT_OTPkmn2Item], a
-	ld [BT_OTPkmn3Item], a
-
-	; Set BT_OTTrainer as start address to write the following data to
-	ld de, BT_OTTrainer
-
-	ld a, [hRandomAdd]
-	ld b, a
-.resample ; loop to find a random trainer
-	call Random
-	ld a, [hRandomAdd]
-	add b
-	ld b, a ; b contains the nr of the trainer
-IF DEF(CRYSTAL11)
-	and (1 << 7) - 1
-	cp 70
-ELSE
-	and (1 << 5) - 1
-	cp 21
-ENDC
-	jr nc, .resample
-	ld b, a
-
-	ld a, BANK(sBTTrainers)
-	call GetSRAMBank
-
-	ld c, BATTLETOWER_NROFTRAINERS
-	ld hl, sBTTrainers
-.next_trainer
-	ld a, [hli]
-	cp b
-	jr z, .resample
-	dec c
-	jr nz, .next_trainer ; c <= 7  initialise all 7 trainers?
-
-	ld hl, sBTTrainers
-	ld a, [sNrOfBeatenBattleTowerTrainers]
-	ld c, a
-	ld a, b
-	ld b, 0
-	add hl, bc
-	ld [hl], a
-
-	call CloseSRAM
-
-	push af
-; Copy name (10 bytes) and class (1 byte) of trainer
-	ld hl, BattleTowerTrainers
-	ld bc, NAME_LENGTH
-	call AddNTimes
-	ld bc, NAME_LENGTH
-	call CopyBytes
-
-	call Function_LoadRandomBattleTowerPkmn
-	pop af
-
-	ld hl, BattleTowerTrainerData
-	ld bc, BATTLETOWER_TRAINERDATALENGTH
-	call AddNTimes
-	ld bc, BATTLETOWER_TRAINERDATALENGTH
-.copy_bt_trainer_data_loop
-	ld a, BANK(BattleTowerTrainerData)
-	call GetFarByte
-	ld [de], a
-	inc hl
-	inc de
-	dec bc
-	ld a, b
-	or c
-	jr nz, .copy_bt_trainer_data_loop
-
-	pop af
-	ld [rSVBK], a
-
-	ret
-
-
-Function_LoadRandomBattleTowerPkmn: ; 1f8081
-	ld c, BATTLETOWER_NROFPKMNS
-.loop
-	push bc
-	ld a, BANK(sBTPkmnPrevTrainer1)
-	call GetSRAMBank
-
-.FindARandomBattleTowerPkmn:
-	; From Which LevelGroup are the Pkmn loaded
-	; a = 1..10
-	ld a, [wBTChoiceOfLvlGroup] ; [$d800]
-	dec a
-	ld hl, BattleTowerMons
-	ld bc, BattleTowerMons2 - BattleTowerMons1
-	call AddNTimes
-
-	ld a, [hRandomAdd]
-	ld b, a
-.resample
-	call Random
-	ld a, [hRandomAdd]
-	add b
-	ld b, a
-	and $1f
-	cp BATTLETOWER_NRMONSPERLEVELBRACKET
-	jr nc, .resample
-	; in register 'a' is the chosen Pkmn of the LevelGroup
-
-	; Check if Pkmn was already loaded before
-	; Check current and the 2 previous teams
-	; includes check if item is double at the current team
-	ld bc, PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH
-	call AddNTimes
-	ld a, [hli]
-	ld b, a
-	ld a, [hld]
-	ld c, a
-	ld a, [BT_OTPkmn1]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [BT_OTPkmn1Item]
-	cp c
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [BT_OTPkmn2]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [BT_OTPkmn2Item]
-	cp c
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [BT_OTPkmn3]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [BT_OTPkmn3Item]
-	cp c
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevTrainer1]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevTrainer2]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevTrainer3]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevPrevTrainer1]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevPrevTrainer2]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-	ld a, [sBTPkmnPrevPrevTrainer3]
-	cp b
-	jr z, .FindARandomBattleTowerPkmn
-
-	ld bc, PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH
-	call CopyBytes
-
-	ld a, [wNamedObjectIndexBuffer]
-	push af
-	push de
-	ld hl, - (PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH)
-	add hl, de
-	ld a, [hl]
-	ld [wNamedObjectIndexBuffer], a
-	ld bc, PARTYMON_STRUCT_LENGTH
-	add hl, bc
-	push hl
-	call GetPokemonName
-	ld h, d
-	ld l, e
-	pop de
-	ld bc, PKMN_NAME_LENGTH
-	call CopyBytes
-
-	pop de
-	pop af
-	ld [wNamedObjectIndexBuffer], a
-	pop bc
-	dec c
-	jp nz, .loop
-
-	ld a, [sBTPkmnPrevTrainer1]
-	ld [sBTPkmnPrevPrevTrainer1], a
-	ld a, [sBTPkmnPrevTrainer2]
-	ld [sBTPkmnPrevPrevTrainer2], a
-	ld a, [sBTPkmnPrevTrainer3]
-	ld [sBTPkmnPrevPrevTrainer3], a
-	ld a, [BT_OTPkmn1]
-	ld [sBTPkmnPrevTrainer1], a
-	ld a, [BT_OTPkmn2]
-	ld [sBTPkmnPrevTrainer2], a
-	ld a, [BT_OTPkmn3]
-	ld [sBTPkmnPrevTrainer3], a
-	call CloseSRAM
-	ret
-; 1f814e
-
-INCLUDE "data/battle_tower.asm"
--- a/engine/odd_eggs.asm
+++ /dev/null
@@ -1,96 +1,0 @@
-GiveOddEgg: ; 1fb4b6
-	; Figure out which egg to give.
-
-	; Compare a random word to
-	; probabilities out of 0xffff.
-	call Random
-	ld hl, OddEggProbabilities
-	ld c, 0
-	ld b, c
-.loop
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-
-	; Break on $ffff.
-	ld a, d
-	cp HIGH($ffff)
-	jr nz, .not_done
-	ld a, e
-	cp LOW($ffff)
-	jr z, .done
-.not_done
-
-	; Break when [hRandom] <= de.
-	ld a, [hRandom + 1]
-	cp d
-	jr c, .done
-	jr z, .ok
-	jr .next
-.ok
-	ld a, [hRandom + 0]
-	cp e
-	jr c, .done
-	jr z, .done
-.next
-	inc bc
-	jr .loop
-.done
-
-	ld hl, OddEggs
-	ld a, OddEgg2 - OddEgg1
-	call AddNTimes
-
-	ld de, OddEggSpecies
-	ld bc, PARTYMON_STRUCT_LENGTH + 2 * PKMN_NAME_LENGTH
-	call CopyBytes
-
-	ld a, EGG_TICKET
-	ld [CurItem], a
-	ld a, 1
-	ld [wItemQuantityChangeBuffer], a
-	ld a, -1
-	ld [CurItemQuantity], a
-	ld hl, NumItems
-	call TossItem
-
-	; load species in wcd2a
-	ld a, EGG
-	ld [wMobileMonSpeciesBuffer], a
-
-	; load pointer to (wMobileMonSpeciesBuffer - 1) in wMobileMonSpeciesPointerBuffer
-	ld a, LOW(wMobileMonSpeciesBuffer - 1)
-	ld [wMobileMonSpeciesPointerBuffer], a
-	ld a, HIGH(wMobileMonSpeciesBuffer - 1)
-	ld [wMobileMonSpeciesPointerBuffer + 1], a
-	; load pointer to OddEggSpecies in wMobileMonStructurePointerBuffer
-	ld a, LOW(OddEggSpecies)
-	ld [wMobileMonStructurePointerBuffer], a
-	ld a, HIGH(OddEggSpecies)
-	ld [wMobileMonStructurePointerBuffer + 1], a
-
-	; load Odd Egg Name in wTempOddEggNickname
-	ld hl, .Odd
-	ld de, wTempOddEggNickname
-	ld bc, PKMN_NAME_LENGTH
-	call CopyBytes
-
-	; load pointer to wTempOddEggNickname in wMobileMonOTNamePointerBuffer
-	ld a, LOW(wTempOddEggNickname)
-	ld [wMobileMonOTNamePointerBuffer], a
-	ld a, HIGH(wTempOddEggNickname)
-	ld [wMobileMonOTNamePointerBuffer + 1], a
-	; load pointer to wOddEggName in wMobileMonNicknamePointerBuffer
-	ld a, LOW(wOddEggName)
-	ld [wMobileMonNicknamePointerBuffer], a
-	ld a, HIGH(wOddEggName)
-	ld [wMobileMonNicknamePointerBuffer + 1], a
-	farcall AddMobileMonToParty
-	ret
-; 1fb546
-
-.Odd:
-	db "ODD@@@@@@@@@"
-
-INCLUDE "data/odd_eggs.asm"
--- a/events/battle_tower.asm
+++ b/events/battle_tower.asm
@@ -1,342 +1,210 @@
-CheckForMobileBattleRules: ; 8b1e1
-	ld de, .PointerTables
-	call BattleTower_ExecuteJumptable
-	ret z
-	call BattleTower_PleaseReturnWhenReady
-	scf
-	ret
-; 8b1ed
+Function_LoadOpponentTrainerAndPokemons: ; 1f8000
+	ld a, [rSVBK]
+	push af
+	ld a, BANK(BT_OTTrainer)
+	ld [rSVBK], a
 
-.PointerTables: ; 8b1ed
-	db 2
-	dw .Functions
-	dw .TextPointers
+	; Fill BT_OTTrainer with zeros
+	xor a
+	ld hl, BT_OTTrainer
+	ld bc, BT_OTTrainerEnd - BT_OTTrainer
+	call ByteFill
 
-.Functions: ; 8b1f2
-	dw BattleTower_CheckPartyLengthIs3
-	dw BattleTower_CheckPartyHasThreeMonsThatAreNotEggs
-; 8b1f6
+	; Write $ff into the Item-Slots
+	ld a, $ff
+	ld [BT_OTPkmn1Item], a
+	ld [BT_OTPkmn2Item], a
+	ld [BT_OTPkmn3Item], a
 
-.TextPointers: ; 8b1f6
-	dw .ExcuseMeText
-	dw JumpText_NeedAtLeastThreeMon
-	dw JumpText_EggDoesNotQualify
-; 8b1fc
+	; Set BT_OTTrainer as start address to write the following data to
+	ld de, BT_OTTrainer
 
-.ExcuseMeText: ; 0x8b1fc
-	; Excuse me!
-	text_jump UnknownText_0x1c5937
-	db "@"
-; 0x8b201
+	ld a, [hRandomAdd]
+	ld b, a
+.resample ; loop to find a random trainer
+	call Random
+	ld a, [hRandomAdd]
+	add b
+	ld b, a ; b contains the nr of the trainer
+IF DEF(CRYSTAL11)
+	and (1 << 7) - 1
+	cp 70
+ELSE
+	and (1 << 5) - 1
+	cp 21
+ENDC
+	jr nc, .resample
+	ld b, a
 
-CheckForBattleTowerRules: ; 8b201
-	ld hl, StringBuffer2
-	ld [hl], "3"
-	inc hl
-	ld [hl], "@"
-	ld de, .PointerTables
-	call BattleTower_ExecuteJumptable
-	ret z
-	call BattleTower_PleaseReturnWhenReady
-	scf
-	ret
-; 8b215
+	ld a, BANK(sBTTrainers)
+	call GetSRAMBank
 
-.PointerTables: ; 8b215
-	db 4
-	dw .Functions
-	dw .TextPointers
+	ld c, BATTLETOWER_NROFTRAINERS
+	ld hl, sBTTrainers
+.next_trainer
+	ld a, [hli]
+	cp b
+	jr z, .resample
+	dec c
+	jr nz, .next_trainer ; c <= 7  initialise all 7 trainers?
 
-.Functions: ; 8b21a
-	dw Function_PartyCountEq3
-	dw Function_PartySpeciesAreUnique
-	dw Function_PartyItemsAreUnique
-	dw Function_HasPartyAnEgg
-; 8b222
-
-.TextPointers: ; 8b222
-	dw JumpText_ExcuseMeYoureNotReady
-	dw JumpText_OnlyThreePkmnMayBeEntered
-	dw JumpText_ThePkmnMustAllBeDifferentKinds
-	dw JumpText_ThePkmnMustNotHoldTheSameItems
-	dw JumpText_YouCantTakeAnEgg
-; 8b22c
-
-JumpText_ExcuseMeYoureNotReady: ; 0x8b22c
-	; Excuse me. You're not ready.
-	text_jump Text_ExcuseMeYoureNotReady
-	db "@"
-; 0x8b231
-
-BattleTower_PleaseReturnWhenReady: ; 8b231
-	ld hl, .PleaseReturnWhenReady
-	call PrintText
-	ret
-; 8b238
-
-.PleaseReturnWhenReady: ; 0x8b238
-	; Please return when you're ready.
-	text_jump UnknownText_0x1c5962
-	db "@"
-; 0x8b23d
-
-JumpText_NeedAtLeastThreeMon: ; 0x8b23d
-	; You need at least three #MON.
-	text_jump UnknownText_0x1c5983
-	db "@"
-; 0x8b242
-
-JumpText_EggDoesNotQualify: ; 0x8b242
-	; Sorry, an EGG doesn't qualify.
-	text_jump UnknownText_0x1c59a3
-	db "@"
-; 0x8b247
-
-JumpText_OnlyThreePkmnMayBeEntered: ; 0x8b247
-	; Only three #MON may be entered.
-	text_jump Text_OnlyThreePkmnMayBeEntered
-	db "@"
-; 0x8b24c
-
-JumpText_ThePkmnMustAllBeDifferentKinds: ; 0x8b24c
-	; The @  #MON must all be different kinds.
-	text_jump Text_ThePkmnMustAllBeDifferentKinds
-	db "@"
-; 0x8b251
-
-JumpText_ThePkmnMustNotHoldTheSameItems: ; 0x8b251
-	; The @  #MON must not hold the same items.
-	text_jump Text_ThePkmnMustNotHoldTheSameItems
-	db "@"
-; 0x8b256
-
-JumpText_YouCantTakeAnEgg: ; 0x8b256
-	; You can't take an EGG!
-	text_jump Text_YouCantTakeAnEgg
-	db "@"
-; 0x8b25b
-
-BattleTower_ExecuteJumptable: ; 8b25b
-	ld bc, 0
-.loop
-	call .DoJumptableFunction
-	call c, .PrintFailureText
-	call .Next_CheckReachedEnd
-	jr nz, .loop
+	ld hl, sBTTrainers
+	ld a, [sNrOfBeatenBattleTowerTrainers]
+	ld c, a
 	ld a, b
-	and a
-	ret
-; 8b26c
+	ld b, 0
+	add hl, bc
+	ld [hl], a
 
-.DoJumptableFunction: ; 8b26c
-	push de
-	push bc
-	call .GetFunctionPointer
-	ld a, c
-	rst JumpTable
-	pop bc
-	pop de
-	ret
-; 8b276
+	call CloseSRAM
 
-.Next_CheckReachedEnd: ; 8b276
-	inc c
-	ld a, [de]
-	cp c
-	ret
-; 8b27a
+	push af
+; Copy name (10 bytes) and class (1 byte) of trainer
+	ld hl, BattleTowerTrainers
+	ld bc, NAME_LENGTH
+	call AddNTimes
+	ld bc, NAME_LENGTH
+	call CopyBytes
 
-.GetFunctionPointer: ; 8b27a
-	inc de
-	ld a, [de]
-	ld l, a
-	inc de
-	ld a, [de]
-	ld h, a
-	ret
-; 8b281
+	call Function_LoadRandomBattleTowerPkmn
+	pop af
 
-.GetTextPointers: ; 8b281
+	ld hl, BattleTowerTrainerData
+	ld bc, BATTLETOWER_TRAINERDATALENGTH
+	call AddNTimes
+	ld bc, BATTLETOWER_TRAINERDATALENGTH
+.copy_bt_trainer_data_loop
+	ld a, BANK(BattleTowerTrainerData)
+	call GetFarByte
+	ld [de], a
+	inc hl
 	inc de
-	inc de
-	inc de
-	ld a, [de]
-	ld l, a
-	inc de
-	ld a, [de]
-	ld h, a
-	ret
-; 8b28a
+	dec bc
+	ld a, b
+	or c
+	jr nz, .copy_bt_trainer_data_loop
 
-.LoadTextPointer: ; 8b28a
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ret
-; 8b28e
+	pop af
+	ld [rSVBK], a
 
-.PrintFailureText: ; 8b28e
-	push de
-	push bc
-	ld a, b
-	and a
-	call z, .PrintFirstText
-	pop bc
-	call .PrintNthText
-	ld b, $1
-	pop de
 	ret
-; 8b29d
 
-.PrintFirstText: ; 8b29d
-	push de
-	call .GetTextPointers
-	call .LoadTextPointer
-	call PrintText
-	pop de
-	ret
-; 8b2a9
 
-.PrintNthText: ; 8b2a9
+Function_LoadRandomBattleTowerPkmn: ; 1f8081
+	ld c, BATTLETOWER_NROFPKMNS
+.loop
 	push bc
-	call .GetTextPointers
-	inc hl
-	inc hl
-	ld b, $0
-	add hl, bc
-	add hl, bc
-	call .LoadTextPointer
-	call PrintText
-	pop bc
-	ret
-; 8b2bb
+	ld a, BANK(sBTPkmnPrevTrainer1)
+	call GetSRAMBank
 
-BattleTower_CheckPartyLengthIs3: ; 8b2bb
-	ld a, [PartyCount]
-	cp 3
-	ret
-; 8b2c1
+.FindARandomBattleTowerPkmn:
+	; From Which LevelGroup are the Pkmn loaded
+	; a = 1..10
+	ld a, [wBTChoiceOfLvlGroup] ; [$d800]
+	dec a
+	ld hl, BattleTowerMons
+	ld bc, BattleTowerMons2 - BattleTowerMons1
+	call AddNTimes
 
-BattleTower_CheckPartyHasThreeMonsThatAreNotEggs: ; 8b2c1
-	ld hl, PartyCount
+	ld a, [hRandomAdd]
+	ld b, a
+.resample
+	call Random
+	ld a, [hRandomAdd]
+	add b
+	ld b, a
+	and $1f
+	cp BATTLETOWER_NRMONSPERLEVELBRACKET
+	jr nc, .resample
+	; in register 'a' is the chosen Pkmn of the LevelGroup
+
+	; Check if Pkmn was already loaded before
+	; Check current and the 2 previous teams
+	; includes check if item is double at the current team
+	ld bc, PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH
+	call AddNTimes
 	ld a, [hli]
-	ld b, $0
+	ld b, a
+	ld a, [hld]
 	ld c, a
-.loop
-	ld a, [hli]
-	cp EGG
-	jr z, .egg
-	inc b
-
-.egg
-	dec c
-	jr nz, .loop
-	ld a, [PartyCount]
+	ld a, [BT_OTPkmn1]
 	cp b
-	ret z
-	ld a, b
-	cp 3
-	ret
-; 8b2da
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [BT_OTPkmn1Item]
+	cp c
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [BT_OTPkmn2]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [BT_OTPkmn2Item]
+	cp c
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [BT_OTPkmn3]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [BT_OTPkmn3Item]
+	cp c
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevTrainer1]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevTrainer2]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevTrainer3]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevPrevTrainer1]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevPrevTrainer2]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
+	ld a, [sBTPkmnPrevPrevTrainer3]
+	cp b
+	jr z, .FindARandomBattleTowerPkmn
 
-Function_PartyCountEq3: ; 8b2da
-	ld a, [PartyCount]
-	cp 3
-	ret z
-	scf
-	ret
-; 8b2e2
+	ld bc, PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH
+	call CopyBytes
 
-Function_PartySpeciesAreUnique: ; 8b2e2
-	ld hl, PartyMon1Species
-	call VerifyUniqueness
-	ret
-; 8b2e9
-
-VerifyUniqueness: ; 8b2e9
-	ld de, PartyCount
-	ld a, [de]
-	inc de
-	dec a
-	jr z, .done
-	ld b, a
-.loop
-	push hl
+	ld a, [wNamedObjectIndexBuffer]
+	push af
 	push de
-	ld c, b
-	call .isegg
-	jr z, .next
+	ld hl, - (PARTYMON_STRUCT_LENGTH + PKMN_NAME_LENGTH)
+	add hl, de
 	ld a, [hl]
-	and a
-	jr z, .next
-.loop2
-	call .nextmon
-	call .isegg
-	jr z, .next2
-	cp [hl]
-	jr z, .gotcha
-
-.next2
-	dec c
-	jr nz, .loop2
-
-.next
+	ld [wNamedObjectIndexBuffer], a
+	ld bc, PARTYMON_STRUCT_LENGTH
+	add hl, bc
+	push hl
+	call GetPokemonName
+	ld h, d
+	ld l, e
 	pop de
-	pop hl
-	call .nextmon
-	dec b
-	jr nz, .loop
+	ld bc, PKMN_NAME_LENGTH
+	call CopyBytes
 
-.done
-	and a
-	ret
-
-.gotcha
 	pop de
-	pop hl
-	scf
-	ret
-; 8b31a
-
-.nextmon ; 8b31a
-	push bc
-	ld bc, PARTYMON_STRUCT_LENGTH
-	add hl, bc
-	inc de
+	pop af
+	ld [wNamedObjectIndexBuffer], a
 	pop bc
-	ret
-; 8b322
-
-.isegg ; 8b322
-	push bc
-	ld b, a
-	ld a, [de]
-	cp EGG
-	ld a, b
-	pop bc
-	ret
-; 8b32a
-
-Function_PartyItemsAreUnique: ; 8b32a
-	ld hl, PartyMon1Item
-	call VerifyUniqueness
-	ret
-; 8b331
-
-Function_HasPartyAnEgg: ; 8b331
-	ld hl, PartyCount
-	ld a, [hli]
-	ld c, a
-.loop
-	ld a, [hli]
-	cp EGG
-	jr z, .found
 	dec c
-	jr nz, .loop
-	and a
-	ret
+	jp nz, .loop
 
-.found
-	scf
+	ld a, [sBTPkmnPrevTrainer1]
+	ld [sBTPkmnPrevPrevTrainer1], a
+	ld a, [sBTPkmnPrevTrainer2]
+	ld [sBTPkmnPrevPrevTrainer2], a
+	ld a, [sBTPkmnPrevTrainer3]
+	ld [sBTPkmnPrevPrevTrainer3], a
+	ld a, [BT_OTPkmn1]
+	ld [sBTPkmnPrevTrainer1], a
+	ld a, [BT_OTPkmn2]
+	ld [sBTPkmnPrevTrainer2], a
+	ld a, [BT_OTPkmn3]
+	ld [sBTPkmnPrevTrainer3], a
+	call CloseSRAM
 	ret
-; 8b342
+; 1f814e
+
+INCLUDE "data/battle_tower.asm"
--- /dev/null
+++ b/events/battle_tower_rules.asm
@@ -1,0 +1,342 @@
+CheckForMobileBattleRules: ; 8b1e1
+	ld de, .PointerTables
+	call BattleTower_ExecuteJumptable
+	ret z
+	call BattleTower_PleaseReturnWhenReady
+	scf
+	ret
+; 8b1ed
+
+.PointerTables: ; 8b1ed
+	db 2
+	dw .Functions
+	dw .TextPointers
+
+.Functions: ; 8b1f2
+	dw BattleTower_CheckPartyLengthIs3
+	dw BattleTower_CheckPartyHasThreeMonsThatAreNotEggs
+; 8b1f6
+
+.TextPointers: ; 8b1f6
+	dw .ExcuseMeText
+	dw JumpText_NeedAtLeastThreeMon
+	dw JumpText_EggDoesNotQualify
+; 8b1fc
+
+.ExcuseMeText: ; 0x8b1fc
+	; Excuse me!
+	text_jump UnknownText_0x1c5937
+	db "@"
+; 0x8b201
+
+CheckForBattleTowerRules: ; 8b201
+	ld hl, StringBuffer2
+	ld [hl], "3"
+	inc hl
+	ld [hl], "@"
+	ld de, .PointerTables
+	call BattleTower_ExecuteJumptable
+	ret z
+	call BattleTower_PleaseReturnWhenReady
+	scf
+	ret
+; 8b215
+
+.PointerTables: ; 8b215
+	db 4
+	dw .Functions
+	dw .TextPointers
+
+.Functions: ; 8b21a
+	dw Function_PartyCountEq3
+	dw Function_PartySpeciesAreUnique
+	dw Function_PartyItemsAreUnique
+	dw Function_HasPartyAnEgg
+; 8b222
+
+.TextPointers: ; 8b222
+	dw JumpText_ExcuseMeYoureNotReady
+	dw JumpText_OnlyThreePkmnMayBeEntered
+	dw JumpText_ThePkmnMustAllBeDifferentKinds
+	dw JumpText_ThePkmnMustNotHoldTheSameItems
+	dw JumpText_YouCantTakeAnEgg
+; 8b22c
+
+JumpText_ExcuseMeYoureNotReady: ; 0x8b22c
+	; Excuse me. You're not ready.
+	text_jump Text_ExcuseMeYoureNotReady
+	db "@"
+; 0x8b231
+
+BattleTower_PleaseReturnWhenReady: ; 8b231
+	ld hl, .PleaseReturnWhenReady
+	call PrintText
+	ret
+; 8b238
+
+.PleaseReturnWhenReady: ; 0x8b238
+	; Please return when you're ready.
+	text_jump UnknownText_0x1c5962
+	db "@"
+; 0x8b23d
+
+JumpText_NeedAtLeastThreeMon: ; 0x8b23d
+	; You need at least three #MON.
+	text_jump UnknownText_0x1c5983
+	db "@"
+; 0x8b242
+
+JumpText_EggDoesNotQualify: ; 0x8b242
+	; Sorry, an EGG doesn't qualify.
+	text_jump UnknownText_0x1c59a3
+	db "@"
+; 0x8b247
+
+JumpText_OnlyThreePkmnMayBeEntered: ; 0x8b247
+	; Only three #MON may be entered.
+	text_jump Text_OnlyThreePkmnMayBeEntered
+	db "@"
+; 0x8b24c
+
+JumpText_ThePkmnMustAllBeDifferentKinds: ; 0x8b24c
+	; The @  #MON must all be different kinds.
+	text_jump Text_ThePkmnMustAllBeDifferentKinds
+	db "@"
+; 0x8b251
+
+JumpText_ThePkmnMustNotHoldTheSameItems: ; 0x8b251
+	; The @  #MON must not hold the same items.
+	text_jump Text_ThePkmnMustNotHoldTheSameItems
+	db "@"
+; 0x8b256
+
+JumpText_YouCantTakeAnEgg: ; 0x8b256
+	; You can't take an EGG!
+	text_jump Text_YouCantTakeAnEgg
+	db "@"
+; 0x8b25b
+
+BattleTower_ExecuteJumptable: ; 8b25b
+	ld bc, 0
+.loop
+	call .DoJumptableFunction
+	call c, .PrintFailureText
+	call .Next_CheckReachedEnd
+	jr nz, .loop
+	ld a, b
+	and a
+	ret
+; 8b26c
+
+.DoJumptableFunction: ; 8b26c
+	push de
+	push bc
+	call .GetFunctionPointer
+	ld a, c
+	rst JumpTable
+	pop bc
+	pop de
+	ret
+; 8b276
+
+.Next_CheckReachedEnd: ; 8b276
+	inc c
+	ld a, [de]
+	cp c
+	ret
+; 8b27a
+
+.GetFunctionPointer: ; 8b27a
+	inc de
+	ld a, [de]
+	ld l, a
+	inc de
+	ld a, [de]
+	ld h, a
+	ret
+; 8b281
+
+.GetTextPointers: ; 8b281
+	inc de
+	inc de
+	inc de
+	ld a, [de]
+	ld l, a
+	inc de
+	ld a, [de]
+	ld h, a
+	ret
+; 8b28a
+
+.LoadTextPointer: ; 8b28a
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ret
+; 8b28e
+
+.PrintFailureText: ; 8b28e
+	push de
+	push bc
+	ld a, b
+	and a
+	call z, .PrintFirstText
+	pop bc
+	call .PrintNthText
+	ld b, $1
+	pop de
+	ret
+; 8b29d
+
+.PrintFirstText: ; 8b29d
+	push de
+	call .GetTextPointers
+	call .LoadTextPointer
+	call PrintText
+	pop de
+	ret
+; 8b2a9
+
+.PrintNthText: ; 8b2a9
+	push bc
+	call .GetTextPointers
+	inc hl
+	inc hl
+	ld b, $0
+	add hl, bc
+	add hl, bc
+	call .LoadTextPointer
+	call PrintText
+	pop bc
+	ret
+; 8b2bb
+
+BattleTower_CheckPartyLengthIs3: ; 8b2bb
+	ld a, [PartyCount]
+	cp 3
+	ret
+; 8b2c1
+
+BattleTower_CheckPartyHasThreeMonsThatAreNotEggs: ; 8b2c1
+	ld hl, PartyCount
+	ld a, [hli]
+	ld b, $0
+	ld c, a
+.loop
+	ld a, [hli]
+	cp EGG
+	jr z, .egg
+	inc b
+
+.egg
+	dec c
+	jr nz, .loop
+	ld a, [PartyCount]
+	cp b
+	ret z
+	ld a, b
+	cp 3
+	ret
+; 8b2da
+
+Function_PartyCountEq3: ; 8b2da
+	ld a, [PartyCount]
+	cp 3
+	ret z
+	scf
+	ret
+; 8b2e2
+
+Function_PartySpeciesAreUnique: ; 8b2e2
+	ld hl, PartyMon1Species
+	call VerifyUniqueness
+	ret
+; 8b2e9
+
+VerifyUniqueness: ; 8b2e9
+	ld de, PartyCount
+	ld a, [de]
+	inc de
+	dec a
+	jr z, .done
+	ld b, a
+.loop
+	push hl
+	push de
+	ld c, b
+	call .isegg
+	jr z, .next
+	ld a, [hl]
+	and a
+	jr z, .next
+.loop2
+	call .nextmon
+	call .isegg
+	jr z, .next2
+	cp [hl]
+	jr z, .gotcha
+
+.next2
+	dec c
+	jr nz, .loop2
+
+.next
+	pop de
+	pop hl
+	call .nextmon
+	dec b
+	jr nz, .loop
+
+.done
+	and a
+	ret
+
+.gotcha
+	pop de
+	pop hl
+	scf
+	ret
+; 8b31a
+
+.nextmon ; 8b31a
+	push bc
+	ld bc, PARTYMON_STRUCT_LENGTH
+	add hl, bc
+	inc de
+	pop bc
+	ret
+; 8b322
+
+.isegg ; 8b322
+	push bc
+	ld b, a
+	ld a, [de]
+	cp EGG
+	ld a, b
+	pop bc
+	ret
+; 8b32a
+
+Function_PartyItemsAreUnique: ; 8b32a
+	ld hl, PartyMon1Item
+	call VerifyUniqueness
+	ret
+; 8b331
+
+Function_HasPartyAnEgg: ; 8b331
+	ld hl, PartyCount
+	ld a, [hli]
+	ld c, a
+.loop
+	ld a, [hli]
+	cp EGG
+	jr z, .found
+	dec c
+	jr nz, .loop
+	and a
+	ret
+
+.found
+	scf
+	ret
+; 8b342
--- a/events/happiness_egg.asm
+++ b/events/happiness_egg.asm
@@ -73,7 +73,7 @@
 	ld d, 0
 	add hl, de
 	ld a, [hl]
-	cp $64 ; $80?
+	cp $64 ; why not $80?
 	pop de
 
 	ld a, [de]
@@ -141,7 +141,9 @@
 	jr nz, .loop
 	ret
 
+
 DayCareStep:: ; 7282
+; Raise the experience of Day-Care Pokémon every step cycle.
 
 	ld a, [wDayCareMan]
 	bit 0, a
--- /dev/null
+++ b/events/odd_egg.asm
@@ -1,0 +1,96 @@
+GiveOddEgg: ; 1fb4b6
+	; Figure out which egg to give.
+
+	; Compare a random word to
+	; probabilities out of 0xffff.
+	call Random
+	ld hl, OddEggProbabilities
+	ld c, 0
+	ld b, c
+.loop
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+
+	; Break on $ffff.
+	ld a, d
+	cp HIGH($ffff)
+	jr nz, .not_done
+	ld a, e
+	cp LOW($ffff)
+	jr z, .done
+.not_done
+
+	; Break when [hRandom] <= de.
+	ld a, [hRandom + 1]
+	cp d
+	jr c, .done
+	jr z, .ok
+	jr .next
+.ok
+	ld a, [hRandom + 0]
+	cp e
+	jr c, .done
+	jr z, .done
+.next
+	inc bc
+	jr .loop
+.done
+
+	ld hl, OddEggs
+	ld a, OddEgg2 - OddEgg1
+	call AddNTimes
+
+	ld de, OddEggSpecies
+	ld bc, PARTYMON_STRUCT_LENGTH + 2 * PKMN_NAME_LENGTH
+	call CopyBytes
+
+	ld a, EGG_TICKET
+	ld [CurItem], a
+	ld a, 1
+	ld [wItemQuantityChangeBuffer], a
+	ld a, -1
+	ld [CurItemQuantity], a
+	ld hl, NumItems
+	call TossItem
+
+	; load species in wcd2a
+	ld a, EGG
+	ld [wMobileMonSpeciesBuffer], a
+
+	; load pointer to (wMobileMonSpeciesBuffer - 1) in wMobileMonSpeciesPointerBuffer
+	ld a, LOW(wMobileMonSpeciesBuffer - 1)
+	ld [wMobileMonSpeciesPointerBuffer], a
+	ld a, HIGH(wMobileMonSpeciesBuffer - 1)
+	ld [wMobileMonSpeciesPointerBuffer + 1], a
+	; load pointer to OddEggSpecies in wMobileMonStructurePointerBuffer
+	ld a, LOW(OddEggSpecies)
+	ld [wMobileMonStructurePointerBuffer], a
+	ld a, HIGH(OddEggSpecies)
+	ld [wMobileMonStructurePointerBuffer + 1], a
+
+	; load Odd Egg Name in wTempOddEggNickname
+	ld hl, .Odd
+	ld de, wTempOddEggNickname
+	ld bc, PKMN_NAME_LENGTH
+	call CopyBytes
+
+	; load pointer to wTempOddEggNickname in wMobileMonOTNamePointerBuffer
+	ld a, LOW(wTempOddEggNickname)
+	ld [wMobileMonOTNamePointerBuffer], a
+	ld a, HIGH(wTempOddEggNickname)
+	ld [wMobileMonOTNamePointerBuffer + 1], a
+	; load pointer to wOddEggName in wMobileMonNicknamePointerBuffer
+	ld a, LOW(wOddEggName)
+	ld [wMobileMonNicknamePointerBuffer], a
+	ld a, HIGH(wOddEggName)
+	ld [wMobileMonNicknamePointerBuffer + 1], a
+	farcall AddMobileMonToParty
+	ret
+; 1fb546
+
+.Odd:
+	db "ODD@@@@@@@@@"
+
+INCLUDE "data/odd_eggs.asm"
--- a/lib/mobile/main.asm
+++ b/lib/mobile/main.asm
@@ -4,7 +4,8 @@
 
 INCLUDE "constants/hardware_constants.asm"
 
-SECTION "Main", ROMX
+
+SECTION "Mobile Adapter SDK", ROMX
 
 Function110000: ; 110000 (44:4000)
 ; Copy b bytes from hl to de
--- a/main.asm
+++ b/main.asm
@@ -190,7 +190,7 @@
 INCLUDE "engine/mail.asm"
 
 
-SECTION "Crystal Unique", ROMX
+SECTION "Crystal Features 1", ROMX
 
 INCLUDE "engine/init_gender.asm"
 INCLUDE "engine/routines/drawkrispackgfx.asm"
@@ -312,7 +312,7 @@
 INCLUDE "events/halloffame.asm"
 
 
-SECTION "bank22", ROMX
+SECTION "Crystal Features 2", ROMX
 
 INCLUDE "events/kurt.asm"
 INCLUDE "engine/player_gfx.asm"
@@ -320,7 +320,7 @@
 INCLUDE "events/crystal_unown.asm"
 INCLUDE "events/buena.asm"
 INCLUDE "events/dratini.asm"
-INCLUDE "events/battle_tower.asm"
+INCLUDE "events/battle_tower_rules.asm"
 INCLUDE "mobile/mobile_22_2.asm"
 
 
@@ -508,7 +508,7 @@
 INCLUDE "gfx/overworld_font.asm"
 
 
-SECTION "mobile_42", ROMX
+SECTION "Mobile 42", ROMX
 
 INCLUDE "mobile/mobile_42.asm"
 
@@ -519,7 +519,7 @@
 INCBIN "gfx/intro/logo.2bpp.lz"
 
 
-SECTION "bank43", ROMX
+SECTION "Title", ROMX
 
 INCLUDE "engine/unused_title.asm"
 INCLUDE "engine/title.asm"
@@ -531,7 +531,7 @@
 INCLUDE "mobile/mobile_46.asm"
 
 
-SECTION "battle_tower_47", ROMX
+SECTION "Battle Tower", ROMX
 
 INCLUDE "mobile/battle_tower_47.asm"
 
@@ -542,7 +542,7 @@
 INCLUDE "engine/link_trade.asm"
 
 
-SECTION "mobile_5c", ROMX
+SECTION "Mobile 5C", ROMX
 
 INCLUDE "mobile/mobile_5c.asm"
 
@@ -552,17 +552,17 @@
 INCLUDE "text/phone/extra2.asm"
 
 
-SECTION "bank5E", ROMX
+SECTION "UpdateBattleHUDs", ROMX
 
 INCLUDE "engine/battle/updatebattlehuds.asm"
 
 
-SECTION "mobile_5e", ROMX
+SECTION "Mobile 5E", ROMX
 
 INCLUDE "mobile/mobile_5e.asm"
 
 
-SECTION "bank5F", ROMX
+SECTION "Mobile 5F", ROMX
 
 INCLUDE "mobile/mobile_5f.asm"
 
@@ -591,7 +591,7 @@
 INCLUDE "text/phone/trainers1.asm"
 
 
-SECTION "bank72", ROMX
+SECTION "Miscellaneous Text", ROMX
 
 INCLUDE "data/items/item_names.asm"
 INCLUDE "data/items/item_descriptions.asm"
@@ -636,13 +636,10 @@
 INCLUDE "mobile/news/news.asm"
 
 
-SECTION "bank7E", ROMX
+SECTION "Crystal Events", ROMX
 
-INCLUDE "engine/battle_tower.asm"
-INCLUDE "engine/odd_eggs.asm"
-
-
-SECTION "bank7F", ROMX
+INCLUDE "events/battle_tower.asm"
+INCLUDE "events/odd_egg.asm"
 
 
 SECTION "Mobile Stadium 2", ROMX
--- a/mobile/mobile_45.asm
+++ b/mobile/mobile_45.asm
@@ -1,4 +1,4 @@
-SECTION "bank45", ROMX
+SECTION "Mobile 45", ROMX
 
 	charmap " ", $20 ; revert to ascii
 
--- a/mobile/mobile_46.asm
+++ b/mobile/mobile_46.asm
@@ -1,4 +1,4 @@
-SECTION "bank46", ROMX
+SECTION "Mobile 46", ROMX
 
 Function118000: ; 118000
 	ld a, $1
@@ -3016,7 +3016,7 @@
 ; 1196cd
 
 
-SECTION "bank46_2", ROMX
+SECTION "Mobile 46 ASCII", ROMX
 ; A hack to use ascii above.
 
 Function1196cd: ; 1196cd (46:56cd)
--- a/pokecrystal.link
+++ b/pokecrystal.link
@@ -68,7 +68,7 @@
 ROMX $11
 	"bank11"
 ROMX $12
-	"Crystal Unique"
+	"Crystal Features 1"
 ROMX $13
 	"bank13"
 ROMX $14
@@ -100,7 +100,7 @@
 ROMX $21
 	"bank21"
 ROMX $22
-	"bank22"
+	"Crystal Features 2"
 ROMX $23
 	"bank23"
 ROMX $24
@@ -174,21 +174,21 @@
 ROMX $41
 	"bank41"
 ROMX $42
-	"mobile_42"
+	"Mobile 42"
 	"Intro Logo"
 	"Credits"
 ROMX $43
-	"bank43"
+	"Title"
 ROMX $44
-	"Main"
+	"Mobile Adapter SDK"
 ROMX $45
-	"bank45"
+	"Mobile 45"
 	"Mobile Stadium"
 ROMX $46
-	"bank46"
-	"bank46_2"
+	"Mobile 46"
+	"Mobile 46 ASCII"
 ROMX $47
-	"battle_tower_47"
+	"Battle Tower"
 ROMX $48
 	org $4000
 	"Pic Pointers"
@@ -235,16 +235,16 @@
 ROMX $5b
 	"bank5B"
 ROMX $5c
-	"mobile_5c"
+	"Mobile 5C"
 ROMX $5d
 	"Crystal Phone Text 2"
 ROMX $5e
-	"bank5E"
+	"UpdateBattleHUDs"
 	"Songs 5"
 	"Crystal Sound Effects"
-	"mobile_5e"
+	"Mobile 5E"
 ROMX $5f
-	"bank5F"
+	"Mobile 5F"
 ROMX $60
 	"Map Scripts 13"
 	"Pokedex Entries 001-064"
@@ -284,7 +284,7 @@
 ROMX $71
 	"Text 3"
 ROMX $72
-	"bank72"
+	"Miscellaneous Text"
 ROMX $73
 	"Pokedex Entries 129-192"
 ROMX $74
@@ -302,9 +302,8 @@
 ROMX $7d
 	"Mobile News Data"
 ROMX $7e
-	"bank7E"
+	"Crystal Events"
 ROMX $7f
-	"bank7F"
 	org $7de0
 	"Mobile Stadium 2"
 WRAM0
@@ -325,7 +324,7 @@
 WRAMX 2
 	"Pic Animations"
 WRAMX 3
-	"Battle Tower"
+	"Battle Tower RAM"
 WRAMX 5
 	"GBC Video"
 	org $d300
--- a/wram.asm
+++ b/wram.asm
@@ -2818,7 +2818,7 @@
 wPokeAnimStructEnd::
 
 
-SECTION "Battle Tower", WRAMX
+SECTION "Battle Tower RAM", WRAMX
 
 w3_d000:: ds 1 ; d000
 w3_d001:: ds 1