@@ -1,13 +1,103 @@
# 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 ))
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 @@ BattleCommand_BellyDrum: ; 37c1a
**Fix:**
```
```asm
BattleCommand_BellyDrum: ; 37c1a
; bellydrum
callab GetHalfMaxHP
@@ -39,13 +129,13 @@ BattleCommand_BellyDrum: ; 37c1a
```
## 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 @@ This is a bug with `LongAnim_UpdateVariables` in [engine/anim_hp_bar.asm](engine
**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 can bring Pokémon straight from level 1 to 100 by gaining just a few exper
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 @@ CalcExpAtLevel: ; 50e47
**Fix:**
```
```asm
CalcExpAtLevel: ; 50e47
; (a/b)*n**3 + c*n**2 + d*n - e
ld a , d
@@ -121,7 +237,7 @@ CalcExpAtLevel: ; 50e47
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,7 +254,84 @@ Text_StringBuffer2ExpPoints::
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
@@ -149,7 +342,7 @@ This bug existed for all battles in Gold and Silver, and was only fixed for sing
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 @@ BattleCommand_Present: ; 37874
**Fix:**
```
```asm
BattleCommand_Present: ; 37874
; present
@@ -188,7 +381,7 @@ BattleCommand_Present: ; 37874
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 `PokeBall` in [items/item_effects.asm](items/item_effects.asm
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 @@ MoonBallMultiplier:
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 @@ LoveBallMultiplier:
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 @@ FastBallMultiplier:
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 `PokeBall` in [items/item_effects.asm](items/item_effects.asm
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 `ItemAttributes` in [items/item_attributes.asm](items/item_at
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,18 +559,89 @@ CopyPokemonName_Buffer1_Buffer3: ; 746e
**Fix:**
```
```asm
Data_DaisyMassage: ; 746b
db $80 , 2 , HAPPINESS_MASSAGE ; 50% chance
db $ff , 2 , HAPPINESS_MASSAGE ; 50% chance
```
## 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 @@ This is a bug with `DoPlayerMovement.CheckWarp` in [engine/player_movement.asm](
**Fix:**
```
```asm
ld a , [ WalkingDirection ]
cp STANDING
jr z , .not_warp
@@ -419,6 +683,13 @@ This is a bug with `DoPlayerMovement.CheckWarp` in [engine/player_movement.asm](
```
## 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 @@ This bug can allow you to talk to Eusine in Celadon City and encounter Ho-Oh wit
[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 @@ endr
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 @@ This is a bug with `PokeBall` in [items/item_effects.asm](items/item_effects.asm
[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 @@ ScriptCall:
[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 @@ LoadSpriteGFX: ; 14306
[engine/wildmons.asm ](engine/wildmons.asm ):
```
```asm
ChooseWildEncounter: ; 2a14f
...
@@ -583,7 +854,7 @@ ValidateTempWildMonSpecies: ; 2a4a0
**Fix:**
```
```asm
ld a , b
ld [ CurPartyLevel ], a
ld b , [ hl ]
@@ -599,7 +870,7 @@ ValidateTempWildMonSpecies: ; 2a4a0
[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 @@ ValidateTempWildMonSpecies: ; 2a4a0
[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 @@ BugCatchingContestantEventFlagTable: ; 139fe
[home/init.asm ](home/init.asm ):
```
```asm
ClearWRAM: : ; 25a
; Wipe swappable WRAM banks (1-7)
; Assumes CGB or AGB
@@ -693,7 +964,7 @@ ClearWRAM:: ; 25a
[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 @@ GetForestTreeFrame: ; fc54c
**Fix:**
```
```asm
GetForestTreeFrame: ; fc54c
; Return 0 if a is even, or 2 if odd.
and 1