Skip to content

Attack after waking up from sleep

Xillicis edited this page Jan 8, 2023 · 3 revisions

Attack after waking up from sleep

This tutorial is for implementing the ability to attack immediately after waking up from sleep for both you and your enemy. I adapted the code modifications from Jojobear13's fork of pokered: shinpokered.

Access the menu while still asleep

In Pokemon Red/Blue, when attempting to FIGHT while asleep, the move list is immediately skipped and the check for waking up begins. The first change is to allow us to pick a move while still asleep.

Open the file engine/battle/core.asm and make the following modification.

...
        ret nz ; return if pokedoll was used to escape from battle
        ld a, [wBattleMonStatus]
-       and (1 << FRZ) | SLP_MASK
+       and (1 << FRZ)
        jr nz, .selectEnemyMove ; if so, jump
        ld a, [wPlayerBattleStatus1]
        and (1 << STORING_ENERGY) | (1 << USING_TRAPPING_MOVE) ; check player is using Bide or using a multi-turn attack like wrap
...

In order for the move to actually be exectued, we will simply skip over the .sleepDone call when we wake up. Head down to line 3337 and make the following change,

...
.WakeUp
        ld hl, WokeUpText
        call PrintText
+       jr z, .FrozenCheck
.sleepDone
        xor a
...

This should also be true for your opponent, so head to line 5815 and make the change

...
.wokeUp
        ld hl, WokeUpText
        call PrintText
+       jr z, .checkIfFrozen
.sleepDone
        xor a
...

That's it. This is a good fix for how overpowered the sleep mechanic is in generation I.

(Bonus) Change the number of turns asleep

In Generation II, sleep lasts at most 6 turns. So if you'd like to change the number of turns asleep, head over to engine/battle/effects.asm and make the following change.

...
.setSleepCounter
; set target's sleep counter to a random number between 1 and 7
        call BattleRandom
        and $7
+       cp $7
        jr z, .setSleepCounter
        ld [de], a
        call PlayCurrentMoveAnimation2
        ld hl, FellAsleepText
        jp PrintText
...

Its a little tricky to modify the number of turns since we are working with the bits. Register a contains the number of turns between 0 and 7 after and $7 has been called. The cp $7 call sets the z flag to zero if register a contains 7, hence we jump back to .setSleepCounter to generate a new random number if a is either 0 or 7.

Clone this wiki locally