shithub: pokecrystal

Download patch

ref: 10eb426e40f48df3ae9b40e3ea3aa7e92f890090
parent: c85587d973df6565f2863493acb9f9af88518662
author: Remy Oukaour <remy.oukaour@gmail.com>
date: Tue Dec 12 17:58:20 EST 2017

Document more bugs

--- a/battle/ai/items.asm
+++ b/battle/ai/items.asm
@@ -749,7 +749,7 @@
 Function384d5: ; This appears to be unused
 	call AIUsedItemSound
 	call AI_HealStatus
-	ld a, X_SPEED
+	ld a, FULL_HEAL_RED ; X_SPEED
 	jp PrintText_UsedItemOn_AND_AIUpdateHUD
 ; 384e0
 
@@ -761,6 +761,10 @@
 	xor a
 	ld [hl], a
 	ld [EnemyMonStatus], a
+	; Bug: this should reset SUBSTATUS_NIGHTMARE too
+	; Uncomment the lines below to fix
+	; ld hl, EnemySubStatus1
+	; res SUBSTATUS_NIGHTMARE, [hl]
 	ld hl, EnemySubStatus5
 	res SUBSTATUS_TOXIC, [hl]
 	ret
--- a/battle/ai/scoring.asm
+++ b/battle/ai/scoring.asm
@@ -1876,7 +1876,8 @@
 	pop hl
 	jp z, AIDiscourageMove
 
-; 80% chance to greatly encourage this move if the enemy is badly poisoned (weird).
+; 80% chance to greatly encourage this move if the enemy is badly poisoned (buggy).
+; Should check PlayerSubStatus5 instead.
 	ld a, [EnemySubStatus5]
 	bit SUBSTATUS_TOXIC, a
 	jr nz, .asm_38e26
--- a/battle/core.asm
+++ b/battle/core.asm
@@ -5998,7 +5998,7 @@
 	swap a
 	and $f
 	ld b, a
-	ld d, $5
+	ld d, NUM_MOVES + 1
 	xor a
 .loop
 	dec d
@@ -6011,7 +6011,9 @@
 	jr .loop
 
 .done
-	and a ; This is probably a bug, and will result in a move with PP Up confusing the game.
+	; Bug: this will result in a move with PP Up confusing the game.
+	; Replace with "and $3f" to fix.
+	and a
 	ret nz
 
 .force_struggle
--- a/constants/item_constants.asm
+++ b/constants/item_constants.asm
@@ -272,6 +272,7 @@
 ; leftovers from red
 SAFARI_BALL    EQU $08 ; MOON_STONE
 MOON_STONE_RED EQU $0A ; BURN_HEAL
+FULL_HEAL_RED  EQU $34 ; X_SPEED
 
 ; mail
 MAIL_MSG_LENGTH    EQU $20
--- a/docs/bugs.md
+++ b/docs/bugs.md
@@ -1,6 +1,96 @@
 # Bugs and Glitches
 
 
