shithub: pokecrystal

Download patch

ref: 533fdd8b4c4fb64046e42ed5c8d60118e690d8b1
parent: ee8479f05ebcfed30a5a47b60d8e50c0d99525b8
author: Thomas Winwood <twwinwood@gmail.com>
date: Tue Jun 26 17:32:44 EDT 2018

Add fix for battle transition bug

--- a/docs/bugs_and_glitches.md
+++ b/docs/bugs_and_glitches.md
@@ -887,18 +887,49 @@
 
 ([Video](https://www.youtube.com/watch?v=eij_1060SMc))
 
-This is a bug with `StartTrainerBattle_DetermineWhichAnimation` in [engine/battle/battle_transition.asm](/engine/battle/battle_transition.asm):
+**Fix:**
 
-```asm
+There's three things wrong here.
+
+* `wEnemyMonLevel` doesn't have the value its name implies yet; it'll be populated later from `wCurPartyLevel`.
+* `wBattleMonLevel` gets overwritten between when the value is written in `FindFirstAliveMonAndStartBattle` and when it's read.
+* `wBattleMonLevel` isn't set until much later when the battle is with a trainer; extra code is needed to read a trainer's party and get the level of their lead Pokémon.
+
+First, in [engine/battle/battle_transition.asm](/engine/battle/battle_transition.asm):
+
+```diff
 StartTrainerBattle_DetermineWhichAnimation:
 ; The screen flashes a different number of times depending on the level of
 ; your lead Pokemon relative to the opponent's.
-; BUG: wBattleMonLevel and wEnemyMonLevel are not set at this point, so whatever
-; values happen to be there will determine the animation.
+-; BUG: wBattleMonLevel and wEnemyMonLevel are not set at this point, so whatever
+-; values happen to be there will determine the animation.
++	ld a, [wOtherTrainerClass]
++	and a
++	jr z, .wild
++	farcall SetTrainerBattleLevel
++
++.wild
++	ld b, PARTY_LENGTH
++	ld hl, wPartyMon1HP
++	ld de, PARTYMON_STRUCT_LENGTH - 1
++
++.loop
++	ld a, [hli]
++	or [hl]
++	jr nz, .okay
++	add hl, de
++	dec b
++	jr nz, .loop
++
++.okay
++	ld de, MON_LEVEL - MON_HP
++	add hl, de
 	ld de, 0
-	ld a, [wBattleMonLevel]
+-	ld a, [wBattleMonLevel]
++	ld a, [hl]
 	add 3
-	ld hl, wEnemyMonLevel
+-	ld hl, wEnemyMonLevel
++	ld hl, wCurPartyLevel
 	cp [hl]
 	jr nc, .not_stronger
 	set TRANS_STRONGER_F, e
@@ -926,7 +957,82 @@
 	db BATTLETRANSITION_NO_CAVE_STRONGER
 ```
 
-*To do:* Fix this bug.
+In [engine/battle/start_battle.asm](/engine/battle/start_battle.asm):
+
+```diff
+FindFirstAliveMonAndStartBattle:
+	xor a
+	ld [hMapAnims], a
+	call DelayFrame
+-	ld b, 6
+-	ld hl, wPartyMon1HP
+-	ld de, PARTYMON_STRUCT_LENGTH - 1
+-
+-.loop
+-	ld a, [hli]
+-	or [hl]
+-	jr nz, .okay
+-	add hl, de
+-	dec b
+-	jr nz, .loop
+-
+-.okay
+-	ld de, MON_LEVEL - MON_HP
+-	add hl, de
+-	ld a, [hl]
+-	ld [wBattleMonLevel], a
+	predef DoBattleTransition
+```
+
+Finally, add this code to the end of [engine/battle/read_trainer_party.asm](/engine/battle/read_trainer_party.asm):
+
+```asm
+SetTrainerBattleLevel:
+	ld a, 255
+	ld [wCurPartyLevel], a
+
+	ld a, [wInBattleTowerBattle]
+	bit 0, a
+	ret nz
+
+	ld a, [wLinkMode]
+	and a
+	ret nz
+
+	ld a, [wOtherTrainerClass]
+	dec a
+	ld c, a
+	ld b, 0
+	ld hl, TrainerGroups
+rept 2
+	add hl, bc
+endr
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+
+	ld a, [wOtherTrainerID]
+	ld b, a
+.skip_trainer
+	dec b
+	jr z, .got_trainer
+.loop1
+	ld a, [hli]
+	cp $ff
+	jr nz, .loop1
+	jr .skip_trainer
+.got_trainer
+
+.skip_name
+	ld a, [hli]
+	cp "@"
+	jr nz, .skip_name
+
+	inc hl
+	ld a, [hl]
+	ld [wCurPartyLevel], a
+	ret
+```
 
 
 ## A "HOF Master!" title for 200-Time Famers is defined but inaccessible