Running Shoes - pret/pokered GitHub Wiki

Hi guys! This code was provided to me by Luna so credit to that person!

Anyway, what this code does is it makes the player run at double walking speed when holding B, 4x walking speed while holding B on bike, and the surfing speed is also double running speed.

You should also note that your current save file may not be compatible with these changes, as you might be unable to move when you load the game. Restarting your progress will solve this issue, but if there is no problem, then no need to restart.

Here are the lines you gotta add in home/overworld.asm starting at about line 284:

...

	ld a, [wd736]
	bit 6, a ; jumping a ledge?
	jr nz, .normalPlayerSpriteAdvancement
	call DoBikeSpeedup
+	call DoBikeSpeedup
+	call DoBikeSpeedup
+	jr .notRunning
 .normalPlayerSpriteAdvancement
+	; surf at 2x walking speed
+	ld a, [wWalkBikeSurfState]
+	cp $02
+	jr z, .surfFaster
+	; Holding B makes you run at 2x walking speed
+	ld a, [hJoyHeld]
+	and PAD_B
+	jr z, .notRunning
+.surfFaster
+	call DoBikeSpeedup
+.notRunning
+	;original .normalPlayerSpriteAdvancement continues here
	call AdvancePlayerSprite
	ld a, [wWalkCounter]
	and a
...

Done! Not too bad, eh?

Bonus: Running Animation

Ever felt like running needed a little more Shazzaah? Well now you can!

First you will need to decalre your trigger within your ram\wram.asm.
Not sure if locations or w/e matters.

...
+wPlayerIsRunning:: db ; 0 = not running, 1 = running
...

Then you will need to add your running sprite to to your gfx/sprites/red_run.png
And don't forget to declare it as well within the gfx\sprites.asm
You might need to move a sprite to another bank

...
RedSprite::              INCBIN "gfx/sprites/red.2bpp"
+RedRunningSprite::       INCBIN "gfx/sprites/red_run.2bpp"
...

Red Running Sprite

The original code was modified, since it did check B for speed up on surf or biking.
Head over to the home/overworld.asm and find .moveAhead2

...
.moveAhead2
	ld hl, wFlags_0xcd60
	res 2, [hl]

+        ; Check if we're in walking state
+	ld a, [wWalkBikeSurfState]
+	cp $00
+	jr nz, .skipSprite
	
+	; Update running flag from B button
+	ld a, [hJoyHeld]
+	and PAD_B
+	ld b, a
+	ld a, [wPlayerIsRunning]
+	cp b
+	jr z, .skipSprite
	
+	; State changed - update flag and reload
+	ld a, b
+	ld [wPlayerIsRunning], a
+	call LoadWalkingPlayerSpriteGraphics

+.skipSprite
	
	ld a, [wWalkBikeSurfState]
	dec a ; riding a bike?
	jr nz, .normalPlayerSpriteAdvancement
	ld a, [wd736]
	bit 6, a ; jumping a ledge?
	jr nz, .normalPlayerSpriteAdvancement
	call DoBikeSpeedup

+       ; Check B for bike boost
+	ld a, [hJoyHeld]
+	and PAD_B
+	jr z, .notRunning
+	call DoBikeSpeedup
+	call DoBikeSpeedup
+	jr .notRunning
	
.normalPlayerSpriteAdvancement

+	; surf at 2x walking speed
+	ld a, [hJoyHeld]
+	and PAD_B
+	jr z, .notRunning
+	ld a, [wWalkBikeSurfState]
+	cp $02
+	jr z, .surfFaster
+	; Holding B makes you run at 2x walking speed
+	ld a, [hJoyHeld]
+	and PAD_B
+	jr z, .notRunning
+.surfFaster
+	call DoBikeSpeedup
+.notRunning

;Original code continues here
	call AdvancePlayerSprite
	ld a, [wWalkCounter]
...

This allows the sprite to load depending on the trigger status of [wPlayerIsRunning] in the LoadWalkingPlayerSpriteGraphics

...
LoadWalkingPlayerSpriteGraphics::
+    ld a, [wPlayerIsRunning]
+    and a
+    jr z, .loadNormal
+    ld de, RedRunningSprite
+    jr .loadGraphics
+.loadNormal
	ld de, RedSprite
+.loadGraphics
	ld hl, vNPCSprites
	jr LoadPlayerSpriteGraphicsCommon
...

The sprite will change when holding B and moving, but the animation will stay even if you release B until you move.
This is because .aheadmove2 only checks when you are moving and not standing still or releasing the button.

Add this code to the bottom of the page

...
+HandleRunningState::
+    ; Check if we're in a valid state for running
+    ld a, [wWalkBikeSurfState]
+    cp $00           ; Only walking state (0)
+    ret nz
    
+    ; Update running flag from B button
+    ld a, [hJoyHeld]
+    and PAD_B
+    ld b, a
+    ld a, [wPlayerIsRunning]
+    cp b
+    ret z
    
+    ; State changed - update flag and reload
+    ld a, b
+    ld [wPlayerIsRunning], a
+    jp LoadWalkingPlayerSpriteGraphics
...

And finally add this to call the code above at OverworldLoop, so that it will detect it.

...
OverworldLoop::
    call DelayFrame
+   call HandleRunningState ; add this to call the new code
...

Hopefully i didn't miss anything, enjoy.