summaryrefslogtreecommitdiff
path: root/engine/overworld/movement.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/overworld/movement.asm')
-rw-r--r--engine/overworld/movement.asm385
1 files changed, 285 insertions, 100 deletions
diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm
index 2fb8c384..dadf2194 100644
--- a/engine/overworld/movement.asm
+++ b/engine/overworld/movement.asm
@@ -22,7 +22,13 @@ UpdatePlayerSprite:
ld [wSpritePlayerStateData1ImageIndex], a
ret
.lowerLeftTileIsMapTile
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
call DetectCollisionBetweenSprites
+ pop af
+ ld [wUpdateSpritesEnabled], a
ld h, HIGH(wSpriteStateData1)
ld a, [wWalkCounter]
and a
@@ -48,42 +54,24 @@ UpdatePlayerSprite:
jr z, .notMoving
ld a, SPRITE_FACING_RIGHT
jr .next
+.next
+ ld [wSpritePlayerStateData1FacingDirection], a ; facing direction
+ ld a, [wFontLoaded]
+ bit 0, a
+ jr z, .moving
.notMoving
; zero the animation counters
xor a
ld [wSpritePlayerStateData1IntraAnimFrameCounter], a
ld [wSpritePlayerStateData1AnimFrameCounter], a
- jr .calcImageIndex
-.next
- ld [wSpritePlayerStateData1FacingDirection], a
- ld a, [wFontLoaded]
- bit 0, a
- jr nz, .notMoving
+ call Func_4e32
+ jr .skipSpriteAnim
.moving
ld a, [wd736]
bit 7, a ; is the player sprite spinning due to a spin tile?
jr nz, .skipSpriteAnim
- ldh a, [hCurrentSpriteOffset]
- add $7
- ld l, a
- ld a, [hl]
- inc a
- ld [hl], a
- cp 4
- jr nz, .calcImageIndex
- xor a
- ld [hl], a
- inc hl
- ld a, [hl]
- inc a
- and $3
- ld [hl], a
-.calcImageIndex
- ld a, [wSpritePlayerStateData1AnimFrameCounter]
- ld b, a
- ld a, [wSpritePlayerStateData1FacingDirection]
- add b
- ld [wSpritePlayerStateData1ImageIndex], a
+ call Func_5274
+ call Func_4e32
.skipSpriteAnim
; If the player is standing on a grass tile, make the player's sprite have
; lower priority than the background so that it's partially obscured by the
@@ -100,15 +88,12 @@ UpdatePlayerSprite:
ld [wSpritePlayerStateData2GrassPriority], a
ret
-UnusedReadSpriteDataFunction:
- push bc
- push af
- ldh a, [hCurrentSpriteOffset]
- ld c, a
- pop af
- add c
- ld l, a
- pop bc
+Func_4e32:
+ ld a, [wSpritePlayerStateData1AnimFrameCounter]
+ ld b, a
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ add b
+ ld [wSpritePlayerStateData1ImageIndex], a
ret
UpdateNPCSprite:
@@ -146,6 +131,8 @@ UpdateNPCSprite:
jp z, UpdateSpriteMovementDelay ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] == 2
cp $3
jp z, UpdateSpriteInWalkingAnimation ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] == 3
+ cp $4
+ jp z, Func_5357
ld a, [wWalkCounter]
and a
ret nz ; don't do anything yet if player is currently moving (redundant, already tested in CheckSpriteAvailability)
@@ -156,9 +143,9 @@ UpdateNPCSprite:
ld l, a
ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
inc a
- jr z, .randomMovement ; value STAY
+ jp z, .randomMovement ; value STAY
inc a
- jr z, .randomMovement ; value WALK
+ jp z, .randomMovement ; value WALK
; scripted movement
dec a
ld [hl], a ; increment movement byte 1 (movement data index)
@@ -183,12 +170,18 @@ UpdateNPCSprite:
ret
.next
cp WALK
- jr nz, .determineDirection
+ jr nz, .asm_4ecb
; current NPC movement data is WALK ($fe). this seems buggy
ld [hl], $1 ; set movement byte 1 to $1
ld de, wNPCMovementDirections
call LoadDEPlusA ; a = [wNPCMovementDirections + $fe] (?)
- jr .determineDirection
+.asm_4ecb
+ push af
+ call Func_5288
+ pop bc
+ ld a, b
+ jr nc, .determineDirection
+ ret
.randomMovement
call GetTileSpriteStandsOn
call Random
@@ -263,34 +256,14 @@ ChangeFacingDirection:
; set carry on failure, clears carry on success
TryWalking:
push hl
- ld h, HIGH(wSpriteStateData1)
- ldh a, [hCurrentSpriteOffset]
- add $9
- ld l, a
- ld [hl], c ; x#SPRITESTATEDATA1_FACINGDIRECTION
- ldh a, [hCurrentSpriteOffset]
- add $3
- ld l, a
- ld [hl], d ; x#SPRITESTATEDATA1_YSTEPVECTOR
- inc l
- inc l
- ld [hl], e ; x#SPRITESTATEDATA1_XSTEPVECTOR
+ call Func_5337
pop hl
push de
- ld c, [hl] ; read tile to walk onto
+ ld c, [hl]
call CanWalkOntoTile
pop de
ret c ; cannot walk there (reinitialization of delay values already done)
- ld h, HIGH(wSpriteStateData2)
- ldh a, [hCurrentSpriteOffset]
- add $4
- ld l, a
- ld a, [hl] ; x#SPRITESTATEDATA2_MAPY
- add d
- ld [hli], a ; update Y position
- ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
- add e
- ld [hl], a ; update X position
+ call Func_5349
ldh a, [hCurrentSpriteOffset]
ld l, a
ld [hl], $10 ; [x#SPRITESTATEDATA2_WALKANIMATIONCOUNTER] = 16
@@ -301,22 +274,7 @@ TryWalking:
; update the walking animation parameters for a sprite that is currently walking
UpdateSpriteInWalkingAnimation:
- ldh a, [hCurrentSpriteOffset]
- add $7
- ld l, a
- ld a, [hl] ; x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER
- inc a
- ld [hl], a ; [x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER]++
- cp $4
- jr nz, .noNextAnimationFrame
- xor a
- ld [hl], a ; [x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER] = 0
- inc l
- ld a, [hl] ; x#SPRITESTATEDATA1_ANIMFRAMECOUNTER
- inc a
- and $3
- ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
-.noNextAnimationFrame
+ call Func_5274
ldh a, [hCurrentSpriteOffset]
add $3
ld l, a
@@ -448,6 +406,7 @@ InitializeSpriteStatus:
ld a, $8
ld [hli], a ; [x#SPRITESTATEDATA2_YDISPLACEMENT] = 8
ld [hl], a ; [x#SPRITESTATEDATA2_XDISPLACEMENT] = 8
+ call InitializeSpriteScreenPosition ; could have done fallthrough here
ret
; calculates the sprite's screen position from its map position and the player position
@@ -460,7 +419,7 @@ InitializeSpriteScreenPosition:
ld b, a
ld a, [hl] ; x#SPRITESTATEDATA2_MAPY
sub b ; relative to player position
- swap a ; * 16
+ call Func_5033
sub $4 ; - 4
dec h
ld [hli], a ; [x#SPRITESTATEDATA1_YPIXELS]
@@ -469,11 +428,23 @@ InitializeSpriteScreenPosition:
ld b, a
ld a, [hli] ; x#SPRITESTATEDATA2_MAPX
sub b ; relative to player position
- swap a ; * 16
+ call Func_5033
dec h
ld [hl], a ; [x#SPRITESTATEDATA1_XPIXELS]
ret
+Func_5033:
+ jr nc, .asm_503c
+ cpl
+ inc a
+ swap a
+ cpl
+ inc a
+ ret
+.asm_503c
+ swap a
+ ret
+
; tests if sprite is off screen or otherwise unable to do anything
CheckSpriteAvailability:
predef IsObjectHidden
@@ -593,16 +564,8 @@ CanWalkOntoTile:
and a
ret
.notScripted
- ld a, [wTilesetCollisionPtr]
- ld l, a
- ld a, [wTilesetCollisionPtr+1]
- ld h, a
-.tilePassableLoop
- ld a, [hli]
- cp $ff
- jr z, .impassable
- cp c
- jr nz, .tilePassableLoop
+ call _IsTilePassable
+ jr c, .impassable
ld h, HIGH(wSpriteStateData2)
ldh a, [hCurrentSpriteOffset]
add $6
@@ -626,7 +589,13 @@ CanWalkOntoTile:
jr nc, .impassable ; don't walk off screen
push de
push bc
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
call DetectCollisionBetweenSprites
+ pop af
+ ld [wUpdateSpritesEnabled], a
pop bc
pop de
ld h, HIGH(wSpriteStateData1)
@@ -649,8 +618,9 @@ CanWalkOntoTile:
; stuck whenever they walked upwards 5 steps
; on the other hand, the amount a sprite can walk out to the
; right of bottom is not limited (until the counter overflows)
+ ; this was fixed in Yellow
cp $5
- jr c, .impassable ; if [x#SPRITESTATEDATA2_YDISPLACEMENT]+d < 5, don't go
+ ;jr c, .impassable ; if [x#SPRITESTATEDATA2_YDISPLACEMENT]+d < 5, don't go
jr .checkHorizontal
.upwards
sub $1
@@ -704,7 +674,7 @@ GetTileSpriteStandsOn:
ld l, a
ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
add $4 ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
- and $f0 ; in case object is currently moving
+ and $f8 ; in case object is currently moving (XXX why changed to $f8?)
srl a ; screen Y tile * 4
ld c, a
ld b, $0
@@ -870,20 +840,235 @@ AnimScriptedNPCMovement:
ret
AdvanceScriptedNPCAnimFrameCounter:
+ call Func_5274
+ ld h, HIGH(wSpriteStateData1)
ldh a, [hCurrentSpriteOffset]
- add $7
+ add $8
ld l, a
ld a, [hl] ; intra-animation frame counter
+ and $3
+ ldh [hSpriteAnimFrameCounter], a
+ ret
+
+Func_5274:
+ ldh a, [hCurrentSpriteOffset]
+ add $7
+ ld l, a
+ ld h, HIGH(wSpriteStateData1)
+ ld a, [hl] ; x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER
inc a
- ld [hl], a
- cp 4
+ and $3
+ ld [hl], a ; [x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER]++
ret nz
- xor a
- ld [hl], a ; reset intra-animation frame counter
inc l
- ld a, [hl] ; animation frame counter
+ ld a, [hl] ; x#SPRITESTATEDATA1_ANIMFRAMECOUNTER
inc a
and $3
+ ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
+ ret
+
+Func_5288:
+; nice lookup table
+; a is supposedly [wNPCMovementDirections + $fe]
+ cp $5
+ jr z, .asm_52af
+ cp $4
+ jr z, .asm_52aa
+ cp $6
+ jr z, .asm_52b4
+ cp $7
+ jr z, .asm_52b9
+ cp $11
+ jr z, .asm_52c3
+ cp $12
+ jr z, .asm_52be
+ cp $13
+ jr z, .asm_52c8
+ cp $14
+ jr z, .asm_52cd
+ xor a
+ ret
+; set 1?
+.asm_52aa
+ call Func_531f
+ jr .asm_52e6
+.asm_52af
+ call Func_5325
+ jr .asm_52e6
+.asm_52b4
+ call Func_5331
+ jr .asm_52e6
+.asm_52b9
+ call Func_532b
+ jr .asm_52e6
+; set 2?
+.asm_52be
+ call Func_531f
+ jr .asm_52fa
+.asm_52c3
+ call Func_5325
+ jr .asm_52fa
+.asm_52c8
+ call Func_5331
+ jr .asm_52fa
+.asm_52cd
+ call Func_532b
+ jr .asm_52fa
+; set 3? (unused)
+.asm_52d2
+ call Func_531f
+ jr .asm_530b
+.asm_52d7
+ call Func_5325
+ jr .asm_530b
+.asm_52dc
+ call Func_5331
+ jr .asm_530b
+.asm_52e1
+ call Func_532b
+ jr .asm_530b
+
+.asm_52e6
+ call Func_5337
+ call Func_5349
+ ldh a, [hCurrentSpriteOffset]
+ ld l, a
+ ld [hl], $8
+ dec h
+ inc l
+ ld [hl], $4
+ call UpdateSpriteImage
+ scf
+ ret
+
+.asm_52fa
+ call Func_5337
+ ldh a, [hCurrentSpriteOffset]
+ ld l, a
+ ld [hl], $8
+ dec h
+ inc l
+ ld [hl], $3
+ call UpdateSpriteImage
+ scf
+ ret
+
+.asm_530b
+ call Func_5337
+ call Func_5349
+ ldh a, [hCurrentSpriteOffset]
+ ld l, a
+ ld [hl], $8
+ dec h
+ inc l
+ ld [hl], $3
+ call UpdateSpriteImage
+ scf
+ ret
+
+Func_531f:
+ lb de, 1, 0
+ ld c, SPRITE_FACING_DOWN
+ ret
+
+Func_5325:
+ lb de, -1, 0
+ ld c, SPRITE_FACING_UP
+ ret
+
+Func_532b:
+ lb de, 0, 1
+ ld c, SPRITE_FACING_RIGHT
+ ret
+
+Func_5331:
+ lb de, 0, -1
+ ld c, SPRITE_FACING_LEFT
+ ret
+
+Func_5337:
+ ldh a, [hCurrentSpriteOffset]
+ add $9
+ ld l, a
+ ld h, HIGH(wSpriteStateData1)
+ ld [hl], c ; x#SPRITESTATEDATA1_FACINGDIRECTION
+ ldh a, [hCurrentSpriteOffset]
+ add $3
+ ld l, a
+ ld [hl], d ; x#SPRITESTATEDATA1_YSTEPVECTOR
+ inc l
+ inc l
+ ld [hl], e ; x#SPRITESTATEDATA1_XSTEPVECTOR
+ ret
+
+Func_5349:
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
+ add $4
+ ld l, a
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPY
+ add d
+ ld [hli], a ; update Y position
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
+ add e
+ ld [hl], a ; update X position
+ ret
+
+Func_5357:
+ call Func_5274
+ ldh a, [hCurrentSpriteOffset]
+ add $3
+ ld l, a
+ ld h, HIGH(wSpriteStateData1)
+ ld a, [hli]
+ add a
+ ld b, a
+ ld a, [hl]
+ add b
+ ld [hli], a
+ ld a, [hli]
+ add a
+ ld b, a
+ ld a, [hl]
+ add b
+ ld [hl], a
+ ldh a, [hCurrentSpriteOffset]
+ ld l, a
+ ld h, HIGH(wSpriteStateData2)
+ dec [hl]
+ ret nz
+ ld a, $6
+ add l
+ ld l, a
+ ld a, [hl]
+ cp $fe
+ jr nc, .asm_5386
+ ldh a, [hCurrentSpriteOffset]
+ inc a
+ ld l, a
+ ld h, HIGH(wSpriteStateData1)
+ ld [hl], $1
+ ret
+.asm_5386
+ call Random
+ ldh a, [hCurrentSpriteOffset]
+ add $8
+ ld l, a
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hRandomAdd]
+ and $7f
+ ld [hl], a
+ dec h
+ ldh a, [hCurrentSpriteOffset]
+ inc a
+ ld l, a
+ ld [hl], $2
+ inc l
+ inc l
+ xor a
+ ld b, [hl]
+ ld [hli], a
+ inc l
+ ld c, [hl]
ld [hl], a
- ldh [hSpriteAnimFrameCounter], a
ret