ref: 3a7f518de4bbced15cbf5bb877a988055de7d063
dir: /engine/player_object.asm/
BlankScreen: ; 8000 call DisableSpriteUpdates xor a ld [hBGMapMode], a call ClearBGPalettes call ClearSprites hlcoord 0, 0 ld bc, TileMapEnd - TileMap ld a, " " call ByteFill hlcoord 0, 0, AttrMap ld bc, AttrMapEnd - AttrMap ld a, $7 call ByteFill call WaitBGMap2 call SetPalettes ret SpawnPlayer: ; 8029 ld a, -1 ld [wObjectFollow_Leader], a ld [wObjectFollow_Follower], a ld a, $0 ld hl, PlayerObjectTemplate call CopyPlayerObjectTemplate ld b, $0 call PlayerSpawn_ConvertCoords ld a, PLAYER_OBJECT call GetMapObject ld hl, MAPOBJECT_COLOR add hl, bc ln e, PAL_NPC_RED, OBJECTTYPE_SCRIPT ld a, [wPlayerSpriteSetupFlags] bit PLAYERSPRITESETUP_FEMALE_TO_MALE_F, a jr nz, .ok ld a, [wPlayerGender] bit PLAYERGENDER_FEMALE_F, a jr z, .ok ln e, PAL_NPC_BLUE, OBJECTTYPE_SCRIPT .ok ld [hl], e ld a, PLAYER_OBJECT ld [hMapObjectIndexBuffer], a ld bc, MapObjects ld a, PLAYER_OBJECT ld [hObjectStructIndexBuffer], a ld de, ObjectStructs call CopyMapObjectToObjectStruct ld a, PLAYER ld [wCenteredObject], a ret PlayerObjectTemplate: ; 8071 ; 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 CopyDECoordsToMapObject:: ; 807e 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 PlayerSpawn_ConvertCoords: ; 808f push bc ld a, [XCoord] add 4 ld d, a ld a, [YCoord] add 4 ld e, a pop bc call CopyDECoordsToMapObject ret WriteObjectXY:: ; 80a1 ld a, b call CheckObjectVisibility 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 a, [hMapObjectIndexBuffer] ld b, a call CopyDECoordsToMapObject and a ret RefreshPlayerCoords: ; 80b8 ld a, [XCoord] add 4 ld d, a ld hl, PlayerStandingMapX sub [hl] ld [hl], d ld hl, MapObjects + MAPOBJECT_X_COORD ld [hl], d ld hl, PlayerLastMapX ld [hl], d ld d, a ld a, [YCoord] add 4 ld e, a ld hl, PlayerStandingMapY sub [hl] ld [hl], e ld hl, MapObjects + MAPOBJECT_Y_COORD ld [hl], e ld hl, PlayerLastMapY ld [hl], e ld e, a ld a, [wObjectFollow_Leader] cp $0 ret nz ; wtf ret CopyObjectStruct:: ; 80e7 call CheckObjectMask and a ret nz ; masked ld hl, ObjectStructs + OBJECT_STRUCT_LENGTH * 1 ld a, 1 ld de, OBJECT_STRUCT_LENGTH .loop ld [hObjectStructIndexBuffer], a ld a, [hl] and a jr z, .done add hl, de ld a, [hObjectStructIndexBuffer] inc a cp NUM_OBJECT_STRUCTS jr nz, .loop scf ret ; overflow .done ld d, h ld e, l call CopyMapObjectToObjectStruct ld hl, VramState bit 7, [hl] ret z ld hl, OBJECT_FLAGS2 add hl, de set 5, [hl] ret CopyMapObjectToObjectStruct: ; 8116 call .CopyMapObjectToTempObject call CopyTempObjectToObjectStruct ret .CopyMapObjectToTempObject: ; 811d ld a, [hObjectStructIndexBuffer] ld hl, MAPOBJECT_OBJECT_STRUCT_ID add hl, bc ld [hl], a ld a, [hMapObjectIndexBuffer] 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_COLOR add hl, bc ld a, [hl] and $f0 jr z, .skip_color_override swap a and PALETTE_MASK ld [wTempObjectCopyPalette], a .skip_color_override ld hl, MAPOBJECT_MOVEMENT add hl, bc ld a, [hl] ld [wTempObjectCopyMovement], a ld hl, MAPOBJECT_RANGE 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 InitializeVisibleSprites: ; 8177 ld bc, MapObjects + OBJECT_LENGTH ld a, 1 .loop ld [hMapObjectIndexBuffer], a 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 ld a, [XCoord] ld d, a ld a, [YCoord] 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, OBJECT_LENGTH add hl, bc ld b, h ld c, l ld a, [hMapObjectIndexBuffer] inc a cp NUM_OBJECTS jr nz, .loop ret .ret ; 81c9 ret CheckObjectEnteringVisibleRange:: ; 81ca nop ld a, [wPlayerStepDirection] cp STANDING ret z ld hl, .dw rst JumpTable ret .dw ; 81d6 dw .Down dw .Up dw .Left dw .Right .Up: ; 81de ld a, [YCoord] sub 1 jr .Vertical .Down: ; 81e5 ld a, [YCoord] add 9 .Vertical: ; 81ea ld d, a ld a, [XCoord] ld e, a ld bc, MapObjects + OBJECT_LENGTH ld a, 1 .loop_v ld [hMapObjectIndexBuffer], a 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, OBJECT_LENGTH add hl, bc ld b, h ld c, l ld a, [hMapObjectIndexBuffer] inc a cp NUM_OBJECTS jr nz, .loop_v ret .Left: ; 8232 ld a, [XCoord] sub 1 jr .Horizontal .Right: ; 8239 ld a, [XCoord] add 10 .Horizontal: ; 823e ld e, a ld a, [YCoord] ld d, a ld bc, MapObjects + OBJECT_LENGTH ld a, 1 .loop_h ld [hMapObjectIndexBuffer], a 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, OBJECT_LENGTH add hl, bc ld b, h ld c, l ld a, [hMapObjectIndexBuffer] inc a cp NUM_OBJECTS jr nz, .loop_h ret CopyTempObjectToObjectStruct: ; 8286 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_00 ld hl, OBJECT_FACING_STEP 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 .InitYCoord: ; 82d5 ld hl, OBJECT_INIT_Y add hl, de ld [hl], a ld hl, OBJECT_NEXT_MAP_Y add hl, de ld [hl], a ld hl, YCoord sub [hl] and $f swap a ld hl, wPlayerBGMapOffsetY sub [hl] ld hl, OBJECT_SPRITE_Y add hl, de ld [hl], a ret .InitXCoord: ; 82f1 ld hl, OBJECT_INIT_X add hl, de ld [hl], a ld hl, OBJECT_NEXT_MAP_X add hl, de ld [hl], a ld hl, XCoord sub [hl] and $f swap a ld hl, wPlayerBGMapOffsetX sub [hl] ld hl, OBJECT_SPRITE_X add hl, de ld [hl], a ret .InitRadius: ; 830d 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 TrainerWalkToPlayer: ; 831e ld a, [hLastTalked] call InitMovementBuffer ld a, movement_step_sleep call AppendToMovementBuffer ld a, [wd03f] dec a jr z, .TerminateStep ld a, [hLastTalked] ld b, a ld c, PLAYER ld d, 1 call .GetPathToPlayer call DecrementMovementBufferCount .TerminateStep: ld a, movement_step_end call AppendToMovementBuffer ret .GetPathToPlayer: ; 8341 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_NEXT_MAP_X add hl, bc ld a, [hl] ld hl, OBJECT_NEXT_MAP_Y add hl, bc ld c, [hl] ld b, a ; get player coords, load to de ld hl, OBJECT_NEXT_MAP_X add hl, de ld a, [hl] ld hl, OBJECT_NEXT_MAP_Y add hl, de ld e, [hl] ld d, a pop af call ComputePathToWalkToPlayer ret Special_SurfStartStep: ; 8379 call InitMovementBuffer call .GetMovementData call AppendToMovementBuffer ld a, movement_step_end call AppendToMovementBuffer ret .GetMovementData: ; 8388 ld a, [PlayerDirection] srl a srl a maskbits NUM_DIRECTIONS ld e, a ld d, 0 ld hl, .movement_data add hl, de ld a, [hl] ret .movement_data slow_step DOWN slow_step UP slow_step LEFT slow_step RIGHT FollowNotExact:: ; 839e 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_NEXT_MAP_X add hl, bc ld a, [hl] ld hl, OBJECT_NEXT_MAP_Y add hl, bc ld c, [hl] ld b, a ld hl, OBJECT_NEXT_MAP_X 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_NEXT_MAP_Y 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_NEXT_MAP_X add hl, de ld [hl], b ld a, b ld hl, XCoord sub [hl] and $f swap a ld hl, wPlayerBGMapOffsetX sub [hl] ld hl, OBJECT_SPRITE_X add hl, de ld [hl], a ld hl, OBJECT_NEXT_MAP_Y add hl, de ld [hl], c ld a, c ld hl, YCoord sub [hl] and $f swap a ld hl, wPlayerBGMapOffsetY sub [hl] ld hl, OBJECT_SPRITE_Y add hl, de ld [hl], a ld a, [hObjectStructIndexBuffer] ld hl, OBJECT_RANGE add hl, de ld [hl], a ld hl, OBJECT_MOVEMENTTYPE add hl, de ld [hl], SPRITEMOVEDATA_FOLLOWNOTEXACT ld hl, OBJECT_STEP_TYPE add hl, de ld [hl], STEP_TYPE_00 ret GetRelativeFacing:: ; 8417 ; 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 .GetFacing_e_relativeto_d: ; 8439 ; 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_NEXT_MAP_X add hl, bc ld a, [hl] ld hl, OBJECT_NEXT_MAP_Y 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_NEXT_MAP_X add hl, bc ld d, [hl] ld hl, OBJECT_NEXT_MAP_Y 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 QueueFollowerFirstStep: ; 848a call .QueueFirstStep jr c, .same ld [wFollowMovementQueue], a xor a ld [wFollowerMovementQueueLength], a ret .same ld a, -1 ld [wFollowerMovementQueueLength], a ret .QueueFirstStep: ld a, [wObjectFollow_Leader] call GetObjectStruct 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 a, [wObjectFollow_Follower] call GetObjectStruct ld hl, OBJECT_NEXT_MAP_X add hl, bc ld a, d cp [hl] jr z, .check_y jr c, .left and a ld a, movement_step + RIGHT ret .left and a ld a, movement_step + LEFT ret .check_y ld hl, OBJECT_NEXT_MAP_Y add hl, bc ld a, e cp [hl] jr z, .same_xy jr c, .up and a ld a, movement_step + DOWN ret .up and a ld a, movement_step + UP ret .same_xy scf ret