You are not logged in.
Pages: 1
There are four minor bugs related to the catch rate of certain types of pokeballs in pokemon gold/silver/crystal. The fourth is not stricly a bug but does feel quite odd.
The first one is that paralysis, burn and posion were intended to increase the catch rate by 5, but instead have no effect. I could explain it myself but I don't think I would explain it better than this, so I'll just leave the link here...
The second one is that love ball increases the catch rate against pokemon of the same gender instead of different gender. Here is the code:
Function_0xed12: ; ed12
ld a, [TempEnemyMonSpecies]
ld c, a
ld a, [TempBattleMonSpecies]
cp c
ret nz
push bc
ld a, [TempBattleMonSpecies]
ld [CurPartySpecies], a
xor a
ld [MonType], a
ld a, [CurBattleMon]
ld [CurPartyMon], a
callba GetGender
jr c, .asm_ed66
ld d, 0
jr nz, .asm_ed39
inc d
.asm_ed39
push de ; female: d=1 ; male d=0
ld a, [TempEnemyMonSpecies]
ld [CurPartySpecies], a
ld a, WILDMON
ld [MonType], a
callba GetGender
jr c, .asm_ed65
ld d, 0
jr nz, .asm_ed52
inc d
.asm_ed52
ld a, d ; female a=1 ; male a=0
pop de
cp d
pop bc
ret nz ; return if different genders
sla b
jr c, .asm_ed62
sla b
jr c, .asm_ed62
sla b
ret nc
.asm_ed62
ld b, $ff
ret
So basically we first compare the species and then the gender of both pokemon in battle, and if both match, the catch rate is multiplied by 8 (three left shifts). If the species match we then save our pokemon's gender into d, load into a the enemy's gender, and finally compare both. But we want to return only if the genders match, instead of if they differ, so that we increase the catch rate in the second case. The fix to this bug is simple, we just have to change the ret nz instruction before the three sla b to a ret z instruction that does exactly the opposite.
The third bug is straightforward. We want moon ball to increase the catch rate (x4) against pokemon that evolve with moon stone and not against pokemon that evolve with... burn heal!
Function_0xecdd: ; ecdd
GLOBAL EvosAttacks
GLOBAL EvosAttacksPointers
push bc
ld a, [TempEnemyMonSpecies]
dec a
ld c, a
ld b, 0
ld hl, EvosAttacksPointers
add hl, bc
add hl, bc
ld a, BANK(EvosAttacksPointers)
call GetFarHalfword
pop bc
push bc
ld a, BANK(EvosAttacks)
call GetFarByte
cp EVOLVE_ITEM
pop bc
ret nz
inc hl
inc hl
inc hl
; It appears that Moon Stone's constant from Pokémon Red is used.
; No Pokémon evolve with Burn Heal, so
; Moon Balls always have a catch rate of 1x.
push bc
ld a, BANK(EvosAttacks)
call GetFarByte
cp BURN_HEAL
pop bc
ret nz
sla b
jr c, .max
sla b
jr nc, .done
.max
ld b, $ff
.done
ret
; ed12
So we'd just change the cp BURN HEAL to cp MOON STONE, whose constant is 08 (Burn heal's constant is 0A).
And finally the last one is mostly something that doesn't feel too right (at least to me). Fast ball is supposed to increase catch rate against pokemon that may flee, but it only works against the first three pokemon in the fleeing pokemon table, which are magnemite, grimer and tangela. Ironically, these are some of the slowest pokemon!
Function_0xed68: ; ed68
ld a, [TempEnemyMonSpecies]
ld c, a
ld hl, FleeMons
ld d, 3
.loop
ld a, BANK(FleeMons)
call GetFarByte
inc hl
cp -1
jr z, .next
cp c
jr nz, .next
sla b
jr c, .max
sla b
ret nc
.max
ld b, $ff
ret
.next
dec d
jr nz, .loop
ret
; ed8c
So what does this do? We take the first entry from the fleeing pokemons and see if the pokemon there matches with the species of the wild pokemon. If it doesn't check the next entry and so on until register d reaches 0. Since d is initially 3 only three entries are checked. But there are a total of 23 (24 in g/s) fleeing Pokemon separated in three tables!
SometimesFleeMons: ; 3c59a ; 10%
db MAGNEMITE
db GRIMER
db TANGELA
db MR__MIME
db EEVEE
db PORYGON
db DRATINI
db DRAGONAIR
db TOGETIC
db UMBREON
db UNOWN
db SNUBBULL
db HERACROSS
db -1
OftenFleeMons: ; 3c5a8 ; 50%
db CUBONE
db ARTICUNO
db ZAPDOS
db MOLTRES
db QUAGSIRE
db DELIBIRD
db PHANPY
db TEDDIURSA
db -1
AlwaysFleeMons: ; 3c5b1 ; %100
db RAIKOU
db ENTEI
; db SUICUNE
db -1
; 3c5b4
The tables are separated by 0xFF and d is decremented with FF too, so to cover all fleeing pokemon we need to check a total of 25 or 0x19 (26 or 0x1A in g/s) entries. So the solution is simple; we just have to change the ld d, 3 instruction to ld d,19 (ld d,1A in g/s).
Last edited by Crystal_ (2014-09-10 14:49:15)
Offline
That's interesting !
@Crystal_ i think you made a little mistake.
There's no Pokémon that evolves with Burn Heal,but with a Fire Stone.
Offline
There's no Pokémon that evolves with Burn Heal,but with a Fire Stone.
That's what the bug is about. Moon Ball was accidentally made to increase catch rate against pokemon that evolve with burn heal, but as you said no pokemon evolves with burn heal.
Offline
This is a really nice find, thanks for pointing this out and clarifying it for people. I'll be applying these fixes to Pokémon Christmas as well.
I am not very active on this forum. I only pop in from time to time.
Offline
The tables are separated by 0xFF and d is decremented with FF too, so to cover all fleeing pokemon we need to check a total of 25 or 0x19 (26 or 0x1A in g/s) entries. So the solution is simple; we just have to change the ld d, 3 instruction to ld d,19 (ld d,1A in g/s).
That would work, but the bug was just a typo.
.loop
ld a, BANK(FleeMons)
call GetFarByte
inc hl
cp -1
jr z, .next
cp c
jr nz, .next
sla b
...
should actually be
.loop
ld a, BANK(FleeMons)
call GetFarByte
inc hl
cp -1
jr z, .next
cp c
jr nz, .loop
sla b
...
Then you wouldn't need to fix the length each time you changed the FleeMons tables.
Offline
Basic Question:
In the link you provided it says
ld b, a
ld a, [WildPokemonStatus]
and SLP|FRZ
ld c, 10
jr nz, .done
and a
ld c, 5
jr nz, .done
ld c, 0
.done
But the pokecrystal disassembly says...
ld b, a
ld a, [EnemyMonStatus]
and 1 << FRZ | SLP
ld c, 10
jr nz, .addstatus
and a
ld c, 5
jr nz, .addstatus
ld c, 0
As you can see they are slightly different.
If I just replace it with what the link suggests to replace it with will it still work?
Last edited by Urnighter (2015-03-07 22:18:08)
Offline
Use 1 << FRZ.
FRZ describes which bit from 0-7 it is. Example: "bit FRZ, a".
When using instructions that operate on a byte, like "and", you can shift a 1 into the right place to make a mask (1 << FRZ).
The exception is SLP, which is already a mask (it's the number of turns until you wake up).
Last edited by comet (2015-03-08 00:33:16)
Offline
The link suggests to replace it with
ld b, a
ld a, [WildPokemonStatus]
and a
ld c, 0
jr z, .done
and SLP|FRZ
ld c, 10
jr nz, .done
ld c, 5
And you're saying I should replace it with
ld b, a
ld a, [WildPokemonStatus]
and a
ld c, 0
jr z, .done
and 1 << FRZ | SLP
ld c, 10
jr nz, .done
ld c, 5
Correct? What should I do about [EnemyMonStatus] vs. [WildPokemonStatus]
Offline
Keep the dissasembly's label. When iimarckus made that post that ram address probably wasn't labeled in the dissasembly yet so he used his own name for it. EnemyMon extends to both wild and (the current) trainer pokemon. WildPokemonStatus doesn't exist, so if you use it you will get an error when trying to build pokecrystal.
Last edited by Crystal_ (2015-03-08 10:10:53)
Offline
Pages: 1