Attack after waking up from sleep - pret/pokered GitHub Wiki

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
        jr z, .setSleepCounter
+       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. call BattleRandom generates a random number between 0 and 255 in register a. The instruction and $7 forces the value stored in a to be between 0 and 7. If a contains 0, then we jump back and generate a new random number. The cp $7 call sets the z flag if register a contains 7, hence we jump back to .setSleepCounter to generate a new random number.