-
Notifications
You must be signed in to change notification settings - Fork 1k
Poison, burn and leech seed do an 8th of max HP
In generation 1, poison, burn and leech seed deals 1/16th of the users
max hp. This was changed in later generations to be 1/8th of the users
max hp. Changing this is simple, head to
engine/battle/core.asm
and make the following change to the subroutine HandlePoisonBurnLeechSeed_DecreaseOwnHP:
HandlePoisonBurnLeechSeed_DecreaseOwnHP:
push hl
push hl
ld bc, $e ; skip to max HP
add hl, bc
ld a, [hli] ; load max HP
ld [wHPBarMaxHP+1], a
ld b, a
ld a, [hl]
ld [wHPBarMaxHP], a
ld c, a
srl b
rr c
srl b
rr c
- srl c
- srl c ; c = max HP/16 (assumption: HP < 1024)
+ srl c ; c = max HP/8 (assumption: HP < 1024)
ld a, c
and a
jr nz, .nonZeroDamage
...
That's it, srl c
shifts all bits in register c
to the right. This binary operation is equivalent to dividing by 2. So by commenting it
out, the value of c
stays at (max HP)/8.
More Detailed Remarks: Remember that Max HP is is stored across two bytes of data and is done in a "big endian" format. This subroutine loads the max HP into registers b
and c
. Then the bit shifting and rotating operations are performed on b
and c
. These are the srl
and rr
instructions, respectively. Notice the assumption in the comment that the HP < 1024. Without going into too many details on assembly, notice there are only two bit shifts performed on register b
and four rotates/shifts on register c
, in the original code. If HP < 1024, then two bit shifts (to the right) will zero out register b
, hence no more bit shifts are necessary.
Make sure to check out the CPU opcode page to see exactly how these assembly instructions work.
However, this change currently also affects toxic damage. Toxic damage is supposed to be dealt in increasing increments of 1/16th of the pokemon's max hp, so we will need to make another charge for it to still function as intended. A little further down in HandlePoisonBurnLeechSeed_DecreaseOwnHP:
, make the following change:
...
.playersTurn
bit BADLY_POISONED, [hl]
jr z, .noToxic
+ srl c ; c = max HP/16 (assumption: HP < 1024)
+ ld a, c
+ and a
+ jr nz, .nonZeroDamageAgain
+ inc c
+.nonZeroDamageAgain
ld a, [de] ; increment toxic counter
inc a
ld [de], a
ld hl, 0
...
This change adds an additional division by 2 on register c
when calculating toxic damage. It also adds a check to make sure this division didn't cause the value in c
to round down to 0, and sets it to 1 if it did.