pokecrystal-board/engine/player_movement.asm
pfero 7c9a156133 Fix WATERTILE/WALLTILE constants
WATRTILE was wrongly defined as 15, and WALLTILE as 1. Those had to be
flipped around.
This has allowed for us to replace inmediate values with these constants
in several places to improve readability.

WATRTILE was renamed to WATERTILE in the name of readability.
2017-10-28 18:08:24 -04:00

847 lines
11 KiB
NASM
Executable File

DoPlayerMovement:: ; 80000
call .GetDPad
ld a, movement_step_sleep
ld [MovementAnimation], a
xor a
ld [wd041], a
call .TranslateIntoMovement
ld c, a
ld a, [MovementAnimation]
ld [wPlayerNextMovement], a
ret
.GetDPad:
ld a, [hJoyDown]
ld [CurInput], a
; Standing downhill instead moves down.
ld hl, BikeFlags
bit 2, [hl] ; downhill
ret z
ld c, a
and D_PAD
ret nz
ld a, c
or D_DOWN
ld [CurInput], a
ret
; 8002d
.TranslateIntoMovement:
ld a, [PlayerState]
cp PLAYER_NORMAL
jr z, .Normal
cp PLAYER_SURF
jr z, .Surf
cp PLAYER_SURF_PIKA
jr z, .Surf
cp PLAYER_BIKE
jr z, .Normal
cp PLAYER_SLIP
jr z, .Ice
.Normal:
call .CheckForced
call .GetAction
call .CheckTile
ret c
call .CheckTurning
ret c
call .TryStep
ret c
call .TryJump
ret c
call .CheckWarp
ret c
jr .NotMoving
.Surf:
call .CheckForced
call .GetAction
call .CheckTile
ret c
call .CheckTurning
ret c
call .TrySurf
ret c
jr .NotMoving
.Ice:
call .CheckForced
call .GetAction
call .CheckTile
ret c
call .CheckTurning
ret c
call .TryStep
ret c
call .TryJump
ret c
call .CheckWarp
ret c
ld a, [WalkingDirection]
cp STANDING
jr z, .HitWall
call .BumpSound
.HitWall:
call .StandInPlace
xor a
ret
.NotMoving:
ld a, [WalkingDirection]
cp STANDING
jr z, .Standing
; Walking into an edge warp won't bump.
ld a, [EngineBuffer4]
and a
jr nz, .CantMove
call .BumpSound
.CantMove:
call ._WalkInPlace
xor a
ret
.Standing:
call .StandInPlace
xor a
ret
; 800b7
.CheckTile: ; 800b7
; Tiles such as waterfalls and warps move the player
; in a given direction, overriding input.
ld a, [PlayerStandingTile]
ld c, a
call CheckWhirlpoolTile
jr c, .not_whirlpool
ld a, 3
scf
ret
.not_whirlpool
and $f0
cp $30 ; moving water
jr z, .water
cp $40 ; moving land 1
jr z, .land1
cp $50 ; moving land 2
jr z, .land2
cp $70 ; warps
jr z, .warps
jr .no_walk
.water
ld a, c
and 3
ld c, a
ld b, 0
ld hl, .water_table
add hl, bc
ld a, [hl]
ld [WalkingDirection], a
jr .continue_walk
.water_table
db RIGHT
db LEFT
db UP
db DOWN
.land1
ld a, c
and 7
ld c, a
ld b, 0
ld hl, .land1_table
add hl, bc
ld a, [hl]
cp STANDING
jr z, .no_walk
ld [WalkingDirection], a
jr .continue_walk
.land1_table
db STANDING
db RIGHT
db LEFT
db UP
db DOWN
db STANDING
db STANDING
db STANDING
.land2
ld a, c
and 7
ld c, a
ld b, 0
ld hl, .land2_table
add hl, bc
ld a, [hl]
cp STANDING
jr z, .no_walk
ld [WalkingDirection], a
jr .continue_walk
.land2_table
db RIGHT
db LEFT
db UP
db DOWN
db STANDING
db STANDING
db STANDING
db STANDING
.warps
ld a, c
cp $71 ; door
jr z, .down
cp $79
jr z, .down
cp $7a ; stairs
jr z, .down
cp $7b ; cave
jr nz, .no_walk
.down
ld a, DOWN
ld [WalkingDirection], a
jr .continue_walk
.no_walk
xor a
ret
.continue_walk
ld a, STEP_WALK
call .DoStep
ld a, 5
scf
ret
; 80147
.CheckTurning: ; 80147
; If the player is turning, change direction first. This also lets
; the player change facing without moving by tapping a direction.
ld a, [wPlayerTurningDirection]
cp 0
jr nz, .not_turning
ld a, [WalkingDirection]
cp STANDING
jr z, .not_turning
ld e, a
ld a, [PlayerDirection]
rrca
rrca
and 3
cp e
jr z, .not_turning
ld a, STEP_TURN
call .DoStep
ld a, 2
scf
ret
.not_turning
xor a
ret
; 8016b
.TryStep: ; 8016b
; Surfing actually calls .TrySurf directly instead of passing through here.
ld a, [PlayerState]
cp PLAYER_SURF
jr z, .TrySurf
cp PLAYER_SURF_PIKA
jr z, .TrySurf
call .CheckLandPerms
jr c, .bump
call .CheckNPC
and a
jr z, .bump
cp 2
jr z, .bump
ld a, [PlayerStandingTile]
call CheckIceTile
jr nc, .ice
; Downhill riding is slower when not moving down.
call .BikeCheck
jr nz, .walk
ld hl, BikeFlags
bit 2, [hl] ; downhill
jr z, .fast
ld a, [WalkingDirection]
cp DOWN
jr z, .fast
ld a, STEP_WALK
call .DoStep
scf
ret
.fast
ld a, STEP_BIKE
call .DoStep
scf
ret
.walk
ld a, STEP_WALK
call .DoStep
scf
ret
.ice
ld a, STEP_ICE
call .DoStep
scf
ret
; unused?
xor a
ret
.bump
xor a
ret
; 801c0
.TrySurf: ; 801c0
call .CheckSurfPerms
ld [wd040], a
jr c, .surf_bump
call .CheckNPC
ld [wd03f], a
and a
jr z, .surf_bump
cp 2
jr z, .surf_bump
ld a, [wd040]
and a
jr nz, .ExitWater
ld a, STEP_WALK
call .DoStep
scf
ret
.ExitWater:
call .GetOutOfWater
call PlayMapMusic
ld a, STEP_WALK
call .DoStep
ld a, 6
scf
ret
.surf_bump
xor a
ret
; 801f3
.TryJump: ; 801f3
ld a, [PlayerStandingTile]
ld e, a
and $f0
cp $a0 ; ledge
jr nz, .DontJump
ld a, e
and 7
ld e, a
ld d, 0
ld hl, .data_8021e
add hl, de
ld a, [FacingDirection]
and [hl]
jr z, .DontJump
ld de, SFX_JUMP_OVER_LEDGE
call PlaySFX
ld a, STEP_LEDGE
call .DoStep
ld a, 7
scf
ret
.DontJump:
xor a
ret
.data_8021e
db FACE_RIGHT
db FACE_LEFT
db FACE_UP
db FACE_DOWN
db FACE_RIGHT | FACE_DOWN
db FACE_DOWN | FACE_LEFT
db FACE_UP | FACE_RIGHT
db FACE_UP | FACE_LEFT
; 80226
.CheckWarp: ; 80226
; Bug: Since no case is made for STANDING here, it will check
; [.edgewarps + $ff]. This resolves to $3e at $8035a.
; This causes wd041 to be nonzero when standing on tile $3e,
; making bumps silent.
ld a, [WalkingDirection]
ld e, a
ld d, 0
ld hl, .EdgeWarps
add hl, de
ld a, [PlayerStandingTile]
cp [hl]
jr nz, .not_warp
ld a, 1
ld [wd041], a
ld a, [WalkingDirection]
cp STANDING
jr z, .not_warp
ld e, a
ld a, [PlayerDirection]
rrca
rrca
and 3
cp e
jr nz, .not_warp
call WarpCheck
jr nc, .not_warp
call .StandInPlace
scf
ld a, 1
ret
.not_warp
xor a
ret
.EdgeWarps:
db $70, $78, $76, $7e
; 8025f
.DoStep:
ld e, a
ld d, 0
ld hl, .Steps
add hl, de
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [WalkingDirection]
ld e, a
cp STANDING
jp z, .StandInPlace
add hl, de
ld a, [hl]
ld [MovementAnimation], a
ld hl, .FinishFacing
add hl, de
ld a, [hl]
ld [wPlayerTurningDirection], a
ld a, 4
ret
.Steps:
dw .SlowStep
dw .NormalStep
dw .FastStep
dw .JumpStep
dw .SlideStep
dw .TurningStep
dw .BackJumpStep
dw .FinishFacing
.SlowStep:
slow_step DOWN
slow_step UP
slow_step LEFT
slow_step RIGHT
.NormalStep:
step DOWN
step UP
step LEFT
step RIGHT
.FastStep:
big_step DOWN
big_step UP
big_step LEFT
big_step RIGHT
.JumpStep:
jump_step DOWN
jump_step UP
jump_step LEFT
jump_step RIGHT
.SlideStep:
fast_slide_step DOWN
fast_slide_step UP
fast_slide_step LEFT
fast_slide_step RIGHT
.BackJumpStep:
jump_step UP
jump_step DOWN
jump_step RIGHT
jump_step LEFT
.TurningStep:
turn_step DOWN
turn_step UP
turn_step LEFT
turn_step RIGHT
.FinishFacing:
db $80 + DOWN
db $80 + UP
db $80 + LEFT
db $80 + RIGHT
; 802b3
.StandInPlace: ; 802b3
ld a, 0
ld [wPlayerTurningDirection], a
ld a, movement_step_sleep
ld [MovementAnimation], a
xor a
ret
; 802bf
._WalkInPlace: ; 802bf
ld a, 0
ld [wPlayerTurningDirection], a
ld a, movement_step_bump
ld [MovementAnimation], a
xor a
ret
; 802cb
.CheckForced: ; 802cb
; When sliding on ice, input is forced to remain in the same direction.
call CheckStandingOnIce
ret nc
ld a, [wPlayerTurningDirection]
cp 0
ret z
and 3
ld e, a
ld d, 0
ld hl, .forced_dpad
add hl, de
ld a, [CurInput]
and BUTTONS
or [hl]
ld [CurInput], a
ret
.forced_dpad
db D_DOWN, D_UP, D_LEFT, D_RIGHT
; 802ec
.GetAction: ; 802ec
; Poll player input and update movement info.
ld hl, .table
ld de, .table2 - .table1
ld a, [CurInput]
bit D_DOWN_F, a
jr nz, .d_down
bit D_UP_F, a
jr nz, .d_up
bit D_LEFT_F, a
jr nz, .d_left
bit D_RIGHT_F, a
jr nz, .d_right
; Standing
jr .update
.d_down add hl, de
.d_up add hl, de
.d_left add hl, de
.d_right add hl, de
.update
ld a, [hli]
ld [WalkingDirection], a
ld a, [hli]
ld [FacingDirection], a
ld a, [hli]
ld [WalkingX], a
ld a, [hli]
ld [WalkingY], a
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [hl]
ld [WalkingTile], a
ret
.table
; struct:
; walk direction
; facing
; x movement
; y movement
; tile collision pointer
.table1
db STANDING, FACE_CURRENT, 0, 0
dw PlayerStandingTile
.table2
db RIGHT, FACE_RIGHT, 1, 0
dw TileRight
db LEFT, FACE_LEFT, -1, 0
dw TileLeft
db UP, FACE_UP, 0, -1
dw TileUp
db DOWN, FACE_DOWN, 0, 1
dw TileDown
; 80341
.CheckNPC: ; 80341
; Returns 0 if there is an NPC in front that you can't move
; Returns 1 if there is no NPC in front
; Returns 2 if there is a movable NPC in front
ld a, 0
ld [hMapObjectIndexBuffer], a
; Load the next X coordinate into d
ld a, [PlayerStandingMapX]
ld d, a
ld a, [WalkingX]
add d
ld d, a
; Load the next Y coordinate into e
ld a, [PlayerStandingMapY]
ld e, a
ld a, [WalkingY]
add e
ld e, a
; Find an object struct with coordinates equal to d,e
ld bc, ObjectStructs ; redundant
callba IsNPCAtCoord
jr nc, .is_npc
call .CheckStrengthBoulder
jr c, .no_bump
xor a
ret
.is_npc
ld a, 1
ret
.no_bump
ld a, 2
ret
; 8036f
.CheckStrengthBoulder: ; 8036f
ld hl, BikeFlags
bit 0, [hl] ; using strength
jr z, .not_boulder
ld hl, OBJECT_DIRECTION_WALKING
add hl, bc
ld a, [hl]
cp STANDING
jr nz, .not_boulder
ld hl, OBJECT_PALETTE
add hl, bc
bit 6, [hl]
jr z, .not_boulder
ld hl, OBJECT_FLAGS2
add hl, bc
set 2, [hl]
ld a, [WalkingDirection]
ld d, a
ld hl, OBJECT_RANGE
add hl, bc
ld a, [hl]
and $fc
or d
ld [hl], a
scf
ret
.not_boulder
xor a
ret
; 8039e
.CheckLandPerms: ; 8039e
; Return 0 if walking onto land and tile permissions allow it.
; Otherwise, return carry.
ld a, [TilePermissions]
ld d, a
ld a, [FacingDirection]
and d
jr nz, .NotWalkable
ld a, [WalkingTile]
call .CheckWalkable
jr c, .NotWalkable
xor a
ret
.NotWalkable:
scf
ret
; 803b4
.CheckSurfPerms: ; 803b4
; Return 0 if moving in water, or 1 if moving onto land.
; Otherwise, return carry.
ld a, [TilePermissions]
ld d, a
ld a, [FacingDirection]
and d
jr nz, .NotSurfable
ld a, [WalkingTile]
call .CheckSurfable
jr c, .NotSurfable
and a
ret
.NotSurfable:
scf
ret
; 803ca
.BikeCheck: ; 803ca
ld a, [PlayerState]
cp PLAYER_BIKE
ret z
cp PLAYER_SLIP
ret
; 803d3
.CheckWalkable: ; 803d3
; Return 0 if tile a is land. Otherwise, return carry.
call GetTileCollision
and a ; land
ret z
scf
ret
; 803da
.CheckSurfable: ; 803da
; Return 0 if tile a is water, or 1 if land.
; Otherwise, return carry.
call GetTileCollision
cp WATERTILE
jr z, .Water
; Can walk back onto land from water.
and a
jr z, .Land
jr .Neither
.Water:
xor a
ret
.Land:
ld a, 1
and a
ret
.Neither:
scf
ret
; 803ee
.BumpSound: ; 803ee
call CheckSFX
ret c
ld de, SFX_BUMP
call PlaySFX
ret
; 803f9
.GetOutOfWater: ; 803f9
push bc
ld a, PLAYER_NORMAL
ld [PlayerState], a
call ReplaceKrisSprite ; UpdateSprites
pop bc
ret
; 80404
CheckStandingOnIce:: ; 80404
ld a, [wPlayerTurningDirection]
cp 0
jr z, .not_ice
cp $f0
jr z, .not_ice
ld a, [PlayerStandingTile]
call CheckIceTile
jr nc, .yep
ld a, [PlayerState]
cp PLAYER_SLIP
jr nz, .not_ice
.yep
scf
ret
.not_ice
and a
ret
; 80422
StopPlayerForEvent:: ; 80422
ld hl, wPlayerNextMovement
ld a, movement_step_sleep
cp [hl]
ret z
ld [hl], a
ld a, 0
ld [wPlayerTurningDirection], a
ret
; 80430