+## Thick Club and Light Ball can decrease damage done with boosted (Special) Attack
+
+([Video](https://www.youtube.com/watch?v=rGqu3d3pdok&t=450))
+
+This is a bug with `SpeciesItemBoost` in [battle/effect_commands.asm](battle/effect_commands.asm):
+
+```asm
+; Double the stat
+	sla l
+	rl h
+	ret
+```
+
+**Fix:**
+
+```asm
+; Double the stat
+	sla l
+	rl h
+
+	ld a, 999 / $100
+	cp h
+	jr c, .cap
+	ld a, 999 % $100
+	cp l
+	ret nc
+
+.cap
+	ld h, 999 / $100
+	ld l, 999 % $100
+	ret
+```
+
+
+## Metal Powder can increase damage taken with boosted (Special) Defense
+
+([Video](https://www.youtube.com/watch?v=rGqu3d3pdok&t=450))
+
+This is a bug with `DittoMetalPowder` in [battle/effect_commands.asm](battle/effect_commands.asm):
+
+```asm
+	ld a, c
+	srl a
+	add c
+	ld c, a
+	ret nc
+
+	srl b
+	ld a, b
+	and a
+	jr nz, .done
+	inc b
+.done
+	scf
+	rr c
+	ret
+```
+
+**Fix:**
+
+```asm
+	ld a, c
+	srl a
+	add c
+	ld c, a
+	ret nc
+
+	srl b
+	ld a, b
+	and a
+	jr nz, .done
+	inc b
+.done
+	scf
+	rr c
+
+	ld a, 999 / $100
+	cp b
+	jr c, .cap
+	ld a, 999 % $100
+	cp c
+	ret nc
+
+.cap
+	ld b, 999 / $100
+	ld c, 999 % $100
+	ret
+```
+
+
 ## Belly Drum sharply boosts Attack even with under 50% HP
 
 ([Video](https://www.youtube.com/watch?v=zuCLMikWo4Y))
@@ -7,7 +97,7 @@
 
 This is a bug with `BattleCommand_BellyDrum` in [battle/effect_commands.asm](battle/effect_commands.asm):
 
-```
+```asm
 BattleCommand_BellyDrum: ; 37c1a
 ; bellydrum
 ; This command is buggy because it raises the user's attack
@@ -25,7 +115,7 @@
 
 **Fix:**
 
-```
+```asm
 BattleCommand_BellyDrum: ; 37c1a
 ; bellydrum
 	callab GetHalfMaxHP
@@ -39,13 +129,13 @@
 ```
 
 
-## HP bar animation is slower with more HP
+## HP bar animation is slow for high HP
 
 ([Video](https://www.youtube.com/watch?v=SE-BfsFgZVM))
 
 This is a bug with `LongAnim_UpdateVariables` in [engine/anim_hp_bar.asm](engine/anim_hp_bar.asm):
 
-```
+```asm
 	; This routine is buggy. The result from ComputeHPBarPixels is stored
 	; in e. However, the pop de opcode deletes this result before it is even
 	; used. The game then proceeds as though it never deleted that output.
@@ -67,6 +157,32 @@
 **Fix:** Move `ld a, e` to right after `call ComputeHPBarPixels`.
 
 
+## HP bar animation off-by-one error for low HP
+
+([Video](https://www.youtube.com/watch?v=9KyNVIZxJvI))
+
+This is a bug with `ShortHPBar_CalcPixelFrame` in [engine/anim_hp_bar.asm](engine/anim_hp_bar.asm):
+
+```asm
+	ld b, 0
+; This routine is buggy. If [wCurHPAnimMaxHP] * [wCurHPBarPixels] is divisible
+; by 48, the loop runs one extra time. To fix, uncomment the line below.
+.loop
+	ld a, l
+	sub 6 * 8
+	ld l, a
+	ld a, h
+	sbc $0
+	ld h, a
+	; jr z, .done
+	jr c, .done
+	inc b
+	jr .loop
+```
+
+**Fix:** Uncomment `jr z, .done`.
+
+
 ## Experience underflow for level 1 Pokémon with Medium-Slow growth rate
 
 ([Video](https://www.youtube.com/watch?v=SXH8u0plHrE))
@@ -75,7 +191,7 @@
 
 This is a bug with `CalcExpAtLevel` in [main.asm](main.asm):
 
-```
+```asm
 CalcExpAtLevel: ; 50e47
 ; (a/b)*n**3 + c*n**2 + d*n - e
 	ld a, [BaseGrowthRate]
@@ -89,7 +205,7 @@
 
 **Fix:**
 
-```
+```asm
 CalcExpAtLevel: ; 50e47
 ; (a/b)*n**3 + c*n**2 + d*n - e
 	ld a, d
@@ -121,7 +237,7 @@
 
 This is a bug with `Text_ABoostedStringBuffer2ExpPoints` and `Text_StringBuffer2ExpPoints` in [text/common_2.asm](text/common_2.asm):
 
-```
+```asm
 Text_ABoostedStringBuffer2ExpPoints::
 	text ""
 	line "a boosted"
@@ -138,9 +254,86 @@
 	prompt
 ```
 
-**Fix:** Change `deciram StringBuffer2, 2, 4` to `deciram StringBuffer2, 2, 5`.
+**Fix:** Change both `deciram StringBuffer2, 2, 4` to `deciram StringBuffer2, 2, 5`.
 
 
+## NPC use of Full Heal or Full Restore does not cure Nightmare status
+
+([Video](https://www.youtube.com/watch?v=rGqu3d3pdok&t=322)
+
+This is a bug with `AI_HealStatus` in [battle/ai/items.asm](battle/ai/items.asm):
+
+```asm
+AI_HealStatus: ; 384e0
+	ld a, [CurOTMon]
+	ld hl, OTPartyMon1Status
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call AddNTimes
+	xor a
+	ld [hl], a
+	ld [EnemyMonStatus], a
+	; Bug: this should reset SUBSTATUS_NIGHTMARE too
+	; Uncomment the lines below to fix
+	; ld hl, EnemySubStatus1
+	; res SUBSTATUS_NIGHTMARE, [hl]
+	ld hl, EnemySubStatus5
+	res SUBSTATUS_TOXIC, [hl]
+	ret
+; 384f7
+```
+
+**Fix:** Uncomment `ld hl, EnemySubStatus1` and `res SUBSTATUS_NIGHTMARE, [hl]`.
+
+
+## "Smart" AI encourages Mean Look if its own Pokémon is badly poisoned
+
+([Video](https://www.youtube.com/watch?v=cygMO-zHTls))
+
+This is a bug with `AI_Smart_MeanLook` in [battle/ai/scoring.asm](battle/ai/scoring.asm):
+
+```asm
+; 80% chance to greatly encourage this move if the enemy is badly poisoned (buggy).
+; Should check PlayerSubStatus5 instead.
+	ld a, [EnemySubStatus5]
+	bit SUBSTATUS_TOXIC, a
+	jr nz, .asm_38e26
+```
+
+**Fix:** Change `EnemySubStatus5` to `PlayerSubStatus5`.
+
+
+## A Disabled, PP Up–enhanced move may not trigger automatic Struggling
+
+([Video](https://www.youtube.com/watch?v=1v9x4SgMggs))
+
+This is a bug with `CheckPlayerHasUsableMoves` in [battle/core.asm](battle/core.asm):
+
+```asm
+.done
+	; Bug: this will result in a move with PP Up confusing the game.
+	; Replace with "and $3f" to fix.
+	and a
+	ret nz
+
+.force_struggle
+	ld hl, BattleText_PkmnHasNoMovesLeft
+	call StdBattleTextBox
+	ld c, 60
+	call DelayFrames
+	xor a
+	ret
+```
+
+**Fix:** Change `and a` to `and $3f`.
+
+
+## Counter and Mirror Coat still work if the opponent uses an item
+
+([Video](https://www.youtube.com/watch?v=uRYyzKRatFk))
+
+*To do:* Identify specific code causing this bug and fix it.
+
+
 ## Present damage is incorrect in link battles
 
 ([Video](https://www.youtube.com/watch?v=XJaQoKtrEuw))
@@ -149,7 +342,7 @@
 
 This is a bug with `BattleCommand_Present` in [battle/effects/present.asm](battle/effects/present.asm):
 
-```
+```asm
 BattleCommand_Present: ; 37874
 ; present
 
@@ -172,7 +365,7 @@
 
 **Fix:**
 
-```
+```asm
 BattleCommand_Present: ; 37874
 ; present
 
@@ -188,7 +381,7 @@
 
 This is a bug with `PokeBall` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 .statuscheck
 ; This routine is buggy. It was intended that SLP and FRZ provide a higher
 ; catch rate than BRN/PSN/PAR, which in turn provide a higher catch rate than
@@ -220,7 +413,7 @@
 
 This is a bug with `MoonBallMultiplier` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 MoonBallMultiplier:
 ; This function is buggy.
 ; Intent:  multiply catch rate by 4 if mon evolves with moon stone
@@ -246,7 +439,7 @@
 
 This is a bug with `LoveBallMultiplier` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 LoveBallMultiplier:
 ; This function is buggy.
 ; Intent:  multiply catch rate by 8 if mons are of same species, different sex
@@ -268,7 +461,7 @@
 
 This is a bug with `FastBallMultiplier` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 FastBallMultiplier:
 ; This function is buggy.
 ; Intent:  multiply catch rate by 4 if enemy mon is in one of the three
@@ -294,7 +487,7 @@
 
 This is a bug with `PokeBall` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 	ld a, [CurItem]
 	cp FRIEND_BALL
 	jr nz, .SkipBoxMonFriendBall
@@ -311,7 +504,7 @@
 
 This is a bug with `ItemAttributes` in [items/item_attributes.asm](items/item_attributes.asm):
 
-```
+```asm
 ; DRAGON FANG
 	item_attribute 100, 0, 0, CANT_SELECT, ITEM, ITEMMENU_NOUSE, ITEMMENU_NOUSE
 
@@ -328,7 +521,7 @@
 
 This is a bug with `MassageOrHaircut` in [event/special.asm](event/special.asm):
 
-```
+```asm
 ; Bug: Subtracting $ff from $ff fails to set c.
 ; This can result in overflow into the next data array.
 ; In the case of getting a massage from Daisy, we bleed
@@ -366,7 +559,7 @@
 
 **Fix:**
 
-```
+```asm
 Data_DaisyMassage: ; 746b
 	db $80, 2, HAPPINESS_MASSAGE ; 50% chance
 	db $ff, 2, HAPPINESS_MASSAGE ; 50% chance
@@ -373,11 +566,82 @@
 ```
 
 
+## Magikarp in Lake of Rage are shorter, not longer
+
+This is a bug with `LoadEnemyMon.CheckMagikarpArea` in [battle/core.asm](battle/core.asm):
+
+```asm
+.CheckMagikarpArea:
+; The z checks are supposed to be nz
+; Instead, all maps in GROUP_LAKE_OF_RAGE (mahogany area)
+; and routes 20 and 44 are treated as Lake of Rage
+
+; This also means Lake of Rage Magikarp can be smaller than ones
+; caught elsewhere rather than the other way around
+
+; Intended behavior enforces a minimum size at Lake of Rage
+; The real behavior prevents size flooring in the Lake of Rage area
+	ld a, [MapGroup]
+	cp GROUP_LAKE_OF_RAGE
+	jr z, .Happiness
+	ld a, [MapNumber]
+	cp MAP_LAKE_OF_RAGE
+	jr z, .Happiness
+```
+
+**Fix:** Change both `jr z, .Happiness` to `jr nz, .Happiness`.
+
+
+## Battle transitions fail to account for the enemy's level
+
+([Video](https://www.youtube.com/watch?v=eij_1060SMc))
+
+This is a bug with `StartTrainerBattle_DetermineWhichAnimation` in [engine/battle_start.asm](engine/battle_start.asm):
+
+```
+StartTrainerBattle_DetermineWhichAnimation: ; 8c365 (23:4365)
+; The screen flashes a different number of times depending on the level of
+; your lead Pokemon relative to the opponent's.
+; BUG: BattleMonLevel and EnemyMonLevel are not set at this point, so whatever
+; values happen to be there will determine the animation.
+	ld de, 0
+	ld a, [BattleMonLevel]
+	add 3
+	ld hl, EnemyMonLevel
+	cp [hl]
+	jr nc, .okay
+	set 0, e
+.okay
+	ld a, [wPermission]
+	cp CAVE
+	jr z, .okay2
+	cp PERM_5
+	jr z, .okay2
+	cp DUNGEON
+	jr z, .okay2
+	set 1, e
+.okay2
+	ld hl, .StartingPoints
+	add hl, de
+	ld a, [hl]
+	ld [wJumptableIndex], a
+	ret
+; 8c38f (23:438f)
+
+.StartingPoints: ; 8c38f
+	db 1,  9
+	db 16, 24
+; 8c393
+```
+
+*To do:* Fix this bug.
+
+
 ## No bump noise if standing on tile `$3E`
 
 This is a bug with `DoPlayerMovement.CheckWarp` in [engine/player_movement.asm](engine/player_movement.asm):
 
-```
+```asm
 ; Bug: Since no case is made for STANDING here, it will check
 ; [.edgewarps + $ff]. This resolves to $3e at $8035a.
 ; This causes wd041 to be nonzero when standing on tile $3e,
@@ -401,7 +665,7 @@
 
 **Fix:**
 
-```
+```asm
 	ld a, [WalkingDirection]
 	cp STANDING
 	jr z, .not_warp
@@ -419,6 +683,13 @@
 ```
 
 
+## Surfing directly across a map connection does not load the new map
+
+([Video](https://www.youtube.com/watch?v=XFOWvMNG-zw))
+
+*To do:* Identify specific code causing this bug and fix it.
+
+
 ## `CheckOwnMon` only checks the first five letters of OT names
 
 ([Video](https://www.youtube.com/watch?v=GVTTmReM4nQ))
@@ -427,7 +698,7 @@
 
 [engine/search.asm](engine/search.asm):
 
-```
+```asm
 ; check OT
 ; This only checks five characters, which is fine for the Japanese version,
 ; but in the English version the player name is 7 characters, so this is wrong.
@@ -463,7 +734,7 @@
 
 This is a bug with `PokeBall` in [items/item_effects.asm](items/item_effects.asm):
 
-```
+```asm
 	; BUG: callba overwrites a,
 	; and GetItemHeldEffect takes b anyway.
 
@@ -487,7 +758,7 @@
 
 [engine/scripting.asm](engine/scripting.asm):
 
-```
+```asm
 ScriptCall:
 ; Bug: The script stack has a capacity of 5 scripts, yet there is
 ; nothing to stop you from pushing a sixth script.  The high part
@@ -525,7 +796,7 @@
 
 [engine/overworld.asm](engine/overworld.asm):
 
-```
+```asm
 LoadSpriteGFX: ; 14306
 ; Bug: b is not preserved, so
 ; it's useless as a next count.
@@ -560,7 +831,7 @@
 
 [engine/wildmons.asm](engine/wildmons.asm):
 
-```
+```asm
 ChooseWildEncounter: ; 2a14f
 ...
 
@@ -583,7 +854,7 @@
 
 **Fix:**
 
-```
+```asm
 	ld a, b
 	ld [CurPartyLevel], a
 	ld b, [hl]
@@ -599,7 +870,7 @@
 
 [engine/events.asm](engine/events.asm):
 
-```
+```asm
 ; Bug: If IsInArray returns nc, data at bc will be executed as code.
 	push bc
 	ld de, 3
@@ -627,7 +898,7 @@
 
 [event/bug_contest_2.asm](event/bug_contest_2.asm):
 
-```
+```asm
 Special_CheckBugContestContestantFlag: ; 139ed
 ; Checks the flag of the Bug Catching Contestant whose index is loaded in a.
 
@@ -665,7 +936,7 @@
 
 [home/init.asm](home/init.asm):
 
-```
+```asm
 ClearWRAM:: ; 25a
 ; Wipe swappable WRAM banks (1-7)
 ; Assumes CGB or AGB
@@ -693,7 +964,7 @@
 
 [tilesets/animations.asm](tilesets/animations.asm):
 
-```
+```asm
 GetForestTreeFrame: ; fc54c
 ; Return 0 if a is even, or 2 if odd.
 	and a
@@ -722,7 +993,7 @@
 
 **Fix:**
 
-```
+```asm
 GetForestTreeFrame: ; fc54c
 ; Return 0 if a is even, or 2 if odd.
 	and 1
--- a/engine/anim_hp_bar.asm
+++ b/engine/anim_hp_bar.asm
@@ -382,7 +382,10 @@
 	and a
 	jr z, .return_zero
 	call AddNTimes
+
 	ld b, 0
+; This routine is buggy. If [wCurHPAnimMaxHP] * [wCurHPBarPixels] is divisible
+; by 48, the loop runs one extra time. To fix, uncomment the line below.
 .loop
 	ld a, l
 	sub 6 * 8
@@ -390,6 +393,7 @@
 	ld a, h
 	sbc $0
 	ld h, a
+	; jr z, .done
 	jr c, .done
 	inc b
 	jr .loop
--- a/engine/battle_start.asm
+++ b/engine/battle_start.asm
@@ -196,9 +196,10 @@
 
 
 StartTrainerBattle_DetermineWhichAnimation: ; 8c365 (23:4365)
-; The screen flashes a different number of
-; times depending on the level of your lead
-; Pokemon relative to the opponent's.
+; The screen flashes a different number of times depending on the level of
+; your lead Pokemon relative to the opponent's.
+; BUG: BattleMonLevel and EnemyMonLevel are not set at this point, so whatever
+; values happen to be there will determine the animation.
 	ld de, 0
 	ld a, [BattleMonLevel]
 	add 3