Revise bugs_and_glitches.md

This commit is contained in:
Rangi 2020-01-04 17:08:25 -05:00
parent 5728d01417
commit 9aeb0ab522

View File

@ -15,8 +15,6 @@ Some fixes are mentioned as breaking compatibility with link battles. This can b
## Contents ## Contents
- [Berserk Gene's confusion lasts for 256 turns or the previous Pokémon's confusion count](#berserk-genes-confusion-lasts-for-256-turns-or-the-previous-Pokémons-confusion-count)
- [A Transformed Pokémon knowing Sketch can give itself otherwise unobtainable moves](#a-transformed-pokémon-knowing-sketch-can-give-itself-otherwise-unobtainable-moves)
- [Perish Song and Spikes can leave a Pokémon with 0 HP and not faint](#perish-song-and-spikes-can-leave-a-pokémon-with-0-hp-and-not-faint) - [Perish Song and Spikes can leave a Pokémon with 0 HP and not faint](#perish-song-and-spikes-can-leave-a-pokémon-with-0-hp-and-not-faint)
- [Thick Club and Light Ball can make (Special) Attack wrap around above 1024](#thick-club-and-light-ball-can-make-special-attack-wrap-around-above-1024) - [Thick Club and Light Ball can make (Special) Attack wrap around above 1024](#thick-club-and-light-ball-can-make-special-attack-wrap-around-above-1024)
- [Metal Powder can increase damage taken with boosted (Special) Defense](#metal-powder-can-increase-damage-taken-with-boosted-special-defense) - [Metal Powder can increase damage taken with boosted (Special) Defense](#metal-powder-can-increase-damage-taken-with-boosted-special-defense)
@ -24,6 +22,7 @@ Some fixes are mentioned as breaking compatibility with link battles. This can b
- [Glacier Badge may not boost Special Defense depending on the value of Special Attack](#glacier-badge-may-not-boost-special-defense-depending-on-the-value-of-special-attack) - [Glacier Badge may not boost Special Defense depending on the value of Special Attack](#glacier-badge-may-not-boost-special-defense-depending-on-the-value-of-special-attack)
- [Moves with a 100% secondary effect chance will not trigger it in 1/256 uses](#moves-with-a-100-secondary-effect-chance-will-not-trigger-it-in-1256-uses) - [Moves with a 100% secondary effect chance will not trigger it in 1/256 uses](#moves-with-a-100-secondary-effect-chance-will-not-trigger-it-in-1256-uses)
- [Belly Drum sharply boosts Attack even with under 50% HP](#belly-drum-sharply-boosts-attack-even-with-under-50-hp) - [Belly Drum sharply boosts Attack even with under 50% HP](#belly-drum-sharply-boosts-attack-even-with-under-50-hp)
- [Berserk Gene's confusion lasts for 256 turns or the previous Pokémon's confusion count](#berserk-genes-confusion-lasts-for-256-turns-or-the-previous-Pokémons-confusion-count)
- [Confusion damage is affected by type-boosting items and Explosion/Self-Destruct doubling](#confusion-damage-is-affected-by-type-boosting-items-and-explosionself-destruct-doubling) - [Confusion damage is affected by type-boosting items and Explosion/Self-Destruct doubling](#confusion-damage-is-affected-by-type-boosting-items-and-explosionself-destruct-doubling)
- [Saves corrupted by mid-save shutoff are not handled](#saves-corrupted-by-mid-save-shutoff-are-not-handled) - [Saves corrupted by mid-save shutoff are not handled](#saves-corrupted-by-mid-save-shutoff-are-not-handled)
- [Moves that lower Defense can do so after breaking a Substitute](#moves-that-lower-defense-can-do-so-after-breaking-a-substitute) - [Moves that lower Defense can do so after breaking a Substitute](#moves-that-lower-defense-can-do-so-after-breaking-a-substitute)
@ -36,6 +35,7 @@ Some fixes are mentioned as breaking compatibility with link battles. This can b
- [Beat Up may fail to raise Substitute](#beat-up-may-fail-to-raise-substitute) - [Beat Up may fail to raise Substitute](#beat-up-may-fail-to-raise-substitute)
- [Beat Up may trigger King's Rock even if it failed](#beat-up-may-trigger-kings-rock-even-if-it-failed) - [Beat Up may trigger King's Rock even if it failed](#beat-up-may-trigger-kings-rock-even-if-it-failed)
- [Present damage is incorrect in link battles](#present-damage-is-incorrect-in-link-battles) - [Present damage is incorrect in link battles](#present-damage-is-incorrect-in-link-battles)
- [A Transformed Pokémon can use Sketch and learn otherwise unobtainable moves](#a-transformed-pokémon-can-use-sketch-and-learn-otherwise-unobtainable-moves)
- ["Smart" AI encourages Mean Look if its own Pokémon is badly poisoned](#smart-ai-encourages-mean-look-if-its-own-pokémon-is-badly-poisoned) - ["Smart" AI encourages Mean Look if its own Pokémon is badly poisoned](#smart-ai-encourages-mean-look-if-its-own-pokémon-is-badly-poisoned)
- [AI makes a false assumption about `CheckTypeMatchup`](#ai-makes-a-false-assumption-about-checktypematchup) - [AI makes a false assumption about `CheckTypeMatchup`](#ai-makes-a-false-assumption-about-checktypematchup)
- [NPC use of Full Heal or Full Restore does not cure Nightmare status](#npc-use-of-full-heal-or-full-restore-does-not-cure-nightmare-status) - [NPC use of Full Heal or Full Restore does not cure Nightmare status](#npc-use-of-full-heal-or-full-restore-does-not-cure-nightmare-status)
@ -80,69 +80,23 @@ Some fixes are mentioned as breaking compatibility with link battles. This can b
- [`BattleAnimCmd_ClearObjs` only clears the first 6⅔ objects](#battleanimcmd_clearobjs-only-clears-the-first-6-objects) - [`BattleAnimCmd_ClearObjs` only clears the first 6⅔ objects](#battleanimcmd_clearobjs-only-clears-the-first-6-objects)
## Berserk Gene's confusion lasts for 256 turns or the previous Pokémon's confusion count
*Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.*
([Video](https://youtube.com/watch?v=Pru3mohq20A))
**Fix:** Edit `HandleBerserkGene` in [engine/battle/core.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/core.asm)
(This makes the Berserk Gene use the regular confusion formula (2-5 turns))
```diff
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVarAddr
push af
set SUBSTATUS_CONFUSED, [hl]
+ ld a, [hBattleTurn]
+ and a
+ ld hl, wEnemyConfuseCount
+ jr z, .set_confuse_count
+ ld hl, wPlayerConfuseCount
+.set_confuse_count
+ call BattleRandom
+ and %11
+ add a, 2
+ ld [hl], a
ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVarAddr
```
## A Transformed Pokémon knowing Sketch can give itself otherwise unobtainable moves
([Video](https://www.youtube.com/watch?v=AFiBxAOkCGI))
**Fix:** Edit `BattleCommand_Sketch` in [engine/battle/move_effects/sketch.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/move_effects/sketch.asm)
```diff
-; If the opponent is transformed, fail.
+; If the user is transformed, fail.
- ld a, BATTLE_VARS_SUBSTATUS5_OPP
+ ld a, BATTLE_VARS_SUBSTATUS5
call GetBattleVarAddr
bit SUBSTATUS_TRANSFORMED, [hl]
jp nz, .fail
```
## Perish Song and Spikes can leave a Pokémon with 0 HP and not faint ## Perish Song and Spikes can leave a Pokémon with 0 HP and not faint
*Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.* *Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.*
([Video](https://cdn.discordapp.com/attachments/487424856913346580/653998883185360913/death_metal.mp4)) ([Video](https://www.youtube.com/watch?v=1IiPWw5fMf8&t=85))
**Fix:** Edit `CheckFaint_PlayerThenEnemy` and `CheckFaint_EnemyThenPlayer` in [engine/battle/core.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/core.asm) **Fix:** Edit `CheckFaint_PlayerThenEnemy` and `CheckFaint_EnemyThenPlayer` in [engine/battle/core.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/core.asm):
```diff ```diff
jp HandleEncore jp HandleEncore
+HasAnyoneFainted: +HasAnyoneFainted:
+ call HasPlayerFainted + call HasPlayerFainted
+ call nz, HasEnemyFainted + call nz, HasEnemyFainted
+ ret + ret
+ +
CheckFaint_PlayerThenEnemy: CheckFaint_PlayerThenEnemy:
+.faint_loop +.faint_loop
+ call .Function + call .Function
+ ret c + ret c
@ -154,10 +108,11 @@ CheckFaint_PlayerThenEnemy:
call HasPlayerFainted call HasPlayerFainted
jr nz, .PlayerNotFainted jr nz, .PlayerNotFainted
call HandlePlayerMonFaint call HandlePlayerMonFaint
...
``` ```
```diff ```diff
CheckFaint_EnemyThenPlayer: CheckFaint_EnemyThenPlayer:
+.faint_loop +.faint_loop
+ call .Function + call .Function
+ ret c + ret c
@ -169,6 +124,7 @@ CheckFaint_EnemyThenPlayer:
call HasEnemyFainted call HasEnemyFainted
jr nz, .EnemyNotFainted jr nz, .EnemyNotFainted
call HandleEnemyMonFaint call HandleEnemyMonFaint
...
``` ```
@ -368,6 +324,39 @@ As Pryce's dialog ("That BADGE will raise the SPECIAL stats of POKéMON.") impli
``` ```
## Berserk Gene's confusion lasts for 256 turns or the previous Pokémon's confusion count
*Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.*
([Video](https://youtube.com/watch?v=Pru3mohq20A))
**Fix:** Edit `HandleBerserkGene` in [engine/battle/core.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/core.asm):
```diff
HandleBerserkGene:
...
ld a, BATTLE_VARS_SUBSTATUS3
call GetBattleVarAddr
push af
set SUBSTATUS_CONFUSED, [hl]
+ ld a, [hBattleTurn]
+ and a
+ ld hl, wEnemyConfuseCount
+ jr z, .set_confuse_count
+ ld hl, wPlayerConfuseCount
+.set_confuse_count
+ call BattleRandom
+ and %11
+ add a, 2
+ ld [hl], a
ld a, BATTLE_VARS_MOVE_ANIM
call GetBattleVarAddr
...
```
This makes the Berserk Gene use the regular confusion duration (2-5 turns).
## Confusion damage is affected by type-boosting items and Explosion/Self-Destruct doubling ## Confusion damage is affected by type-boosting items and Explosion/Self-Destruct doubling
*Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.* *Fixing this bug will break compatibility with standard Pokémon Crystal for link battles.*
@ -376,11 +365,15 @@ As Pryce's dialog ("That BADGE will raise the SPECIAL stats of POKéMON.") impli
**Fix:** **Fix:**
First, edit [hram.asm](https://github.com/pret/pokecrystal/blob/master/hram.asm): First, edit [wram.asm](https://github.com/pret/pokecrystal/blob/master/wram.asm):
```diff ```diff
hClockResetTrigger:: db ; ffeb wTurnEnded:: db ; c6b4
+hIsConfusionDamage:: db ; ffec
- ds 1
+wIsConfusionDamage:: db ; c6b5
wPlayerStats:: ; c6b6
``` ```
Then edit four routines in [engine/battle/effect_commands.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/effect_commands.asm): Then edit four routines in [engine/battle/effect_commands.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/effect_commands.asm):
@ -393,7 +386,7 @@ Then edit four routines in [engine/battle/effect_commands.asm](https://github.co
pop af pop af
ld e, a ld e, a
+ ld a, TRUE + ld a, TRUE
+ ldh [hIsConfusionDamage], a + ld [wIsConfusionDamage], a
ret ret
``` ```
@ -403,7 +396,7 @@ Then edit four routines in [engine/battle/effect_commands.asm](https://github.co
... ...
.skip_zero_damage_check .skip_zero_damage_check
+ xor a ; Not confusion damage + xor a ; Not confusion damage
+ ldh [hIsConfusionDamage], a + ld [wIsConfusionDamage], a
+ ; fallthrough + ; fallthrough
+ +
+ConfusionDamageCalc: +ConfusionDamageCalc:
@ -419,7 +412,7 @@ Then edit four routines in [engine/battle/effect_commands.asm](https://github.co
; Item boosts ; Item boosts
+ +
+; Item boosts don't apply to confusion damage +; Item boosts don't apply to confusion damage
+ ldh a, [hIsConfusionDamage] + ld a, [wIsConfusionDamage]
+ and a + and a
+ jr nz, .DoneItem + jr nz, .DoneItem
+ +
@ -460,72 +453,77 @@ Then edit four routines in [engine/battle/effect_commands.asm](https://github.co
## Saves corrupted by mid-save shutoff are not handled ## Saves corrupted by mid-save shutoff are not handled
([Video 1](https://www.youtube.com/watch?v=ukqtK0l6bu0)) ([Video 1](https://www.youtube.com/watch?v=ukqtK0l6bu0), [Video 2](https://www.youtube.com/watch?v=c2zHd1BPtvc))
([Video 2](https://www.youtube.com/watch?v=c2zHd1BPtvc))
**Fix:** Edit `MoveMonWOMail_InsertMon_SaveGame` and `_SaveGameData` in [engine/menus/save.asm](https://github.com/pret/pokecrystal/blob/master/engine/menus/save.asm) **Fix:** Edit `MoveMonWOMail_InsertMon_SaveGame` and `_SaveGameData` in [engine/menus/save.asm](https://github.com/pret/pokecrystal/blob/master/engine/menus/save.asm):
```diff ```diff
ld a, TRUE MoveMonWOMail_InsertMon_SaveGame:
ld [wSaveFileExists], a ...
farcall StageRTCTimeForSave ld a, TRUE
farcall BackupMysteryGift ld [wSaveFileExists], a
+ call InvalidateSave farcall StageRTCTimeForSave
farcall BackupMysteryGift
- call ValidateSave - call ValidateSave
call SaveOptions + call InvalidateSave
call SavePlayerData call SaveOptions
call SavePokemonData call SavePlayerData
call SaveChecksum call SavePokemonData
call SaveChecksum
- call ValidateBackupSave
+ call ValidateSave + call ValidateSave
+ call InvalidateBackupSave + call InvalidateBackupSave
- call ValidateBackupSave call SaveBackupOptions
call SaveBackupOptions call SaveBackupPlayerData
call SaveBackupPlayerData call SaveBackupPokemonData
call SaveBackupPokemonData call SaveBackupChecksum
call SaveBackupChecksum
+ call ValidateBackupSave + call ValidateBackupSave
farcall BackupPartyMonMail farcall BackupPartyMonMail
farcall BackupMobileEventIndex farcall BackupMobileEventIndex
farcall SaveRTC farcall SaveRTC
...
``` ```
```diff ```diff
ld a, TRUE _SaveGameData:
ld [wSaveFileExists], a ...
farcall StageRTCTimeForSave ld a, TRUE
farcall BackupMysteryGift ld [wSaveFileExists], a
+ call InvalidateSave farcall StageRTCTimeForSave
farcall BackupMysteryGift
- call ValidateSave - call ValidateSave
call SaveOptions + call InvalidateSave
call SavePlayerData call SaveOptions
call SavePokemonData call SavePlayerData
call SaveBox call SavePokemonData
call SaveChecksum call SaveBox
call SaveChecksum
- call ValidateBackupSave
+ call ValidateSave + call ValidateSave
+ call InvalidateBackupSave + call InvalidateBackupSave
- call ValidateBackupSave call SaveBackupOptions
call SaveBackupOptions call SaveBackupPlayerData
call SaveBackupPlayerData call SaveBackupPokemonData
call SaveBackupPokemonData call SaveBackupChecksum
call SaveBackupChecksum
+ call ValidateBackupSave + call ValidateBackupSave
call UpdateStackTop call UpdateStackTop
farcall BackupPartyMonMail farcall BackupPartyMonMail
farcall BackupMobileEventIndex farcall BackupMobileEventIndex
farcall SaveRTC farcall SaveRTC
...
``` ```
Also create two new routines, one named `InvalidateSave` and another named `InvalidateBackupSave` in [engine/menus/save.asm](https://github.com/pret/pokecrystal/blob/master/engine/menus/save.asm): Then create two new routines, `InvalidateSave` and `InvalidateBackupSave`:
```diff ```diff
ValidateSave: ValidateSave:
ld a, BANK(sCheckValue1) ; aka BANK(sCheckValue2) ld a, BANK(sCheckValue1) ; aka BANK(sCheckValue2)
call GetSRAMBank call GetSRAMBank
ld a, SAVE_CHECK_VALUE_1 ld a, SAVE_CHECK_VALUE_1
ld [sCheckValue1], a ld [sCheckValue1], a
ld a, SAVE_CHECK_VALUE_2 ld a, SAVE_CHECK_VALUE_2
ld [sCheckValue2], a ld [sCheckValue2], a
jp CloseSRAM jp CloseSRAM
+InvalidateSave: +InvalidateSave:
+ ld a, BANK(sCheckValue1) ; aka BANK(sCheckValue2) + ld a, BANK(sCheckValue1) ; aka BANK(sCheckValue2)
@ -537,14 +535,14 @@ ValidateSave:
``` ```
```diff ```diff
ValidateBackupSave: ValidateBackupSave:
ld a, BANK(sBackupCheckValue1) ; aka BANK(sBackupCheckValue2) ld a, BANK(sBackupCheckValue1) ; aka BANK(sBackupCheckValue2)
call GetSRAMBank call GetSRAMBank
ld a, SAVE_CHECK_VALUE_1 ld a, SAVE_CHECK_VALUE_1
ld [sBackupCheckValue1], a ld [sBackupCheckValue1], a
ld a, SAVE_CHECK_VALUE_2 ld a, SAVE_CHECK_VALUE_2
ld [sBackupCheckValue2], a ld [sBackupCheckValue2], a
jp CloseSRAM jp CloseSRAM
+InvalidateBackupSave: +InvalidateBackupSave:
+ ld a, BANK(sBackupCheckValue1) ; aka BANK(sBackupCheckValue2) + ld a, BANK(sBackupCheckValue1) ; aka BANK(sBackupCheckValue2)
@ -839,6 +837,23 @@ This bug existed for all battles in Gold and Silver, and was only fixed for sing
``` ```
## A Transformed Pokémon can use Sketch and learn otherwise unobtainable moves
([Video](https://www.youtube.com/watch?v=AFiBxAOkCGI))
**Fix:** Edit `BattleCommand_Sketch` in [engine/battle/move_effects/sketch.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/move_effects/sketch.asm):
```diff
-; If the opponent is transformed, fail.
+; If the user is transformed, fail.
- ld a, BATTLE_VARS_SUBSTATUS5_OPP
+ ld a, BATTLE_VARS_SUBSTATUS5
call GetBattleVarAddr
bit SUBSTATUS_TRANSFORMED, [hl]
jp nz, .fail
```
## "Smart" AI encourages Mean Look if its own Pokémon is badly poisoned ## "Smart" AI encourages Mean Look if its own Pokémon is badly poisoned
([Video](https://www.youtube.com/watch?v=cygMO-zHTls)) ([Video](https://www.youtube.com/watch?v=cygMO-zHTls))
@ -919,30 +934,28 @@ This bug existed for all battles in Gold and Silver, and was only fixed for sing
## NPC use of Full Heal does not cure confusion status ## NPC use of Full Heal does not cure confusion status
([Video](TBA))
**Fix:** Edit `EnemyUsedFullRestore`, `EnemyUsedFullHeal`, and `AI_HealStatus` in [engine/battle/ai/items.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/ai/items.asm): **Fix:** Edit `EnemyUsedFullRestore`, `EnemyUsedFullHeal`, and `AI_HealStatus` in [engine/battle/ai/items.asm](https://github.com/pret/pokecrystal/blob/master/engine/battle/ai/items.asm):
```diff ```diff
EnemyUsedFullRestore: EnemyUsedFullRestore:
call AI_HealStatus call AI_HealStatus
ld a, FULL_RESTORE ld a, FULL_RESTORE
ld [wCurEnemyItem], a ld [wCurEnemyItem], a
- ld hl, wEnemySubStatus3 - ld hl, wEnemySubStatus3
- res SUBSTATUS_CONFUSED, [hl] - res SUBSTATUS_CONFUSED, [hl]
xor a xor a
ld [wEnemyConfuseCount], a ld [wEnemyConfuseCount], a
``` ```
```diff ```diff
EnemyUsedFullHeal: EnemyUsedFullHeal:
call AIUsedItemSound call AIUsedItemSound
call AI_HealStatus call AI_HealStatus
ld a, FULL_HEAL ld a, FULL_HEAL
+ ld [wCurEnemyItem], a + ld [wCurEnemyItem], a
+ xor a + xor a
+ ld [wEnemyConfuseCount], a + ld [wEnemyConfuseCount], a
jp PrintText_UsedItemOn_AND_AIUpdateHUD jp PrintText_UsedItemOn_AND_AIUpdateHUD
``` ```
```diff ```diff
@ -1317,7 +1330,7 @@ CopyPokemonName_Buffer1_Buffer3:
jr nc, .GenerateDVs jr nc, .GenerateDVs
``` ```
**Better fix:** Rewrite the whole system to use millimeters instead of feet and inches, since they have better precision (1 in = 25.4 mm); and only convert from metric to imperial units for display purposes (or don't, of course). **Better fix:** Rewrite the whole system to use millimeters instead of feet and inches, since they have better precision (1 in = 25.4 mm); and only convert from metric to imperial units for display purposes (or don't, of course).
## Magikarp lengths can be miscalculated ## Magikarp lengths can be miscalculated
@ -1664,7 +1677,7 @@ If you want to make sure `hInMenu` always has a defined value in the move select
... ...
jp .loop jp .loop
.quit .quit
+ pop af + pop af
+ ldh [hInMenu], a + ldh [hInMenu], a
@ -1723,12 +1736,12 @@ First, edit `UsedSurfScript` in [engine/events/overworld.asm](https://github.com
writetext UsedSurfText ; "used SURF!" writetext UsedSurfText ; "used SURF!"
waitbutton waitbutton
closetext closetext
callasm .empty_fn ; empty function callasm .empty_fn ; empty function
readmem wBuffer2 readmem wBuffer2
writevar VAR_MOVEMENT writevar VAR_MOVEMENT
special ReplaceKrisSprite special ReplaceKrisSprite
special PlayMapMusic special PlayMapMusic
-; step into the water (slow_step DIR, step_end) -; step into the water (slow_step DIR, step_end)