pokecrystal/engine/overworld/npc_movement.asm

563 lines
7.5 KiB
NASM
Raw Normal View History

2018-06-24 14:09:41 +00:00
CanObjectMoveInDirection:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_PALETTE
add hl, bc
2018-05-23 23:10:15 +00:00
bit SWIMMING_F, [hl]
jr z, .not_swimming
2015-12-09 23:25:44 +00:00
; BUG: Swimming NPCs aren't limited by their movement radius (see docs/bugs_and_glitches.md)
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_FLAGS1
add hl, bc
bit NOCLIP_TILES_F, [hl]
2015-12-09 23:25:44 +00:00
push hl
push bc
call WillObjectBumpIntoLand
2015-12-09 23:25:44 +00:00
pop bc
pop hl
ret c
jr .continue
2015-12-09 23:25:44 +00:00
2018-05-23 23:10:15 +00:00
.not_swimming
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_FLAGS1
add hl, bc
bit NOCLIP_TILES_F, [hl]
jr nz, .noclip_tiles
2015-12-09 23:25:44 +00:00
push hl
push bc
call WillObjectBumpIntoWater
2015-12-09 23:25:44 +00:00
pop bc
pop hl
ret c
.noclip_tiles
.continue
bit NOCLIP_OBJS_F, [hl]
jr nz, .noclip_objs
2015-12-09 23:25:44 +00:00
push hl
push bc
call WillObjectBumpIntoSomeoneElse
2015-12-09 23:25:44 +00:00
pop bc
pop hl
ret c
.noclip_objs
bit MOVE_ANYWHERE_F, [hl]
jr nz, .move_anywhere
2015-12-09 23:25:44 +00:00
push hl
call HasObjectReachedMovementLimit
2015-12-09 23:25:44 +00:00
pop hl
ret c
push hl
call IsObjectMovingOffEdgeOfScreen
2015-12-09 23:25:44 +00:00
pop hl
ret c
.move_anywhere
2015-12-09 23:25:44 +00:00
and a
ret
2018-06-24 14:09:41 +00:00
WillObjectBumpIntoWater:
2020-10-05 15:24:47 +00:00
call CanObjectLeaveTile
2015-12-09 23:25:44 +00:00
ret c
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld d, [hl]
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld e, [hl]
ld hl, OBJECT_PALETTE
add hl, bc
2018-01-11 17:00:01 +00:00
bit OAM_PRIORITY, [hl]
2020-10-05 15:24:47 +00:00
jp nz, WillObjectRemainOnWater
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_TILE
add hl, bc
ld a, [hl]
ld d, a
call GetTileCollision
and a ; LAND_TILE
jr z, WillObjectBumpIntoTile
2015-12-09 23:25:44 +00:00
scf
ret
2018-06-24 14:09:41 +00:00
WillObjectBumpIntoLand:
2020-10-05 15:24:47 +00:00
call CanObjectLeaveTile
2015-12-09 23:25:44 +00:00
ret c
ld hl, OBJECT_NEXT_TILE
add hl, bc
ld a, [hl]
call GetTileCollision
cp WATER_TILE
jr z, WillObjectBumpIntoTile
2015-12-09 23:25:44 +00:00
scf
ret
2018-06-24 14:09:41 +00:00
WillObjectBumpIntoTile:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_TILE
add hl, bc
ld a, [hl]
2020-10-05 15:24:47 +00:00
call GetSideWallDirectionMask
2015-12-09 23:25:44 +00:00
ret nc
push af
ld hl, OBJECT_DIRECTION_WALKING
add hl, bc
ld a, [hl]
2018-01-16 22:27:50 +00:00
maskbits NUM_DIRECTIONS
2015-12-09 23:25:44 +00:00
ld e, a
ld d, 0
2020-10-05 15:24:47 +00:00
ld hl, .dir_masks
2015-12-09 23:25:44 +00:00
add hl, de
pop af
and [hl]
ret z
scf
ret
2020-10-05 15:24:47 +00:00
.dir_masks
db DOWN_MASK ; DOWN
db UP_MASK ; UP
db RIGHT_MASK ; LEFT
db LEFT_MASK ; RIGHT
2015-12-09 23:25:44 +00:00
2020-10-05 15:24:47 +00:00
CanObjectLeaveTile:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_STANDING_TILE
add hl, bc
ld a, [hl]
2020-10-05 15:24:47 +00:00
call GetSideWallDirectionMask
2015-12-09 23:25:44 +00:00
ret nc
push af
ld hl, OBJECT_DIRECTION_WALKING
add hl, bc
2018-01-16 22:27:50 +00:00
maskbits NUM_DIRECTIONS
2015-12-09 23:25:44 +00:00
ld e, a
ld d, 0
2020-10-05 15:24:47 +00:00
ld hl, .dir_masks
2015-12-09 23:25:44 +00:00
add hl, de
pop af
and [hl]
ret z
scf
ret
2020-10-05 15:24:47 +00:00
.dir_masks
db UP_MASK ; DOWN
db DOWN_MASK ; UP
db LEFT_MASK ; LEFT
db RIGHT_MASK ; RIGHT
2015-12-09 23:25:44 +00:00
2020-10-05 15:24:47 +00:00
GetSideWallDirectionMask:
2015-12-09 23:25:44 +00:00
ld d, a
and $f0
2018-06-29 02:35:29 +00:00
cp HI_NYBBLE_SIDE_WALLS
jr z, .continue
cp HI_NYBBLE_SIDE_BUOYS
jr z, .continue
2015-12-09 23:25:44 +00:00
xor a
ret
.continue
2015-12-09 23:25:44 +00:00
ld a, d
2020-10-05 15:24:47 +00:00
and $7
2015-12-09 23:25:44 +00:00
ld e, a
ld d, 0
2020-10-05 15:24:47 +00:00
ld hl, .side_wall_masks
2015-12-09 23:25:44 +00:00
add hl, de
ld a, [hl]
scf
ret
2020-10-05 15:24:47 +00:00
.side_wall_masks
db RIGHT_MASK ; COLL_RIGHT_WALL/BUOY
db LEFT_MASK ; COLL_LEFT_WALL/BUOY
db DOWN_MASK ; COLL_UP_WALL/BUOY
db UP_MASK ; COLL_DOWN_WALL/BUOY
db UP_MASK | RIGHT_MASK ; COLL_DOWN_RIGHT_WALL/BUOY
db UP_MASK | LEFT_MASK ; COLL_DOWN_LEFT_WALL/BUOY
db DOWN_MASK | RIGHT_MASK ; COLL_UP_RIGHT_WALL/BUOY
db DOWN_MASK | LEFT_MASK ; COLL_UP_LEFT_WALL/BUOY
2015-12-09 23:25:44 +00:00
2020-10-05 15:24:47 +00:00
WillObjectRemainOnWater:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_DIRECTION_WALKING
add hl, bc
ld a, [hl]
2018-01-16 22:27:50 +00:00
maskbits NUM_DIRECTIONS
2018-01-11 17:00:01 +00:00
jr z, .down
2015-12-09 23:25:44 +00:00
dec a
2018-01-11 17:00:01 +00:00
jr z, .up
2015-12-09 23:25:44 +00:00
dec a
2018-01-11 17:00:01 +00:00
jr z, .left
jr .right
2015-12-09 23:25:44 +00:00
2018-01-11 17:00:01 +00:00
.down
2015-12-09 23:25:44 +00:00
inc e
push de
inc d
2018-01-11 17:00:01 +00:00
jr .continue
2015-12-09 23:25:44 +00:00
2018-01-11 17:00:01 +00:00
.up
2015-12-09 23:25:44 +00:00
push de
inc d
2018-01-11 17:00:01 +00:00
jr .continue
2015-12-09 23:25:44 +00:00
2018-01-11 17:00:01 +00:00
.left
2015-12-09 23:25:44 +00:00
push de
inc e
2018-01-11 17:00:01 +00:00
jr .continue
2015-12-09 23:25:44 +00:00
2018-01-11 17:00:01 +00:00
.right
2015-12-09 23:25:44 +00:00
inc d
push de
inc e
2018-01-11 17:00:01 +00:00
.continue
2015-12-09 23:25:44 +00:00
call GetCoordTile
call GetTileCollision
pop de
and a ; LAND_TILE
2018-01-11 17:00:01 +00:00
jr nz, .not_land
2015-12-09 23:25:44 +00:00
call GetCoordTile
call GetTileCollision
and a ; LAND_TILE
2018-01-11 17:00:01 +00:00
jr nz, .not_land
2015-12-09 23:25:44 +00:00
xor a
ret
2018-01-11 17:00:01 +00:00
.not_land
2015-12-09 23:25:44 +00:00
scf
ret
2018-06-24 14:09:41 +00:00
CheckFacingObject::
2015-12-09 23:25:44 +00:00
call GetFacingTileCoord
; Double the distance for counter tiles.
call CheckCounterTile
2020-10-05 15:24:47 +00:00
jr nz, .not_counter
2015-12-09 23:25:44 +00:00
2018-01-23 22:39:09 +00:00
ld a, [wPlayerStandingMapX]
2015-12-09 23:25:44 +00:00
sub d
cpl
inc a
add d
ld d, a
2018-01-23 22:39:09 +00:00
ld a, [wPlayerStandingMapY]
2015-12-09 23:25:44 +00:00
sub e
cpl
inc a
add e
ld e, a
2020-10-05 15:24:47 +00:00
.not_counter
2018-01-23 22:39:09 +00:00
ld bc, wObjectStructs ; redundant
2015-12-09 23:25:44 +00:00
ld a, 0
ldh [hMapObjectIndex], a
2015-12-09 23:25:44 +00:00
call IsNPCAtCoord
ret nc
ld hl, OBJECT_DIRECTION_WALKING
add hl, bc
ld a, [hl]
cp STANDING
jr z, .standing
xor a
ret
.standing
scf
ret
2018-06-24 14:09:41 +00:00
WillObjectBumpIntoSomeoneElse:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld d, [hl]
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld e, [hl]
jr IsNPCAtCoord
2020-10-06 00:10:01 +00:00
IsObjectFacingSomeoneElse: ; unreferenced
ldh a, [hMapObjectIndex]
2015-12-09 23:25:44 +00:00
call GetObjectStruct
2020-10-06 00:10:01 +00:00
call .GetFacingCoords
2015-12-09 23:25:44 +00:00
call IsNPCAtCoord
ret
2020-10-06 00:10:01 +00:00
.GetFacingCoords:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld d, [hl]
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld e, [hl]
call GetSpriteDirection
2020-10-06 00:10:01 +00:00
and a ; OW_DOWN?
2015-12-09 23:25:44 +00:00
jr z, .down
cp OW_UP
jr z, .up
cp OW_LEFT
jr z, .left
2020-10-06 00:10:01 +00:00
; OW_RIGHT
2015-12-09 23:25:44 +00:00
inc d
ret
.down
inc e
ret
.up
dec e
ret
.left
dec d
ret
2018-06-24 14:09:41 +00:00
IsNPCAtCoord:
2018-01-23 22:39:09 +00:00
ld bc, wObjectStructs
2015-12-09 23:25:44 +00:00
xor a
.loop
ldh [hObjectStructIndex], a
2016-05-05 02:34:09 +00:00
call DoesObjectHaveASprite
2015-12-09 23:25:44 +00:00
jr z, .next
ld hl, OBJECT_FLAGS1
add hl, bc
bit 7, [hl]
jr nz, .next
ld hl, OBJECT_PALETTE
add hl, bc
bit BIG_OBJECT_F, [hl]
2020-10-06 00:10:01 +00:00
jr z, .not_big
2020-10-05 15:24:47 +00:00
call WillObjectIntersectBigObject
2020-10-06 00:10:01 +00:00
jr nc, .check_current_coords
jr .continue
2015-12-09 23:25:44 +00:00
2020-10-06 00:10:01 +00:00
.not_big
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld a, [hl]
cp d
2020-10-06 00:10:01 +00:00
jr nz, .check_current_coords
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld a, [hl]
cp e
2020-10-06 00:10:01 +00:00
jr nz, .check_current_coords
2015-12-09 23:25:44 +00:00
2020-10-06 00:10:01 +00:00
.continue
ldh a, [hMapObjectIndex]
2015-12-09 23:25:44 +00:00
ld l, a
ldh a, [hObjectStructIndex]
2015-12-09 23:25:44 +00:00
cp l
2020-10-06 00:10:01 +00:00
jr nz, .yes
2015-12-09 23:25:44 +00:00
2020-10-06 00:10:01 +00:00
.check_current_coords
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_MAP_X
add hl, bc
ld a, [hl]
cp d
jr nz, .next
ld hl, OBJECT_MAP_Y
add hl, bc
ld a, [hl]
cp e
jr nz, .next
ldh a, [hMapObjectIndex]
2015-12-09 23:25:44 +00:00
ld l, a
ldh a, [hObjectStructIndex]
2015-12-09 23:25:44 +00:00
cp l
2020-10-06 00:10:01 +00:00
jr nz, .yes
2015-12-09 23:25:44 +00:00
.next
ld hl, OBJECT_LENGTH
2015-12-09 23:25:44 +00:00
add hl, bc
ld b, h
ld c, l
ldh a, [hObjectStructIndex]
2015-12-09 23:25:44 +00:00
inc a
cp NUM_OBJECT_STRUCTS
jr nz, .loop
and a
ret
2020-10-06 00:10:01 +00:00
.yes
2015-12-09 23:25:44 +00:00
scf
ret
2018-06-24 14:09:41 +00:00
HasObjectReachedMovementLimit:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_RADIUS
add hl, bc
ld a, [hl]
and a
jr z, .nope
and $f
jr z, .check_y
ld e, a
ld d, a
ld hl, OBJECT_INIT_X
add hl, bc
ld a, [hl]
sub d
ld d, a
ld a, [hl]
add e
ld e, a
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld a, [hl]
cp d
jr z, .yes
cp e
jr z, .yes
.check_y
ld hl, OBJECT_RADIUS
add hl, bc
ld a, [hl]
swap a
and $f
jr z, .nope
ld e, a
ld d, a
ld hl, OBJECT_INIT_Y
add hl, bc
ld a, [hl]
sub d
ld d, a
ld a, [hl]
add e
ld e, a
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld a, [hl]
cp d
jr z, .yes
cp e
jr z, .yes
.nope
xor a
ret
.yes
scf
ret
2018-06-24 14:09:41 +00:00
IsObjectMovingOffEdgeOfScreen:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
2018-01-23 22:39:09 +00:00
ld a, [wXCoord]
2015-12-09 23:25:44 +00:00
cp [hl]
jr z, .check_y
jr nc, .yes
add $9
cp [hl]
jr c, .yes
.check_y
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
2018-01-23 22:39:09 +00:00
ld a, [wYCoord]
2015-12-09 23:25:44 +00:00
cp [hl]
jr z, .nope
jr nc, .yes
add $8
cp [hl]
jr c, .yes
.nope
and a
ret
.yes
scf
ret
2020-10-06 00:10:01 +00:00
IsNPCAtPlayerCoord: ; unreferenced
2018-01-23 22:39:09 +00:00
ld a, [wPlayerStandingMapX]
2015-12-09 23:25:44 +00:00
ld d, a
2018-01-23 22:39:09 +00:00
ld a, [wPlayerStandingMapY]
2015-12-09 23:25:44 +00:00
ld e, a
2018-01-23 22:39:09 +00:00
ld bc, wObjectStructs
2015-12-09 23:25:44 +00:00
xor a
.loop
ldh [hObjectStructIndex], a
2016-05-05 02:34:09 +00:00
call DoesObjectHaveASprite
2015-12-09 23:25:44 +00:00
jr z, .next
2020-10-06 00:10:01 +00:00
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_MOVEMENTTYPE
add hl, bc
ld a, [hl]
cp SPRITEMOVEDATA_BIGDOLLSYM
2020-10-06 00:10:01 +00:00
jr nz, .not_big
2020-10-05 15:24:47 +00:00
call WillObjectIntersectBigObject
2015-12-09 23:25:44 +00:00
jr c, .yes
jr .next
2020-10-06 00:10:01 +00:00
.not_big
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld a, [hl]
cp e
jr nz, .check_current_coords
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld a, [hl]
cp d
jr nz, .check_current_coords
ldh a, [hObjectStructIndex]
cp PLAYER_OBJECT
2015-12-09 23:25:44 +00:00
jr z, .next
jr .yes
.check_current_coords
ld hl, OBJECT_MAP_Y
add hl, bc
ld a, [hl]
cp e
jr nz, .next
ld hl, OBJECT_MAP_X
add hl, bc
ld a, [hl]
cp d
jr nz, .next
jr .yes
.next
ld hl, OBJECT_LENGTH
2015-12-09 23:25:44 +00:00
add hl, bc
ld b, h
ld c, l
ldh a, [hObjectStructIndex]
2015-12-09 23:25:44 +00:00
inc a
cp NUM_OBJECT_STRUCTS
jr nz, .loop
xor a
ret
.yes
scf
ret
2020-10-05 15:24:47 +00:00
WillObjectIntersectBigObject:
2015-12-09 23:25:44 +00:00
ld hl, OBJECT_NEXT_MAP_X
add hl, bc
ld a, d
sub [hl]
jr c, .nope
2020-10-05 15:24:47 +00:00
cp 2 ; big doll width
2015-12-09 23:25:44 +00:00
jr nc, .nope
ld hl, OBJECT_NEXT_MAP_Y
add hl, bc
ld a, e
sub [hl]
jr c, .nope
2020-10-05 15:24:47 +00:00
cp 2 ; big doll height
2015-12-09 23:25:44 +00:00
jr nc, .nope
scf
ret
.nope
and a
ret