Skip to content

Poison, burn and leech seed do an 8th of max HP

Chatot4444 edited this page Aug 5, 2024 · 4 revisions

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.

Clone this wiki locally