pokecrystal-board/engine/overworld/player_object.asm

1195 lines
19 KiB
NASM
Raw Normal View History

2018-06-24 07:09:41 -07:00
BlankScreen:
2016-03-27 09:47:28 -07:00
call DisableSpriteUpdates
xor a
ldh [hBGMapMode], a
2016-03-27 09:47:28 -07:00
call ClearBGPalettes
call ClearSprites
hlcoord 0, 0
ld bc, wTilemapEnd - wTilemap
2016-03-27 09:47:28 -07:00
ld a, " "
call ByteFill
hlcoord 0, 0, wAttrmap
ld bc, wAttrmapEnd - wAttrmap
2016-03-27 09:47:28 -07:00
ld a, $7
call ByteFill
call WaitBGMap2
2024-02-10 15:16:00 -08:00
call SetDefaultBGPAndOBP
2016-03-27 09:47:28 -07:00
ret
2018-06-24 07:09:41 -07:00
SpawnPlayer:
2016-03-27 09:47:28 -07:00
ld a, -1
ld [wObjectFollow_Leader], a
ld [wObjectFollow_Follower], a
2020-04-16 06:30:50 -07:00
ld a, PLAYER
2016-03-27 09:47:28 -07:00
ld hl, PlayerObjectTemplate
call CopyPlayerObjectTemplate
2020-04-16 06:30:50 -07:00
ld b, PLAYER
2016-03-27 09:47:28 -07:00
call PlayerSpawn_ConvertCoords
2018-01-22 10:25:49 -08:00
ld a, PLAYER_OBJECT
2016-03-27 09:47:28 -07:00
call GetMapObject
ld hl, MAPOBJECT_PALETTE
2016-03-27 09:47:28 -07:00
add hl, bc
2024-03-09 07:40:21 -08:00
push hl
ld a, [wPlayerCharacter]
ld e, PLAYERDATA_OW_PAL
call GetPlayerField
add PAL_NPC ; convert from PAL_OW to PAL_NPC
swap a
or OBJECTTYPE_SCRIPT
pop hl
ld [hl], a
2018-01-22 10:25:49 -08:00
ld a, PLAYER_OBJECT
ldh [hMapObjectIndex], a
2018-01-23 14:39:09 -08:00
ld bc, wMapObjects
2018-01-22 10:25:49 -08:00
ld a, PLAYER_OBJECT
ldh [hObjectStructIndex], a
2018-01-23 14:39:09 -08:00
ld de, wObjectStructs
2016-03-27 09:47:28 -07:00
call CopyMapObjectToObjectStruct
ld a, PLAYER
ld [wCenteredObject], a
ret
2018-06-24 07:09:41 -07:00
PlayerObjectTemplate:
2016-03-27 09:47:28 -07:00
; A dummy map object used to initialize the player object.
; Shorter than the actual amount copied by two bytes.
; Said bytes seem to be unused.
object_event -4, -4, SPRITE_CHRIS, SPRITEMOVEDATA_PLAYER, 15, 15, -1, -1, 0, OBJECTTYPE_SCRIPT, 0, 0, -1
2016-03-27 09:47:28 -07:00
2018-06-24 07:09:41 -07:00
CopyDECoordsToMapObject::
2016-03-27 09:47:28 -07:00
push de
ld a, b
call GetMapObject
pop de
ld hl, MAPOBJECT_X_COORD
add hl, bc
ld [hl], d
ld hl, MAPOBJECT_Y_COORD
add hl, bc
ld [hl], e
ret
2018-06-24 07:09:41 -07:00
PlayerSpawn_ConvertCoords:
2016-03-27 09:47:28 -07:00
push bc
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
add 4
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
add 4
ld e, a
pop bc
call CopyDECoordsToMapObject
ret
2018-06-24 07:09:41 -07:00
WriteObjectXY::
2016-03-27 09:47:28 -07:00
ld a, b
call CheckObjectVisibility
ret c
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld d, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld e, [hl]
ldh a, [hMapObjectIndex]
2016-03-27 09:47:28 -07:00
ld b, a
call CopyDECoordsToMapObject
and a
ret
RefreshPlayerCoords::
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
add 4
ld d, a
ld hl, wPlayerMapX
2016-03-27 09:47:28 -07:00
sub [hl]
ld [hl], d
2018-01-23 14:39:09 -08:00
ld hl, wMapObjects + MAPOBJECT_X_COORD
2016-03-27 09:47:28 -07:00
ld [hl], d
2018-01-23 14:39:09 -08:00
ld hl, wPlayerLastMapX
2016-03-27 09:47:28 -07:00
ld [hl], d
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
add 4
ld e, a
ld hl, wPlayerMapY
2016-03-27 09:47:28 -07:00
sub [hl]
ld [hl], e
2018-01-23 14:39:09 -08:00
ld hl, wMapObjects + MAPOBJECT_Y_COORD
2016-03-27 09:47:28 -07:00
ld [hl], e
2018-01-23 14:39:09 -08:00
ld hl, wPlayerLastMapY
2016-03-27 09:47:28 -07:00
ld [hl], e
ld e, a
; the next three lines are useless
2016-03-27 09:47:28 -07:00
ld a, [wObjectFollow_Leader]
cp PLAYER
ret nz
2016-03-27 09:47:28 -07:00
ret
2018-06-24 07:09:41 -07:00
CopyObjectStruct::
2016-03-27 09:47:28 -07:00
call CheckObjectMask
and a
ret nz ; masked
ld hl, wObjectStructs + OBJECT_LENGTH * 1
2016-03-27 09:47:28 -07:00
ld a, 1
ld de, OBJECT_LENGTH
2016-03-27 09:47:28 -07:00
.loop
ldh [hObjectStructIndex], a
2016-03-27 09:47:28 -07:00
ld a, [hl]
and a
jr z, .done
add hl, de
ldh a, [hObjectStructIndex]
2016-03-27 09:47:28 -07:00
inc a
cp NUM_OBJECT_STRUCTS
jr nz, .loop
scf
ret ; overflow
.done
ld d, h
ld e, l
call CopyMapObjectToObjectStruct
ld hl, wStateFlags
2016-03-27 09:47:28 -07:00
bit 7, [hl]
ret z
ld hl, OBJECT_FLAGS2
add hl, de
set 5, [hl]
ret
2018-06-24 07:09:41 -07:00
CopyMapObjectToObjectStruct:
2016-03-27 09:47:28 -07:00
call .CopyMapObjectToTempObject
call CopyTempObjectToObjectStruct
ret
2018-06-24 07:09:41 -07:00
.CopyMapObjectToTempObject:
ldh a, [hObjectStructIndex]
2016-03-27 09:47:28 -07:00
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld [hl], a
ldh a, [hMapObjectIndex]
2016-03-27 09:47:28 -07:00
ld [wTempObjectCopyMapObjectIndex], a
ld hl, MAPOBJECT_SPRITE
add hl, bc
ld a, [hl]
ld [wTempObjectCopySprite], a
call GetSpriteVTile
ld [wTempObjectCopySpriteVTile], a
ld a, [hl]
call GetSpritePalette
ld [wTempObjectCopyPalette], a
ld hl, MAPOBJECT_PALETTE
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, [hl]
and MAPOBJECT_PALETTE_MASK
2016-03-27 09:47:28 -07:00
jr z, .skip_color_override
swap a
and PALETTE_MASK
2016-03-27 09:47:28 -07:00
ld [wTempObjectCopyPalette], a
.skip_color_override
ld hl, MAPOBJECT_MOVEMENT
add hl, bc
ld a, [hl]
ld [wTempObjectCopyMovement], a
ld hl, MAPOBJECT_SIGHT_RANGE
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, [hl]
ld [wTempObjectCopyRange], a
ld hl, MAPOBJECT_X_COORD
add hl, bc
ld a, [hl]
ld [wTempObjectCopyX], a
ld hl, MAPOBJECT_Y_COORD
add hl, bc
ld a, [hl]
ld [wTempObjectCopyY], a
ld hl, MAPOBJECT_RADIUS
add hl, bc
ld a, [hl]
ld [wTempObjectCopyRadius], a
ret
2018-06-24 07:09:41 -07:00
InitializeVisibleSprites:
ld bc, wMapObject1
2016-03-27 09:47:28 -07:00
ld a, 1
.loop
ldh [hMapObjectIndex], a
2016-03-27 09:47:28 -07:00
ld hl, MAPOBJECT_SPRITE
add hl, bc
ld a, [hl]
and a
jr z, .next
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
cp -1
jr nz, .next
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
ld e, a
ld hl, MAPOBJECT_X_COORD
add hl, bc
ld a, [hl]
add 1
sub d
jr c, .next
cp MAPOBJECT_SCREEN_WIDTH
jr nc, .next
ld hl, MAPOBJECT_Y_COORD
add hl, bc
ld a, [hl]
add 1
sub e
jr c, .next
cp MAPOBJECT_SCREEN_HEIGHT
jr nc, .next
push bc
call CopyObjectStruct
pop bc
jp c, .ret
.next
ld hl, MAPOBJECT_LENGTH
2016-03-27 09:47:28 -07:00
add hl, bc
ld b, h
ld c, l
ldh a, [hMapObjectIndex]
2016-03-27 09:47:28 -07:00
inc a
cp NUM_OBJECTS
jr nz, .loop
ret
2018-06-24 07:09:41 -07:00
.ret
2016-03-27 09:47:28 -07:00
ret
2018-06-24 07:09:41 -07:00
CheckObjectEnteringVisibleRange::
2016-03-27 09:47:28 -07:00
nop
ld a, [wPlayerStepDirection]
cp STANDING
ret z
ld hl, .dw
rst JumpTable
ret
2018-06-24 07:09:41 -07:00
.dw
2016-03-27 09:47:28 -07:00
dw .Down
dw .Up
dw .Left
dw .Right
2018-06-24 07:09:41 -07:00
.Up:
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
sub 1
jr .Vertical
2018-06-24 07:09:41 -07:00
.Down:
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
add 9
2018-06-24 07:09:41 -07:00
.Vertical:
2016-03-27 09:47:28 -07:00
ld d, a
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
ld e, a
ld bc, wMapObject1
2016-03-27 09:47:28 -07:00
ld a, 1
.loop_v
ldh [hMapObjectIndex], a
2016-03-27 09:47:28 -07:00
ld hl, MAPOBJECT_SPRITE
add hl, bc
ld a, [hl]
and a
jr z, .next_v
ld hl, MAPOBJECT_Y_COORD
add hl, bc
ld a, d
cp [hl]
jr nz, .next_v
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
cp -1
jr nz, .next_v
ld hl, MAPOBJECT_X_COORD
add hl, bc
ld a, [hl]
add 1
sub e
jr c, .next_v
cp MAPOBJECT_SCREEN_WIDTH
jr nc, .next_v
push de
push bc
call CopyObjectStruct
pop bc
pop de
.next_v
ld hl, MAPOBJECT_LENGTH
2016-03-27 09:47:28 -07:00
add hl, bc
ld b, h
ld c, l
ldh a, [hMapObjectIndex]
2016-03-27 09:47:28 -07:00
inc a
cp NUM_OBJECTS
jr nz, .loop_v
ret
2018-06-24 07:09:41 -07:00
.Left:
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
sub 1
jr .Horizontal
2018-06-24 07:09:41 -07:00
.Right:
2018-01-23 14:39:09 -08:00
ld a, [wXCoord]
2016-03-27 09:47:28 -07:00
add 10
2018-06-24 07:09:41 -07:00
.Horizontal:
2016-03-27 09:47:28 -07:00
ld e, a
2018-01-23 14:39:09 -08:00
ld a, [wYCoord]
2016-03-27 09:47:28 -07:00
ld d, a
ld bc, wMapObject1
2016-03-27 09:47:28 -07:00
ld a, 1
.loop_h
ldh [hMapObjectIndex], a
2016-03-27 09:47:28 -07:00
ld hl, MAPOBJECT_SPRITE
add hl, bc
ld a, [hl]
and a
jr z, .next_h
ld hl, MAPOBJECT_X_COORD
add hl, bc
ld a, e
cp [hl]
jr nz, .next_h
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
cp -1
jr nz, .next_h
ld hl, MAPOBJECT_Y_COORD
add hl, bc
ld a, [hl]
add 1
sub d
jr c, .next_h
cp MAPOBJECT_SCREEN_HEIGHT
jr nc, .next_h
push de
push bc
call CopyObjectStruct
pop bc
pop de
.next_h
ld hl, MAPOBJECT_LENGTH
2016-03-27 09:47:28 -07:00
add hl, bc
ld b, h
ld c, l
ldh a, [hMapObjectIndex]
2016-03-27 09:47:28 -07:00
inc a
cp NUM_OBJECTS
jr nz, .loop_h
ret
2018-06-24 07:09:41 -07:00
CopyTempObjectToObjectStruct:
2016-03-27 09:47:28 -07:00
ld a, [wTempObjectCopyMapObjectIndex]
ld hl, OBJECT_MAP_OBJECT_INDEX
add hl, de
ld [hl], a
ld a, [wTempObjectCopyMovement]
call CopySpriteMovementData
ld a, [wTempObjectCopyPalette]
ld hl, OBJECT_PALETTE
add hl, de
or [hl]
ld [hl], a
ld a, [wTempObjectCopyY]
call .InitYCoord
ld a, [wTempObjectCopyX]
call .InitXCoord
ld a, [wTempObjectCopySprite]
ld hl, OBJECT_SPRITE
add hl, de
ld [hl], a
ld a, [wTempObjectCopySpriteVTile]
ld hl, OBJECT_SPRITE_TILE
add hl, de
ld [hl], a
ld hl, OBJECT_STEP_TYPE
add hl, de
ld [hl], STEP_TYPE_RESET
2016-03-27 09:47:28 -07:00
ld hl, OBJECT_FACING
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], STANDING
ld a, [wTempObjectCopyRadius]
call .InitRadius
ld a, [wTempObjectCopyRange]
ld hl, OBJECT_RANGE
add hl, de
ld [hl], a
and a
ret
2018-06-24 07:09:41 -07:00
.InitYCoord:
2016-03-27 09:47:28 -07:00
ld hl, OBJECT_INIT_Y
add hl, de
ld [hl], a
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], a
2018-01-23 14:39:09 -08:00
ld hl, wYCoord
2016-03-27 09:47:28 -07:00
sub [hl]
and $f
swap a
2016-05-04 19:34:09 -07:00
ld hl, wPlayerBGMapOffsetY
2016-03-27 09:47:28 -07:00
sub [hl]
ld hl, OBJECT_SPRITE_Y
add hl, de
ld [hl], a
ret
2018-06-24 07:09:41 -07:00
.InitXCoord:
2016-03-27 09:47:28 -07:00
ld hl, OBJECT_INIT_X
add hl, de
ld [hl], a
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], a
2018-01-23 14:39:09 -08:00
ld hl, wXCoord
2016-03-27 09:47:28 -07:00
sub [hl]
and $f
swap a
2016-05-04 19:34:09 -07:00
ld hl, wPlayerBGMapOffsetX
2016-03-27 09:47:28 -07:00
sub [hl]
ld hl, OBJECT_SPRITE_X
add hl, de
ld [hl], a
ret
2018-06-24 07:09:41 -07:00
.InitRadius:
2016-03-27 09:47:28 -07:00
ld h, a
inc a
and $f
ld l, a
ld a, h
add $10
and $f0
or l
ld hl, OBJECT_RADIUS
add hl, de
ld [hl], a
ret
TrainerOrTalkerWalkToPlayer:
ldh a, [hLastTalked]
2016-03-27 09:47:28 -07:00
call InitMovementBuffer
2016-05-14 09:28:00 -07:00
ld a, movement_step_sleep
2016-03-27 09:47:28 -07:00
call AppendToMovementBuffer
ld a, [wSeenTrainerOrTalkerDistance]
2016-03-27 09:47:28 -07:00
dec a
jr z, .TerminateStep
ldh a, [hLastTalked]
2016-03-27 09:47:28 -07:00
ld b, a
ld c, PLAYER
ld d, 1
call .GetPathToPlayer
call DecrementMovementBufferCount
.TerminateStep:
2016-03-27 09:47:28 -07:00
ld a, movement_step_end
call AppendToMovementBuffer
ret
2018-06-24 07:09:41 -07:00
.GetPathToPlayer:
2016-03-27 09:47:28 -07:00
push de
push bc
; get player object struct, load to de
ld a, c
call GetMapObject
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
call GetObjectStruct
ld d, b
ld e, c
; get last talked object struct, load to bc
pop bc
ld a, b
call GetMapObject
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
call GetObjectStruct
; get last talked coords, load to bc
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld c, [hl]
ld b, a
; get player coords, load to de
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, de
ld a, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, de
ld e, [hl]
ld d, a
pop af
call ComputePathToWalkToPlayer
ret
2018-06-24 07:09:41 -07:00
SurfStartStep:
2016-03-27 09:47:28 -07:00
call InitMovementBuffer
call .GetMovementData
call AppendToMovementBuffer
ld a, movement_step_end
call AppendToMovementBuffer
ret
2018-06-24 07:09:41 -07:00
.GetMovementData:
2018-01-23 14:39:09 -08:00
ld a, [wPlayerDirection]
2016-03-27 09:47:28 -07:00
srl a
srl a
2018-01-16 14:27:50 -08:00
maskbits NUM_DIRECTIONS
2016-03-27 09:47:28 -07:00
ld e, a
ld d, 0
ld hl, .movement_data
add hl, de
ld a, [hl]
ret
.movement_data
2016-05-14 10:46:14 -07:00
slow_step DOWN
slow_step UP
slow_step LEFT
slow_step RIGHT
2016-03-27 09:47:28 -07:00
2018-06-24 07:09:41 -07:00
FollowNotExact::
2016-03-27 09:47:28 -07:00
push bc
ld a, c
call CheckObjectVisibility
ld d, b
ld e, c
pop bc
ret c
ld a, b
call CheckObjectVisibility
ret c
; object 2 is now in bc, object 1 is now in de
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld c, [hl]
ld b, a
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, de
ld a, [hl]
cp b
jr z, .same_x
jr c, .to_the_left
inc b
jr .continue
.to_the_left
dec b
jr .continue
.same_x
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, de
ld a, [hl]
cp c
jr z, .continue
jr c, .below
inc c
jr .continue
.below
dec c
.continue
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], b
ld a, b
2018-01-23 14:39:09 -08:00
ld hl, wXCoord
2016-03-27 09:47:28 -07:00
sub [hl]
and $f
swap a
2016-05-04 19:34:09 -07:00
ld hl, wPlayerBGMapOffsetX
2016-03-27 09:47:28 -07:00
sub [hl]
ld hl, OBJECT_SPRITE_X
add hl, de
ld [hl], a
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], c
ld a, c
2018-01-23 14:39:09 -08:00
ld hl, wYCoord
2016-03-27 09:47:28 -07:00
sub [hl]
and $f
swap a
2016-05-04 19:34:09 -07:00
ld hl, wPlayerBGMapOffsetY
2016-03-27 09:47:28 -07:00
sub [hl]
ld hl, OBJECT_SPRITE_Y
add hl, de
ld [hl], a
ldh a, [hObjectStructIndex]
2016-03-27 09:47:28 -07:00
ld hl, OBJECT_RANGE
add hl, de
ld [hl], a
ld hl, OBJECT_MOVEMENT_TYPE
2016-03-27 09:47:28 -07:00
add hl, de
ld [hl], SPRITEMOVEDATA_FOLLOWNOTEXACT
ld hl, OBJECT_STEP_TYPE
add hl, de
ld [hl], STEP_TYPE_RESET
2016-03-27 09:47:28 -07:00
ret
2018-06-24 07:09:41 -07:00
GetRelativeFacing::
2016-03-27 09:47:28 -07:00
; Determines which way map object e would have to turn to face map object d. Returns carry if it's impossible for whatever reason.
ld a, d
call GetMapObject
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
cp NUM_OBJECT_STRUCTS
jr nc, .carry
ld d, a
ld a, e
call GetMapObject
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
add hl, bc
ld a, [hl]
cp NUM_OBJECT_STRUCTS
jr nc, .carry
ld e, a
call .GetFacing_e_relativeto_d
ret
.carry
scf
ret
2018-06-24 07:09:41 -07:00
.GetFacing_e_relativeto_d:
2016-03-27 09:47:28 -07:00
; Determines which way object e would have to turn to face object d. Returns carry if it's impossible.
; load the coordinates of object d into bc
ld a, d
call GetObjectStruct
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld c, [hl]
ld b, a
push bc
; load the coordinates of object e into de
ld a, e
call GetObjectStruct
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld d, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld e, [hl]
pop bc
; |x1 - x2|
ld a, b
sub d
jr z, .same_x_1
jr nc, .b_right_of_d_1
cpl
inc a
.b_right_of_d_1
; |y1 - y2|
ld h, a
ld a, c
sub e
jr z, .same_y_1
jr nc, .c_below_e_1
cpl
inc a
.c_below_e_1
; |y1 - y2| - |x1 - x2|
sub h
jr c, .same_y_1
.same_x_1
; compare the y coordinates
ld a, c
cp e
jr z, .same_x_and_y
jr c, .c_directly_below_e
; c directly above e
ld d, DOWN
and a
ret
.c_directly_below_e
ld d, UP
and a
ret
.same_y_1
ld a, b
cp d
jr z, .same_x_and_y
jr c, .b_directly_right_of_d
; b directly left of d
ld d, RIGHT
and a
ret
.b_directly_right_of_d
ld d, LEFT
and a
ret
.same_x_and_y
scf
ret
2018-06-24 07:09:41 -07:00
QueueFollowerFirstStep:
2016-03-27 09:47:28 -07:00
call .QueueFirstStep
jr c, .same
ld [wFollowMovementQueue], a
xor a
ld [wFollowerMovementQueueLength], a
ret
.same
ld a, -1
ld [wFollowerMovementQueueLength], a
ret
.QueueFirstStep:
2016-03-27 09:47:28 -07:00
ld a, [wObjectFollow_Leader]
call GetObjectStruct
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld d, [hl]
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld e, [hl]
ld a, [wObjectFollow_Follower]
call GetObjectStruct
ld hl, OBJECT_MAP_X
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, d
cp [hl]
jr z, .check_y
jr c, .left
and a
2016-05-14 10:46:14 -07:00
ld a, movement_step + RIGHT
2016-03-27 09:47:28 -07:00
ret
.left
and a
2016-05-14 10:46:14 -07:00
ld a, movement_step + LEFT
2016-03-27 09:47:28 -07:00
ret
.check_y
ld hl, OBJECT_MAP_Y
2016-03-27 09:47:28 -07:00
add hl, bc
ld a, e
cp [hl]
jr z, .same_xy
jr c, .up
and a
2016-05-14 10:46:14 -07:00
ld a, movement_step + DOWN
2016-03-27 09:47:28 -07:00
ret
.up
and a
2016-05-14 10:46:14 -07:00
ld a, movement_step + UP
2016-03-27 09:47:28 -07:00
ret
.same_xy
scf
ret
RepositionMockedPlayerObject::
; map setup command called by map setup script MAPSETUP_CONNECTION after LoadBlockData,
; once the new map blocks have been loaded to wOverworldMapBlocks.
; Only applies during BOARDEVENT_VIEW_MAP_MODE
ldh a, [hCurBoardEvent]
cp BOARDEVENT_VIEW_MAP_MODE
ret nz
; if map at wBeforeViewMapMapGroup, wBeforeViewMapMapNumber is not the current map,
; or a map connected to the current map, we are done.
ld hl, wBeforeViewMapMapGroup
ld a, [hli]
ld b, a
ld c, [hl] ; wBeforeViewMapMapNumber
ld a, [wMapGroup]
cp b
jr nz, .next_map_1
ld a, [wMapNumber]
cp c
jr z, MockPlayerObject
.next_map_1
ld a, [wNorthConnectedMapGroup]
cp b
jr nz, .next_map_2
ld a, [wNorthConnectedMapNumber]
cp c
ld a, 0 ; north connected map
jr z, .is_connected_map
.next_map_2
ld a, [wSouthConnectedMapGroup]
cp b
jr nz, .next_map_3
ld a, [wSouthConnectedMapNumber]
cp c
ld a, 1 ; south connected map
jr z, .is_connected_map
.next_map_3
ld a, [wWestConnectedMapGroup]
cp b
jr nz, .next_map_4
ld a, [wWestConnectedMapNumber]
cp c
ld a, 2 ; west connected map
jr z, .is_connected_map
.next_map_4
ld a, [wEastConnectedMapGroup]
cp b
ret nz
ld a, [wEastConnectedMapNumber]
cp c
ld a, 3 ; east connected map
ret nz
.is_connected_map
ld [wTempByteValue], a
ld hl, .got_sprite_coords
push hl
ld a, [wBeforeViewMapXCoord]
ld d, a
ld a, [wBeforeViewMapYCoord]
ld e, a
jumptable_bc .Jumptable, wTempByteValue
.Jumptable:
dw GetNorthConnectedSpriteCoords
dw GetSouthConnectedSpriteCoords
dw GetWestConnectedSpriteCoords
dw GetEastConnectedSpriteCoords
.got_sprite_coords
ret nc ; return if sprite is not in visible part of connected map
jr MockPlayerObject.loaded_player_mock_coords
MockPlayerObject::
ld hl, wBeforeViewMapYCoord
ld de, wPlayerMockYCoord
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
.loaded_player_mock_coords
; refresh wPlayerObjectYCoord and wPlayerObjectXCoord (not strictly necessary)
farcall RefreshPlayerCoords
; copy default sprite object to the last object struct
ld hl, .DefaultPlayerObject
ld de, wMapObject{d:LAST_OBJECT}
ld bc, OBJECT_EVENT_SIZE + 1
call CopyBytes
2024-03-08 09:56:26 -08:00
; adjust palette number
2024-03-09 07:40:21 -08:00
ld a, [wPlayerCharacter]
ld e, PLAYERDATA_OW_PAL
2024-03-08 09:56:26 -08:00
call GetPlayerField
2024-03-09 07:40:21 -08:00
add PAL_NPC ; convert from PAL_OW to PAL_NPC
2024-03-08 09:56:26 -08:00
swap a
or OBJECTTYPE_SCRIPT
ld [wMapObject{d:LAST_OBJECT}Palette], a ; also wMapObject{d:LAST_OBJECT}Type
2024-03-08 09:56:26 -08:00
; adjust sprite id
farcall DeterminePlayerSprite
ld a, c
ld [wMapObject{d:LAST_OBJECT}Sprite], a
; copy player's coordinates
ld hl, wPlayerMockYCoord
ld de, wMapObject{d:LAST_OBJECT}YCoord
ld a, [hli]
add 4
ld [de], a
inc de
ld a, [hl] ; wPlayerMockXCoord
add 4
ld [de], a ; wMapObject{d:LAST_OBJECT}XCoord
; set facing direction
ld a, [wBeforeViewMapDirection]
srl a
srl a
maskbits NUM_DIRECTIONS
ld b, SPRITEMOVEDATA_STANDING_DOWN
add b
ld [wMapObject{d:LAST_OBJECT}Movement], a
; display mocked player object
; it will go to the last wMapObjects slot and to whichever wObjectStructs slot
; wObjectStructs[n][MAPOBJECT_OBJECT_STRUCT_ID] links both structs
ld a, NUM_OBJECTS - 1
call UnmaskCopyMapObjectStruct
ret
.DefaultPlayerObject:
db -1 ; MAPOBJECT_OBJECT_STRUCT_ID
object_event 0, 0, SPRITE_CHRIS, SPRITEMOVEDATA_STANDING_DOWN, 0, 0, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, ObjectEvent, -1
GetSouthConnectedSpriteCoords:
; ycoord / 2 <= 2
ld a, e
srl a
cp 3
ret nc
; [wSouthConnectionStripLocation]
ld hl, wSouthConnectionStripLocation
ld a, [hli]
ld h, [hl]
ld l, a
; + (xcoord / 2)
srl d
ld b, 0
ld c, d
add hl, bc
; + ([wMapWidth] + 6) * ycoord / 2
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
srl e
ld a, e
and a
jr z, .done
.loop
add hl, bc
dec a
jr nz, .loop
.done
call ConvertConnectedOverworldMapBlockAddressToXYCoords
ret
GetNorthConnectedSpriteCoords:
; wNorthConnectedMapHeight >= 3
; ycoord / 2 >= ([wNorthConnectedMapHeight] - 3)
ld a, [wNorthConnectedMapHeight]
sub 3
jr c, .nope
ld c, a
ld a, e
srl a
sub c
jr c, .nope
ld e, a ; e = ycoord / 2 - ([wNorthConnectedMapHeight] - 3)
; [wNorthConnectionStripLocation]
ld hl, wNorthConnectionStripLocation
ld a, [hli]
ld h, [hl]
ld l, a
; + (xcoord / 2)
srl d
ld b, 0
ld c, d
add hl, bc
; + ([wMapWidth] + 6) * {ycoord / 2 - ([wNorthConnectedMapHeight] - 3)} --> + ([wMapWidth] + 6) * e
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
ld a, e
and a
jr z, .done
.loop
add hl, bc
dec a
jr nz, .loop
.done
call ConvertConnectedOverworldMapBlockAddressToXYCoords
ret
.nope
xor a
ret ; nc
GetEastConnectedSpriteCoords:
; xcoord / 2 <= 2
ld a, d
srl a
cp 3
ret nc
; [wEastConnectionStripLocation]
ld hl, wEastConnectionStripLocation
ld a, [hli]
ld h, [hl]
ld l, a
; + (xcoord / 2)
srl d
ld b, 0
ld c, d
add hl, bc
; + ([wMapWidth] + 6) * ycoord / 2
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
srl e
ld a, e
and a
jr z, .done
.loop
add hl, bc
dec a
jr nz, .loop
.done
call ConvertConnectedOverworldMapBlockAddressToXYCoords
ret
GetWestConnectedSpriteCoords:
; wWestConnectedMapWidth >= 3
; xcoord / 2 >= ([wWestConnectedMapWidth] - 3)
ld a, [wWestConnectedMapWidth]
sub 3
jr c, .nope
ld c, a
ld a, d
srl a
sub c
jr c, .nope
ld d, a ; d = xcoord / 2 - ([wWestConnectedMapWidth] - 3)
; [wWestConnectionStripLocation]
ld hl, wWestConnectionStripLocation
ld a, [hli]
ld h, [hl]
ld l, a
; + xcoord / 2 - ([wWestConnectedMapWidth] - 3) --> + d
ld c, d
ld b, 0
add hl, bc
; + ([wMapWidth] + 6) * ycoord / 2
ld a, [wMapWidth]
add 6
ld c, a
ld b, 0
srl e
ld a, e
and a
jr z, .done
.loop
add hl, bc
dec a
jr nz, .loop
.done
call ConvertConnectedOverworldMapBlockAddressToXYCoords
ret
.nope
xor a
ret ; nc
; load into wPlayerMockYCoord and wPlayerMockXCoord the coordinates
; that correspond to wOverworldMapBlocks address at hl.
ConvertConnectedOverworldMapBlockAddressToXYCoords:
ld bc, -wOverworldMapBlocks + $10000
add hl, bc
ld a, [wMapWidth]
add 6
xor $ff
inc a
ld c, a
ld b, $ff
ld d, -2 ;
.calc_y_coord_loop
inc d ;
inc d ; each block in wOverworldMapBlocks occupies two half-blocks
add hl, bc
ld a, h
cp $ff
jr nz, .calc_y_coord_loop
; for X, we want the value of l in the second-to-last iteration of the previous loop,
; so undo the last iteration in l by adding [wMapWidth]+6 to it
ld a, [wMapWidth]
add 6
add l
add a ; each block in wOverworldMapBlocks occupies two half-blocks
; substract 6 tiles from y, substract 6 tiles from x.
; the '6's correspond to the 3 extra blocks in each margin of wOverworldMapBlocks.
sub 6
ld [wPlayerMockXCoord], a
ld a, d
sub 6
ld [wPlayerMockYCoord], a
call CheckPlayerMockSpriteOutOfScreen
ret ; c or nc
; return nc if either X or Y coord is too negative to be visible in the screen.
; this corresponds to half-block coords -5 and -6, which are visible by wOverworldMapBlocks,
; but not by the map sprite engine when it adds 4 to X and to Y to obtain wPlayerObject coords.
CheckPlayerMockSpriteOutOfScreen:
ld a, [wPlayerMockXCoord]
ld b, a
ld a, [wPlayerMockYCoord]
ld c, a
ld a, -5
cp b
ret z ; nc
cp c
ret z ; nc
dec a ; -6
cp b
ret z ; nc
cp c
ret z ; nc
scf
ret