diff options
Diffstat (limited to 'engine/overworld/map_objects.asm')
-rw-r--r-- | engine/overworld/map_objects.asm | 3123 |
1 files changed, 3123 insertions, 0 deletions
diff --git a/engine/overworld/map_objects.asm b/engine/overworld/map_objects.asm new file mode 100644 index 000000000..8d6f4082f --- /dev/null +++ b/engine/overworld/map_objects.asm @@ -0,0 +1,3123 @@ +INCLUDE "data/sprites/facings.asm" + +INCLUDE "data/sprites/map_objects.asm" + + +; 4357 +DeleteMapObject:: ; 4357 + push bc + ld hl, OBJECT_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + push af + ld h, b + ld l, c + ld bc, OBJECT_STRUCT_LENGTH + xor a + call ByteFill + pop af + cp -1 + jr z, .ok + bit 7, a + jr nz, .ok + call GetMapObject + ld hl, OBJECT_SPRITE + add hl, bc + ld [hl], -1 +.ok + pop bc + ret +; 437b + +Function437b: ; 437b + call .CheckObjectStillVisible + ret c + call .HandleStepType + call .HandleObjectAction + ret + +.CheckObjectStillVisible: + ld hl, OBJECT_FLAGS2 + add hl, bc + res 6, [hl] + ld a, [wXCoord] + ld e, a + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld a, [hl] + add 1 + sub e + jr c, .ok + cp MAPOBJECT_SCREEN_WIDTH + jr nc, .ok + ld a, [wYCoord] + ld e, a + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld a, [hl] + add 1 + sub e + jr c, .ok + cp MAPOBJECT_SCREEN_HEIGHT + jr nc, .ok + jr .yes + +.ok + ld hl, OBJECT_FLAGS2 + add hl, bc + set 6, [hl] + ld a, [wXCoord] + ld e, a + ld hl, OBJECT_INIT_X + add hl, bc + ld a, [hl] + add 1 + sub e + jr c, .ok2 + cp MAPOBJECT_SCREEN_WIDTH + jr nc, .ok2 + ld a, [wYCoord] + ld e, a + ld hl, OBJECT_INIT_Y + add hl, bc + ld a, [hl] + add 1 + sub e + jr c, .ok2 + cp MAPOBJECT_SCREEN_HEIGHT + jr nc, .ok2 +.yes + and a + ret + +.ok2 + ld hl, OBJECT_FLAGS1 + add hl, bc + bit 1, [hl] + jr nz, .yes2 + call DeleteMapObject + scf + ret + +.yes2 + ld hl, OBJECT_FLAGS2 + add hl, bc + set 6, [hl] + and a + ret + +.HandleStepType: + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld a, [hl] + and a + jr z, .zero + ld hl, OBJECT_FLAGS2 + add hl, bc + bit 5, [hl] + jr nz, .bit5 + cp STEP_TYPE_SLEEP + jr z, .one + jr .ok3 + +.zero + call ObjectMovementReset + ld hl, OBJECT_FLAGS2 + add hl, bc + bit 5, [hl] + jr nz, .bit5 +.one + call MapObjectMovementPattern + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld a, [hl] + and a + ret z + cp STEP_TYPE_SLEEP + ret z +.ok3 + ld hl, StepTypesJumptable + rst JumpTable + ret + +.bit5 + ret + +.HandleObjectAction: + ld hl, OBJECT_FLAGS1 + add hl, bc + bit INVISIBLE, [hl] + jr nz, SetFacingStanding + ld hl, OBJECT_FLAGS2 + add hl, bc + bit 6, [hl] + jr nz, SetFacingStanding + bit 5, [hl] + jr nz, asm_4448 + ld de, ObjectActionPairPointers ; use first column + jr _HandleObjectAction +; 4440 + +Function4440: ; 4440 + ld hl, OBJECT_FLAGS1 + add hl, bc + bit INVISIBLE, [hl] + jr nz, SetFacingStanding +asm_4448 + ld de, ObjectActionPairPointers + 2 ; use second column + jr _HandleObjectAction +; 444d + +_HandleObjectAction +; call [4 * wObjectStructs[ObjInd, OBJECT_ACTION] + de] + ld hl, OBJECT_ACTION + add hl, bc + ld a, [hl] + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + call _hl_ + ret +; 445f + +INCLUDE "engine/overworld/map_object_action.asm" + +CopyNextCoordsTileToStandingCoordsTile: ; 4600 + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld a, [hl] + ld hl, OBJECT_MAP_X + add hl, bc + ld [hl], a + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld a, [hl] + ld hl, OBJECT_MAP_Y + add hl, bc + ld [hl], a + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld a, [hl] + ld hl, OBJECT_STANDING_TILE + add hl, bc + ld [hl], a + call SetTallGrassFlags + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld a, [hl] + call UselessAndA + ret +; 462a + +Function462a: ; 462a + ld hl, OBJECT_MAP_X + add hl, bc + ld a, [hl] + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld [hl], a + ld hl, OBJECT_MAP_Y + add hl, bc + ld a, [hl] + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld [hl], a + ret +; 463f + +UpdateTallGrassFlags: ; 463f + ld hl, OBJECT_FLAGS2 + add hl, bc + bit OVERHEAD, [hl] + jr z, .ok + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld a, [hl] + call SetTallGrassFlags +.ok + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld a, [hl] + call UselessAndA + ret c ; never happens + ld hl, OBJECT_STANDING_TILE + add hl, bc + ld a, [hl] + call UselessAndA + ret +; 4661 + +SetTallGrassFlags: ; 4661 + call CheckSuperTallGrassTile + jr z, .set + call CheckGrassTile + jr c, .reset +.set + ld hl, OBJECT_FLAGS2 + add hl, bc + set OVERHEAD, [hl] + ret + +.reset + ld hl, OBJECT_FLAGS2 + add hl, bc + res OVERHEAD, [hl] + ret +; 4679 + +UselessAndA: ; 4679 + and a + ret +; 467b + +EndSpriteMovement: ; 467b + xor a + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], a + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a ; OBJECT_1E + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ret +; 4690 + +InitStep: ; 4690 + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], a + ld hl, OBJECT_FLAGS1 + add hl, bc + bit FIXED_FACING, [hl] + jr nz, GetNextTile + add a + add a + and %00001100 + ld hl, OBJECT_FACING + add hl, bc + ld [hl], a +GetNextTile: ; 46a6 + call GetStepVector + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld a, d + call GetStepVectorSign + ld hl, OBJECT_MAP_X + add hl, bc + add [hl] + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld [hl], a + ld d, a + ld a, e + call GetStepVectorSign + ld hl, OBJECT_MAP_Y + add hl, bc + add [hl] + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld [hl], a + ld e, a + push bc + call GetCoordTile + pop bc + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld [hl], a + ret +; 46d7 + +AddStepVector: ; 46d7 + call GetStepVector + ld hl, OBJECT_SPRITE_X + add hl, bc + ld a, [hl] + add d + ld [hl], a + ld hl, OBJECT_SPRITE_Y + add hl, bc + ld a, [hl] + add e + ld [hl], a + ret +; 46e9 + +GetStepVector: ; 46e9 +; Return (x, y, duration, speed) in (d, e, a, h). + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld a, [hl] + and %00001111 + add a + add a + ld l, a + ld h, 0 + ld de, StepVectors + add hl, de + ld d, [hl] + inc hl + ld e, [hl] + inc hl + ld a, [hli] + ld h, [hl] + ret +; 4700 + +StepVectors: ; 4700 +; x, y, duration, speed + ; slow + db 0, 1, 16, 1 + db 0, -1, 16, 1 + db -1, 0, 16, 1 + db 1, 0, 16, 1 + ; normal + db 0, 2, 8, 2 + db 0, -2, 8, 2 + db -2, 0, 8, 2 + db 2, 0, 8, 2 + ; fast + db 0, 4, 4, 4 + db 0, -4, 4, 4 + db -4, 0, 4, 4 + db 4, 0, 4, 4 +; 4730 + +GetStepVectorSign: ; 4730 + add a + ret z ; 0 or 128 + ld a, 1 + ret nc ; 1 - 127 + ld a, -1 + ret ; 129 - 255 +; 4738 + +UpdatePlayerStep: ; 4738 + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld a, [hl] + and %00000011 + ld [wPlayerStepDirection], a + call AddStepVector + ld a, [wPlayerStepVectorX] + add d + ld [wPlayerStepVectorX], a + ld a, [wPlayerStepVectorY] + add e + ld [wPlayerStepVectorY], a + ld hl, wPlayerStepFlags + set 5, [hl] + ret +; 4759 + +Unreferenced_Function4759: ; 4759 + push bc + ld e, a + ld d, 0 + ld hl, OBJECT_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + call GetMapObject + add hl, de + ld a, [hl] + pop bc + ret +; 4769 + +RestoreDefaultMovement: ; 4769 + ld hl, OBJECT_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + cp -1 + jr z, .ok + push bc + call GetMapObject + ld hl, MAPOBJECT_MOVEMENT + add hl, bc + ld a, [hl] + pop bc + ret + +.ok + ld a, SPRITEMOVEFN_STANDING + ret +; 4780 + +ClearObjectMovementByteIndex: ; 4780 + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + ld [hl], 0 + ret +; 4787 + +IncrementObjectMovementByteIndex: ; 4787 + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + inc [hl] + ret +; 478d + +DecrementObjectMovementByteIndex: ; 478d + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + dec [hl] + ret +; 4793 + +MovementAnonymousJumptable: ; 4793 + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + ld a, [hl] + pop hl + rst JumpTable + ret +; 479b + +ClearObjectStructField1c: ; 479b + ld hl, OBJECT_1C + add hl, bc + ld [hl], 0 + ret +; 47a2 + +IncrementObjectStructField1c: ; 47a2 + ld hl, OBJECT_1C + add hl, bc + inc [hl] + ret +; 47a8 + +Field1cAnonymousJumptable: ; 47a8 + ld hl, OBJECT_1C + add hl, bc + ld a, [hl] + pop hl + rst JumpTable + ret +; 47b0 + +GetValueObjectStructField1c: ; 47b0 + ld hl, OBJECT_1C + add hl, bc + ld a, [hl] + ret +; 47b6 + +SetValueObjectStructField1c: ; 47b6 + ld hl, OBJECT_1C + add hl, bc + ld [hl], a + ret +; 47bc + +ObjectMovementReset: ; 47bc + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld d, [hl] + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld e, [hl] + push bc + call GetCoordTile + pop bc + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld [hl], a + call CopyNextCoordsTileToStandingCoordsTile + call EndSpriteMovement + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 47dd + +MapObjectMovementPattern: ; 47dd + call ClearObjectStructField1c + call GetSpriteMovementFunction + ld a, [hl] + ld hl, .Pointers + rst JumpTable + ret + +.Pointers: ; 47e9 +; entries correspond to SPRITEMOVEFN_* constants + dw .Null_00 ; 00 + dw .RandomWalkY ; 01 + dw .RandomWalkX ; 02 + dw .RandomWalkXY ; 03 + dw .RandomSpin1 ; 04 + dw .RandomSpin2 ; 05 + dw .Standing ; 06 + dw .ObeyDPad ; 07 + dw .Movement08 ; 08 + dw .Movement09 ; 09 + dw .Movement0a ; 0a + dw .Movement0b ; 0b + dw .Movement0c ; 0c + dw .Movement0d ; 0d + dw .Movement0e ; 0e + dw .Follow ; 0f + dw .Script ; 10 + dw .Strength ; 11 + dw .FollowNotExact ; 12 + dw .MovementShadow ; 13 + dw .MovementEmote ; 14 + dw .MovementBigStanding ; 15 + dw .MovementBouncing ; 16 + dw .MovementScreenShake ; 17 + dw .MovementSpinClockwise ; 18 + dw .MovementSpinCounterclockwise ; 19 + dw .MovementBoulderDust ; 1a + dw .MovementShakingGrass ; 1b + +.Null_00: + ret + +.RandomWalkY: + call Random + ld a, [hRandomAdd] + and %00000001 + jp .RandomWalkContinue + +.RandomWalkX: + call Random + ld a, [hRandomAdd] + and %00000001 + or %00000010 + jp .RandomWalkContinue + +.RandomWalkXY: + call Random + ld a, [hRandomAdd] + and %00000011 + jp .RandomWalkContinue + +.RandomSpin1: + call Random + ld a, [hRandomAdd] + and %00001100 + ld hl, OBJECT_FACING + add hl, bc + ld [hl], a + jp RandomStepDuration_Slow + +.RandomSpin2: + ld hl, OBJECT_FACING + add hl, bc + ld a, [hl] + and %00001100 + ld d, a + call Random + ld a, [hRandomAdd] + and %00001100 + cp d + jr nz, .keep + xor %00001100 +.keep + ld [hl], a + jp RandomStepDuration_Fast + +.Standing: + call Function462a + call EndSpriteMovement + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STAND + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_05 + ret + +.ObeyDPad: + ld hl, Function5000 + jp HandleMovementData + +.Movement08: + ld hl, Function5015 + jp HandleMovementData + +.Movement09: + ld hl, Function5026 + jp HandleMovementData + +.Movement0a: + jp _GetMovementObject + +.Movement0b: + jp _GetMovementObject + +.Movement0c: + jp _GetMovementObject + +.Movement0d: + ld hl, Function5000 + jp HandleMovementData + +.Movement0e: + jp _GetMovementObject + +.Follow: + ld hl, GetFollowerNextMovementByte + jp HandleMovementData + +.Script: + ld hl, GetMovementByte + jp HandleMovementData + +.Strength: + call MovementAnonymousJumptable + dw .Strength_Start + dw .Strength_Stop + +.Strength_Start: + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld a, [hl] + call CheckPitTile + jr z, .on_pit + ld hl, OBJECT_FLAGS2 + add hl, bc + bit 2, [hl] + res 2, [hl] + jr z, .ok + ld hl, OBJECT_RANGE + add hl, bc + ld a, [hl] + and %00000011 + or 0 + call InitStep + call Function6ec1 + jr c, .ok2 + ld de, SFX_STRENGTH + call PlaySFX + call SpawnStrengthBoulderDust + call UpdateTallGrassFlags + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_0F + ret + +.ok2 + call Function462a +.ok + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ret + +.on_pit + call IncrementObjectMovementByteIndex +.Strength_Stop: + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ret + +.FollowNotExact: + 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_RANGE + add hl, bc + ld a, [hl] + push bc + call GetObjectStruct + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld a, [hl] + cp STANDING + jr z, .standing + ld hl, OBJECT_MAP_X + add hl, bc + ld a, [hl] + cp d + jr z, .equal + jr c, .less + ld a, 3 + jr .done + +.less + ld a, 2 + jr .done + +.equal + ld hl, OBJECT_MAP_Y + add hl, bc + ld a, [hl] + cp e + jr z, .standing + jr c, .less2 + ld a, 0 + jr .done + +.less2 + ld a, 1 +.done + ld d, a + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld a, [hl] + and %00001100 + or d + pop bc + jp NormalStep + +.standing + pop bc + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STAND + ret + +.MovementBigStanding: + call EndSpriteMovement + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_BIG_DOLL_SYM + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_04 + ret + +.MovementBouncing: + call EndSpriteMovement + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_BOUNCE + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_04 + ret + +.MovementSpinCounterclockwise: + call MovementAnonymousJumptable + dw .MovementSpinInit + dw .MovementSpinRepeat + dw .MovementSpinTurnLeft + +.MovementSpinClockwise: + call MovementAnonymousJumptable + dw .MovementSpinInit + dw .MovementSpinRepeat + dw .MovementSpinTurnRight + +.MovementSpinInit: + call EndSpriteMovement + call IncrementObjectMovementByteIndex +.MovementSpinRepeat: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STAND + ld hl, OBJECT_RANGE + add hl, bc + ld a, [hl] + ld a, $10 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_03 + call IncrementObjectMovementByteIndex + ret + +.MovementSpinTurnLeft: + ld de, .DirectionData_Counterclockwise + call .MovementSpinNextFacing + jr .MovementSpinCounterclockwise + +.DirectionData_Counterclockwise: ; 49c0 + db OW_RIGHT, OW_LEFT, OW_DOWN, OW_UP + +.MovementSpinTurnRight: + ld de, .DirectionData_Clockwise + call .MovementSpinNextFacing + jr .MovementSpinClockwise + +.DirectionData_Clockwise: ; 49cc + db OW_LEFT, OW_RIGHT, OW_UP, OW_DOWN + +.MovementSpinNextFacing: + ld hl, OBJECT_FACING + add hl, bc + ld a, [hl] + and %00001100 + rrca + rrca + push hl + ld l, a + ld h, 0 + add hl, de + ld a, [hl] + pop hl + ld [hl], a + call DecrementObjectMovementByteIndex + ret + +.MovementShadow: + call ._MovementShadow_Grass_Emote_BoulderDust + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SHADOW + ld hl, OBJECT_STEP_DURATION + add hl, de + ld a, [hl] + inc a + add a + add 0 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld hl, OBJECT_DIRECTION_WALKING + add hl, de + ld a, [hl] + maskbits NUM_DIRECTIONS + ld d, 1 * 8 + 6 + cp DOWN + jr z, .ok_13 + cp UP + jr z, .ok_13 + ld d, 1 * 8 + 4 +.ok_13 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], d + ld hl, OBJECT_SPRITE_X_OFFSET + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_TRACKING_OBJECT + ret + +.MovementEmote: + call EndSpriteMovement + call ._MovementShadow_Grass_Emote_BoulderDust + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_EMOTE + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 0 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], -2 * 8 + ld hl, OBJECT_SPRITE_X_OFFSET + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_TRACKING_OBJECT + ret + +.MovementBoulderDust: + call EndSpriteMovement + call ._MovementShadow_Grass_Emote_BoulderDust + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_BOULDER_DUST + ld hl, OBJECT_STEP_DURATION + add hl, de + ld a, [hl] + inc a + add a + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld hl, OBJECT_DIRECTION_WALKING + add hl, de + ld a, [hl] + and %00000011 + ld e, a + ld d, 0 + ld hl, .data_4a81 + add hl, de + add hl, de + ld d, [hl] + inc hl + ld e, [hl] + ld hl, OBJECT_SPRITE_X_OFFSET + add hl, bc + ld [hl], d + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], e + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_TRACKING_OBJECT + ret + +.data_4a81 ; 4a81 + ; x, y + db 0, -4 + db 0, 8 + db 6, 2 + db -6, 2 + +.MovementShakingGrass: + call EndSpriteMovement + call ._MovementShadow_Grass_Emote_BoulderDust + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_GRASS_SHAKE + ld hl, OBJECT_STEP_DURATION + add hl, de + ld a, [hl] + add -1 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_TRACKING_OBJECT + ret + +._MovementShadow_Grass_Emote_BoulderDust: + ld hl, OBJECT_RANGE + add hl, bc + ld a, [hl] + push bc + call GetObjectStruct + ld d, b + ld e, c + pop bc + ld hl, OBJECT_1D + add hl, bc + ld [hl], e + inc hl + ld [hl], d + ret + +.MovementScreenShake: + call EndSpriteMovement + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_00 + ld hl, OBJECT_RANGE + add hl, bc + ld a, [hl] + call ._MovementScreenShake + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], e + ld hl, OBJECT_1E + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_15 + ret + +._MovementScreenShake: + ld d, a + and %00111111 + ld e, a + ld a, d + rlca + rlca + and %00000011 + ld d, a + inc d + ld a, 1 +.loop + dec d + ret z + add a + jr .loop + +.RandomWalkContinue: + call InitStep + call Function6ec1 ; check whether the object can move in that direction + jr c, .NewDuration + call UpdateTallGrassFlags + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STEP + ld hl, wCenteredObject + ld a, [hMapObjectIndexBuffer] + cp [hl] + jr z, .load_6 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_07 + ret + +.load_6 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_PLAYER_WALK + ret + +.NewDuration: + call EndSpriteMovement + call Function462a +RandomStepDuration_Slow: ; 4b1d + call Random + ld a, [hRandomAdd] + and %01111111 + jr SetRandomStepDuration +; 4b26 + +RandomStepDuration_Fast: ; 4b26 + call Random + ld a, [hRandomAdd] + and %00011111 +SetRandomStepDuration: ; 4b2d + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], a + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STAND + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_03 + ret +; 4b45 + +StepTypesJumptable: ; 4b45 +; entries correspond to STEP_TYPE_* constants + dw ObjectMovementReset ; 00 + dw MapObjectMovementPattern ; 01 + dw NPCStep ; 02 + dw StepType03 ; 03 + dw StepType04 ; 04 + dw StepType05 ; 05 + dw PlayerStep ; 06 + dw StepType07 ; 07 + dw NPCJump ; 08 + dw PlayerJump ; 09 + dw PlayerOrNPCTurnStep ; 0a + dw StepTypeBump ; 0b + dw TeleportFrom ; 0c + dw TeleportTo ; 0d + dw Skyfall ; 0e + dw StepType0f ; 0f + dw GotBiteStep ; 10 + dw RockSmashStep ; 11 + dw ReturnDigStep ; 12 + dw StepTypeTrackingObject ; 13 + dw StepType14 ; 14 + dw StepType15 ; 15 + dw StepType16 ; 16 + dw StepType17 ; 17 + dw StepType18 ; 18 + dw SkyfallTop ; 19 +; 4b79 + +WaitStep_InPlace: ; 4b79 + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4b86 + +NPCJump: ; 4b86 + call Field1cAnonymousJumptable +; anonymous dw + dw .Jump + dw .Land + +.Jump: + call AddStepVector + call UpdateJumpPosition + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call CopyNextCoordsTileToStandingCoordsTile + call GetNextTile + ld hl, OBJECT_FLAGS2 + add hl, bc + res 3, [hl] + call IncrementObjectStructField1c + ret + +.Land: + call AddStepVector + call UpdateJumpPosition + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4bbf + +PlayerJump: ; 4bbf + call Field1cAnonymousJumptable +; anonymous dw + dw .initjump + dw .stepjump + dw .initland + dw .stepland + +.initjump + ld hl, wPlayerStepFlags + set 7, [hl] + call IncrementObjectStructField1c +.stepjump + call UpdateJumpPosition + call UpdatePlayerStep + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_FLAGS2 + add hl, bc + res 3, [hl] + ld hl, wPlayerStepFlags + set 6, [hl] + set 4, [hl] + call IncrementObjectStructField1c + ret + +.initland + call GetNextTile + ld hl, wPlayerStepFlags + set 7, [hl] + call IncrementObjectStructField1c +.stepland + call UpdateJumpPosition + call UpdatePlayerStep + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, wPlayerStepFlags + set 6, [hl] + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4c18 + +TeleportFrom: ; 4c18 + call Field1cAnonymousJumptable +; anonymous dw + dw .InitSpin + dw .DoSpin + dw .InitSpinRise + dw .DoSpinRise +; 4c23 + +.InitSpin: + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c +.DoSpin: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SPIN + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call IncrementObjectStructField1c + ret + +.InitSpinRise: + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_1F + add hl, bc + ld [hl], $10 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + ld hl, OBJECT_FLAGS2 + add hl, bc + res 3, [hl] + call IncrementObjectStructField1c +.DoSpinRise: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SPIN + ld hl, OBJECT_1F + add hl, bc + inc [hl] + ld a, [hl] + ld d, $60 + call Sine + ld a, h + sub $60 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4c89 + +TeleportTo: ; 4c89 + call Field1cAnonymousJumptable +; anonymous dw + dw .InitWait + dw .DoWait + dw .InitDescent + dw .DoDescent + dw .InitFinalSpin + dw .DoFinalSpin + dw .FinishStep +; 4c9a + +.InitWait: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_00 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c + ret +; 4caa + +.DoWait: + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call IncrementObjectStructField1c +.InitDescent: + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_1F + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c + ret +; 4cc9 + +.DoDescent: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SPIN + ld hl, OBJECT_1F + add hl, bc + inc [hl] + ld a, [hl] + ld d, $60 + call Sine + ld a, h + sub $60 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call IncrementObjectStructField1c +.InitFinalSpin: + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c + ret +; 4cf5 + +.DoFinalSpin: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SPIN + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz +.FinishStep: + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4d14 + +Skyfall: ; 4d14 + call Field1cAnonymousJumptable +; anonymous dw + dw .Init + dw .Step + dw .Fall + dw .Finish +; 4d1f + +.Init: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_00 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c +.Step: + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_STEP + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_1F + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c +.Fall: + ld hl, OBJECT_1F + add hl, bc + inc [hl] + ld a, [hl] + ld d, $60 + call Sine + ld a, h + sub $60 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call IncrementObjectStructField1c +.Finish: + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4d7e + +GotBiteStep: ; 4d7e + call Field1cAnonymousJumptable +; anonymous dw + dw .Init + dw .Run +; 4d85 + +.Init: + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 8 + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], 0 + call IncrementObjectStructField1c +.Run: + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld a, [hl] + xor 1 + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4daf + +RockSmashStep: ; 4daf + call .Step + jp WaitStep_InPlace +; 4db5 + +.Step: + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld a, [hl] + and %00000001 + ld a, OBJECT_ACTION_STAND + jr z, .yes + ld a, OBJECT_ACTION_00 +.yes + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], a + ret +; 4dc8 + +ReturnDigStep: ; 4dc8 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld a, [hl] + and %00000001 + ld a, OBJECT_ACTION_SPIN + jr z, .yes + ld a, OBJECT_ACTION_SPIN_FLICKER +.yes + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], a + jp WaitStep_InPlace +; 4ddd + +StepType03: ; 4ddd + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4df0 + +StepType18: ; 4df0 + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + jp DeleteMapObject +; 4dff + +StepTypeBump: ; 4dff + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4e0c + +StepType05: ; 4e0c + call Field1cAnonymousJumptable +; anonymous dw + dw .Reset + dw StepType04 + +.Reset: + call RestoreDefaultMovement + call GetInitialFacing + ld hl, OBJECT_FACING + add hl, bc + ld [hl], a + call IncrementObjectStructField1c +StepType04: ; 4e21 + call Stubbed_Function4fb2 + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ret +; 4e2b + +NPCStep: ; 4e2b + call Stubbed_Function4fb2 + call AddStepVector + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4e47 + +StepType07: ; 4e47 + call AddStepVector + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call CopyNextCoordsTileToStandingCoordsTile + jp RandomStepDuration_Slow +; 4e56 + +PlayerStep: ; 4e56 +; AnimateStep? + call Field1cAnonymousJumptable +; anonymous dw + dw .init + dw .step + +.init + ld hl, wPlayerStepFlags + set 7, [hl] + call IncrementObjectStructField1c +.step + call UpdatePlayerStep + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, wPlayerStepFlags + set 6, [hl] + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4e83 + +PlayerOrNPCTurnStep: ; 4e83 + call Field1cAnonymousJumptable +; anonymous dw + dw .init1 + dw .step1 + dw .init2 + dw .step2 + +.init1 + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld a, [hl] + ld [hl], 2 + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 2 + call IncrementObjectStructField1c +.step1 + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + call IncrementObjectStructField1c +.init2 + ld hl, OBJECT_1D ; new facing + add hl, bc + ld a, [hl] + ld hl, OBJECT_FACING + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 2 + call IncrementObjectStructField1c +.step2 + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4ecd + +StepType0f: ; 4ecd + call AddStepVector + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + push bc + 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_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + ld b, a + farcall CopyDECoordsToMapObject + pop bc + ld hl, OBJECT_FLAGS2 + add hl, bc + res 2, [hl] + call CopyNextCoordsTileToStandingCoordsTile + ld hl, OBJECT_DIRECTION_WALKING + add hl, bc + ld [hl], STANDING + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4f04 + +StepTypeTrackingObject: ; 4f04 + ld hl, OBJECT_1D + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + ld hl, OBJECT_SPRITE + add hl, de + ld a, [hl] + and a + jr z, .nope + ld hl, OBJECT_SPRITE_X + add hl, de + ld a, [hl] + ld hl, OBJECT_SPRITE_X + add hl, bc + ld [hl], a + ld hl, OBJECT_SPRITE_Y + add hl, de + ld a, [hl] + ld hl, OBJECT_SPRITE_Y + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld a, [hl] + and a + ret z + dec [hl] + ret nz +.nope + jp DeleteMapObject +; 4f33 + +StepType14: ; 4f33 +StepType15: ; 4f33 + call Field1cAnonymousJumptable +; anonymous dw + dw .Init + dw .Run + +.Init: + xor a + ld hl, OBJECT_1D + add hl, bc + ld [hl], a + call IncrementObjectStructField1c +.Run: + ld hl, OBJECT_1D + add hl, bc + ld d, [hl] + ld a, [wPlayerStepVectorY] + sub d + ld [wPlayerStepVectorY], a + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + jr z, .ok + ld a, [hl] + call .GetSign + ld hl, OBJECT_1D + add hl, bc + ld [hl], a + ld d, a + ld a, [wPlayerStepVectorY] + add d + ld [wPlayerStepVectorY], a + ret + +.ok + call DeleteMapObject + ret + +.GetSign: + ld hl, OBJECT_1E + add hl, bc + and 1 + ld a, [hl] + ret z + cpl + inc a + ret +; 4f77 + +StepType16: ; 4f77 + call Field1cAnonymousJumptable ; ???? +; 4f7a +StepType17: ; 4f7a + call Field1cAnonymousJumptable +; anonymous dw + dw .null + dw .null + dw .null +.null +; 4f83 + +SkyfallTop: ; 4f83 + call Field1cAnonymousJumptable +; anonymous dw + dw .Init + dw .Run + +.Init: + ld hl, OBJECT_ACTION + add hl, bc + ld [hl], OBJECT_ACTION_SKYFALL + ld hl, OBJECT_STEP_DURATION + add hl, bc + ld [hl], 16 + call IncrementObjectStructField1c + +.Run: + ld hl, OBJECT_STEP_DURATION + add hl, bc + dec [hl] + ret nz + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], $60 + ld hl, OBJECT_STEP_FRAME + add hl, bc + ld [hl], 0 + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_SLEEP + ret +; 4fb2 + +Stubbed_Function4fb2: + ret + ld hl, OBJECT_1D + add hl, bc + inc [hl] + ld a, [hl] + srl a + srl a + and %00000111 + ld l, a + ld h, 0 + ld de, .y + add hl, de + ld a, [hl] + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], a + ret + +.y ; 4fcd + db 0, -1, -2, -3, -4, -3, -2, -1 +; 4fd5 +UpdateJumpPosition: ; 4fd5 + call GetStepVector + ld a, h + ld hl, OBJECT_1F + add hl, bc + ld e, [hl] + add e + ld [hl], a + nop + srl e + ld d, 0 + ld hl, .y + add hl, de + ld a, [hl] + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld [hl], a + ret + +.y ; 4ff0 + db -4, -6, -8, -10, -11, -12, -12, -12 + db -11, -10, -9, -8, -6, -4, 0, 0 +; 5000 +Function5000: ; unscripted? +; copy [wPlayerNextMovement] to [wPlayerMovement] + ld a, [wPlayerNextMovement] + ld hl, wPlayerMovement + ld [hl], a +; load [wPlayerNextMovement] with movement_step_sleep + ld a, movement_step_sleep + ld [wPlayerNextMovement], a +; recover the previous value of [wPlayerNextMovement] + ld a, [hl] + ret +; 500e + +GetMovementByte: + ld hl, wMovementDataPointer + call _GetMovementByte + ret +; 5015 + +Function5015: ; 5015 + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + ld e, [hl] + inc [hl] + ld d, 0 + ld hl, wc2e2 + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + ld a, [hl] + ret +; 5026 + +Function5026: ; 5026 + ld hl, OBJECT_MOVEMENT_BYTE_INDEX + add hl, bc + ld e, [hl] + inc [hl] + ld d, 0 + ld hl, wc2e6 + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + ld a, [hl] + ret +; 5037 + +_GetMovementObject: ; 5037 + ld hl, GetMovementObject + jp HandleMovementData +; 503d + +GetMovementObject: ; 503d + ld a, [wMovementObject] + ret +; 5041 + +HandleMovementData: ; 5041 + call .StorePointer +.loop + xor a + ld [wMovementByteWasControlSwitch], a + call JumpMovementPointer + call DoMovementFunction + ld a, [wMovementByteWasControlSwitch] + and a + jr nz, .loop + ret + +.StorePointer: + ld a, l + ld [wMovementPointer], a + ld a, h + ld [wMovementPointer + 1], a + ret +; 505e + +JumpMovementPointer: ; 505e + ld hl, wMovementPointer + ld a, [hli] + ld h, [hl] + ld l, a + jp hl +; 5065 + +ContinueReadingMovement: ; 5065 + ld a, 1 + ld [wMovementByteWasControlSwitch], a + ret +; 506b + +DoMovementFunction: ; 506b + push af + call ApplyMovementToFollower + pop af + ld hl, MovementPointers + rst JumpTable + ret +; 5075 + +INCLUDE "engine/overworld/movement.asm" +; 54b8 + +ApplyMovementToFollower: ; 54b8 + ld e, a + ld a, [wObjectFollow_Follower] + cp -1 + ret z + ld a, [wObjectFollow_Leader] + ld d, a + ld a, [hMapObjectIndexBuffer] + cp d + ret nz + ld a, e + cp movement_step_sleep + ret z + cp movement_step_end + ret z + cp movement_step_4b + ret z + cp movement_step_bump + ret z + cp movement_slow_step + ret c + push af + ld hl, wFollowerMovementQueueLength + inc [hl] + ld e, [hl] + ld d, 0 + ld hl, wFollowMovementQueue + add hl, de + pop af + ld [hl], a + ret +; 54e6 + +GetFollowerNextMovementByte: ; 54e6 + ld hl, wFollowerMovementQueueLength + ld a, [hl] + and a + jr z, .done + cp -1 + jr z, .done + dec [hl] + ld e, a + ld d, 0 + ld hl, wFollowMovementQueue + add hl, de + inc e + ld a, -1 +.loop + ld d, [hl] + ld [hld], a + ld a, d + dec e + jr nz, .loop + ret + +.done + call .CancelFollowIfLeaderMissing + ret c + ld a, movement_step_sleep + ret + +.CancelFollowIfLeaderMissing: + ld a, [wObjectFollow_Leader] + cp -1 + jr z, .nope + push bc + call GetObjectStruct + ld hl, OBJECT_SPRITE + add hl, bc + ld a, [hl] + pop bc + and a + jr z, .nope + and a + ret + +.nope + ld a, -1 + ld [wObjectFollow_Follower], a + ld a, movement_step_end + scf + ret +; 5529 + +SpawnShadow: ; 5529 + push bc + ld de, .ShadowObject + call CopyTempObjectData + call InitTempObject + pop bc + ret + +.ShadowObject: + ; vtile, palette, movement + db $00, PAL_OW_SILVER, SPRITEMOVEDATA_SHADOW +; 5538 + +SpawnStrengthBoulderDust: ; 5538 + push bc + ld de, .BoulderDustObject + call CopyTempObjectData + call InitTempObject + pop bc + ret + +.BoulderDustObject: + db $00, PAL_OW_SILVER, SPRITEMOVEDATA_BOULDERDUST +; 5547 + +SpawnEmote: ; 5547 + push bc + ld de, .EmoteObject + call CopyTempObjectData + call InitTempObject + pop bc + ret + +.EmoteObject: + db $00, PAL_OW_SILVER, SPRITEMOVEDATA_EMOTE +; 5556 + +ShakeGrass: ; 5556 + push bc + ld de, .data_5562 + call CopyTempObjectData + call InitTempObject + pop bc + ret + +.data_5562 + db $00, PAL_OW_TREE, SPRITEMOVEDATA_GRASS +; 5565 + +ShakeScreen: ; 5565 + push bc + push af + ld de, .ScreenShakeObject + call CopyTempObjectData + pop af + ld [wTempObjectCopyRange], a + call InitTempObject + pop bc + ret + +.ScreenShakeObject: + db $00, PAL_OW_SILVER, SPRITEMOVEDATA_SCREENSHAKE +; 5579 +DespawnEmote: ; 5579 + push bc + ld a, [hMapObjectIndexBuffer] + ld c, a + call .DeleteEmote + pop bc + ret + +.DeleteEmote: + ld de, wObjectStructs + ld a, NUM_OBJECT_STRUCTS +.loop + push af + ld hl, OBJECT_FLAGS1 + add hl, de + bit EMOTE_OBJECT, [hl] + jr z, .next + ld hl, OBJECT_SPRITE + add hl, de + ld a, [hl] + and a + jr z, .next + push bc + xor a + ld bc, OBJECT_STRUCT_LENGTH + call ByteFill + pop bc +.next + ld hl, OBJECT_STRUCT_LENGTH + add hl, de + ld d, h + ld e, l + pop af + dec a + jr nz, .loop + ret +; 55ac + +InitTempObject: ; 55ac + call FindFirstEmptyObjectStruct + ret nc + ld d, h + ld e, l + farcall CopyTempObjectToObjectStruct + ret +; 55b9 + +CopyTempObjectData: ; 55b9 +; load into wTempObjectCopy: +; -1, -1, [de], [de + 1], [de + 2], [hMapObjectIndexBuffer], [NextMapX], [NextMapY], -1 +; This spawns the object at the same place as whichever object is loaded into bc. + ld hl, wTempObjectCopyMapObjectIndex + ld [hl], -1 + inc hl + ld [hl], -1 + inc hl + ld a, [de] + inc de + ld [hli], a + ld a, [de] + inc de + ld [hli], a + ld a, [de] + ld [hli], a + ld a, [hMapObjectIndexBuffer] + ld [hli], a + push hl + 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 hl + ld [hl], d + inc hl + ld [hl], e + inc hl + ld [hl], -1 + ret +; 55e0 + +Function55e0:: ; 55e0 + ld a, [wVramState] + bit 0, a + ret z + ld bc, wObjectStructs + xor a +.loop + ld [hMapObjectIndexBuffer], a + call DoesObjectHaveASprite + jr z, .ok + call Function565c +.ok + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + ld a, [hMapObjectIndexBuffer] + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + ret +; 5602 + +Function5602: ; 5602, called at battle start + call Function5645 ; clear sprites + ld a, PLAYER + call Function5629 ; respawn player + ld a, [wBattleScriptFlags] + bit 7, a + jr z, .ok + ld a, [hLastTalked] + and a + jr z, .ok + call Function5629 ; respawn opponent +.ok + call _UpdateSprites + ret +; 561d + +Function561d: ; 561d + call Function5645 ; clear sprites + ld a, PLAYER + call Function5629 ; respawn player + call _UpdateSprites + ret +; 5629 + +Function5629: ; 5629 + cp NUM_OBJECTS + ret nc + call GetMapObject + ld hl, MAPOBJECT_OBJECT_STRUCT_ID + add hl, bc + ld a, [hl] + cp -1 + ret z + cp NUM_OBJECT_STRUCTS + ret nc + call GetObjectStruct + call DoesObjectHaveASprite + ret z + call Function5673 + ret +; 5645 + +Function5645: ; 5645 + xor a + ld bc, wObjectStructs +.loop + ld [hMapObjectIndexBuffer], a + call SetFacing_Standing + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + ld a, [hMapObjectIndexBuffer] + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + ret +; 565c + +Function565c: ; 565c + push bc + call Function56cd + pop bc + jr c, SetFacing_Standing + call Function56a3 + jr c, SetFacing_Standing + call Function5688 + farcall Function4440 + xor a + ret +; 5673 + +Function5673: ; 5673 + call Function56a3 + jr c, SetFacing_Standing + farcall Function4440 ; no need to farcall + xor a + ret +; 5680 + +SetFacing_Standing: ; 5680 + ld hl, OBJECT_FACING_STEP + add hl, bc + ld [hl], STANDING + scf + ret +; 5688 + +Function5688: ; 5688 + push bc + 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 GetCoordTile + pop bc + ld hl, OBJECT_NEXT_TILE + add hl, bc + ld [hl], a + farcall UpdateTallGrassFlags ; no need to farcall + ret +; 56a3 + +Function56a3: ; 56a3 + ld hl, OBJECT_NEXT_MAP_X + add hl, bc + ld d, [hl] + ld hl, OBJECT_NEXT_MAP_Y + add hl, bc + ld e, [hl] + inc d + inc e + ld a, [wXCoord] + cp d + jr z, .equal_x + jr nc, .nope + add MAPOBJECT_SCREEN_WIDTH - 1 + cp d + jr c, .nope +.equal_x + ld a, [wYCoord] + cp e + jr z, .equal_y + jr nc, .nope + add MAPOBJECT_SCREEN_HEIGHT - 1 + cp e + jr c, .nope +.equal_y + xor a + ret + +.nope + scf + ret +; 56cd + +Function56cd: ; 56cd + ld a, [wPlayerBGMapOffsetX] + ld d, a + ld hl, OBJECT_SPRITE_X_OFFSET + add hl, bc + ld a, [hl] + ld hl, OBJECT_SPRITE_X + add hl, bc + add [hl] + add d + cp $f0 + jr nc, .ok1 + cp $a0 + jp nc, .nope +.ok1 + and %00000111 + ld d, 2 + cp 4 + jr c, .ok2 + ld d, 3 +.ok2 + ld a, [hl] + srl a + srl a + srl a + cp SCREEN_WIDTH + jr c, .ok3 + sub BG_MAP_WIDTH +.ok3 + ld [hUsedSpriteIndex], a + ld a, [wPlayerBGMapOffsetY] + ld e, a + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + ld a, [hl] + ld hl, OBJECT_SPRITE_Y + add hl, bc + add [hl] + add e + cp $f0 + jr nc, .ok4 + cp $90 + jr nc, .nope +.ok4 + and %00000111 + ld e, 2 + cp 4 + jr c, .ok5 + ld e, 3 +.ok5 + ld a, [hl] + srl a + srl a + srl a + cp SCREEN_HEIGHT + jr c, .ok6 + sub BG_MAP_HEIGHT +.ok6 + ld [hUsedSpriteTile], a + ld hl, OBJECT_PALETTE + add hl, bc + bit 7, [hl] + jr z, .ok7 + ld a, d + add 2 + ld d, a + ld a, e + add 2 + ld e, a +.ok7 + ld a, d + ld [hFFBF], a +.loop + ld a, [hFFBF] + ld d, a + ld a, [hUsedSpriteTile] + add e + dec a + cp SCREEN_HEIGHT + jr nc, .ok9 + ld b, a +.next + ld a, [hUsedSpriteIndex] + add d + dec a + cp SCREEN_WIDTH + jr nc, .ok8 + ld c, a + push bc + call Coord2Tile + pop bc +; NPCs disappear if standing on tile $60-$7f (or $e0-$ff), +; since those IDs are for text characters and textbox frames. + ld a, [hl] + cp FIRST_REGULAR_TEXT_CHAR + jr nc, .nope +.ok8 + dec d + jr nz, .next +.ok9 + dec e + jr nz, .loop + and a + ret + +.nope + scf + ret +; 576a + +HandleNPCStep:: ; 576a + call .ResetStepVector + call .DoStepsForAllObjects + ret + +.ResetStepVector: + xor a + ld [wPlayerStepVectorX], a + ld [wPlayerStepVectorY], a + ld [wPlayerStepFlags], a + ld a, -1 + ld [wPlayerStepDirection], a + ret + +.DoStepsForAllObjects: + ld bc, wObjectStructs + xor a +.loop + ld [hMapObjectIndexBuffer], a + call DoesObjectHaveASprite + jr z, .next + call Function437b +.next + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + ld a, [hMapObjectIndexBuffer] + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + ret +; 579d + +RefreshPlayerSprite: ; 579d + ld a, movement_step_sleep + ld [wPlayerNextMovement], a + ld [wPlayerMovement], a + xor a + ld [wPlayerTurningDirection], a + ld [wPlayerObjectStepFrame], a + call .TryResetPlayerAction + farcall CheckWarpFacingDown + call c, SpawnInFacingDown + call .SpawnInCustomFacing + ret +; 57bc + +.TryResetPlayerAction: ; 57bc + ld hl, wPlayerSpriteSetupFlags + bit PLAYERSPRITESETUP_RESET_ACTION_F, [hl] + jr nz, .ok + ret + +.ok + ld a, OBJECT_ACTION_00 + ld [wPlayerAction], a + ret +; 57ca + +.SpawnInCustomFacing: ; 57ca + ld hl, wPlayerSpriteSetupFlags + bit PLAYERSPRITESETUP_CUSTOM_FACING_F, [hl] + ret z + ld a, [wPlayerSpriteSetupFlags] + and PLAYERSPRITESETUP_FACING_MASK + add a + add a + jr ContinueSpawnFacing +; 57d9 + +SpawnInFacingDown: ; 57d9 + ld a, 0 +ContinueSpawnFacing: ; 57db + ld bc, wPlayerStruct + call SetSpriteDirection + ret +; 57e2 + +_SetPlayerPalette: ; 57e2 + ld a, d + and %10000000 + ret z + ld bc, 0 ; debug? + ld hl, OBJECT_FACING + add hl, bc + ld a, [hl] + or d + ld [hl], a + ld a, d + swap a + and %00000111 + ld d, a + ld bc, wPlayerStruct + ld hl, OBJECT_PALETTE + add hl, bc + ld a, [hl] + and %11111000 + or d + ld [hl], a + ret +; 5803 + +StartFollow:: ; 5803 + push bc + ld a, b + call SetLeaderIfVisible + pop bc + ret c + ld a, c + call SetFollowerIfVisible + farcall QueueFollowerFirstStep + ret +; 5815 + +SetLeaderIfVisible: ; 5815 + call CheckObjectVisibility + ret c + ld a, [hObjectStructIndexBuffer] + ld [wObjectFollow_Leader], a + ret +; 581f + +StopFollow:: ; 581f + call ResetLeader + call ResetFollower + ret +; 5826 + +ResetLeader: ; 5826 + ld a, -1 + ld [wObjectFollow_Leader], a + ret +; 582c + +SetFollowerIfVisible: ; 582c + push af + call ResetFollower + pop af + call CheckObjectVisibility + ret c + ld hl, OBJECT_MOVEMENTTYPE + add hl, bc + ld [hl], SPRITEMOVEDATA_FOLLOWING + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_00 + ld a, [hObjectStructIndexBuffer] + ld [wObjectFollow_Follower], a + ret +; 5847 + +ResetFollower: ; 5847 + ld a, [wObjectFollow_Follower] + cp -1 + ret z + call GetObjectStruct + farcall Function58e3 ; no need to bankswitch + ld a, -1 + ld [wObjectFollow_Follower], a + ret +; 585c + +SetFlagsForMovement_1:: ; 585c + ld a, c + call CheckObjectVisibility + ret c + push bc + call Function587a + pop bc + ld hl, OBJECT_FLAGS2 + add hl, bc + res 5, [hl] + xor a + ret +; 586e + +Function586e: ; 586e + call CheckObjectVisibility + ret c + ld hl, OBJECT_FLAGS2 + add hl, bc + set 5, [hl] + xor a + ret +; 587a + +Function587a: ; 587a + ld bc, wObjectStructs + xor a +.loop + push af + call DoesObjectHaveASprite + jr z, .next + ld hl, OBJECT_FLAGS2 + add hl, bc + set 5, [hl] +.next + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + pop af + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + ret +; 5897 + +_SetFlagsForMovement_2:: ; 5897 + ld a, [wObjectFollow_Leader] + cp -1 + ret z + push bc + call GetObjectStruct + ld hl, OBJECT_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + pop bc + cp c + ret nz + ld a, [wObjectFollow_Follower] + cp -1 + ret z + call GetObjectStruct + ld hl, OBJECT_FLAGS2 + add hl, bc + res 5, [hl] + ret +; 58b9 + +Function58b9:: ; 58b9 + push bc + ld bc, wObjectStructs + xor a +.loop + push af + call DoesObjectHaveASprite + jr z, .next + ld hl, OBJECT_FLAGS2 + add hl, bc + res 5, [hl] +.next + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + pop af + inc a + cp NUM_OBJECT_STRUCTS + jr nz, .loop + pop bc + ret +; 58d8 + +Function58d8: ; 58d8 + call CheckObjectVisibility + ret c + ld hl, OBJECT_FLAGS2 + add hl, bc + res 5, [hl] + ret +; 58e3 + +Function58e3: ; 58e3 + ld hl, OBJECT_MAP_OBJECT_INDEX + add hl, bc + ld a, [hl] + cp -1 + jp z, Function5903 ; a jr would have been appropriate here + push bc + call GetMapObject + ld hl, MAPOBJECT_MOVEMENT + add hl, bc + ld a, [hl] + pop bc + ld hl, OBJECT_MOVEMENTTYPE + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_00 + ret +; 5903 + +Function5903: ; 5903 + call GetSpriteDirection + rrca + rrca + ld e, a + ld d, 0 + ld hl, .standing_movefns + add hl, de + ld a, [hl] + ld hl, OBJECT_MOVEMENTTYPE + add hl, bc + ld [hl], a + ld hl, OBJECT_STEP_TYPE + add hl, bc + ld [hl], STEP_TYPE_00 + ret + +.standing_movefns + db SPRITEMOVEDATA_STANDING_DOWN + db SPRITEMOVEDATA_STANDING_UP + db SPRITEMOVEDATA_STANDING_LEFT + db SPRITEMOVEDATA_STANDING_RIGHT +; 5920 + +_UpdateSprites:: ; 5920 + ld a, [wVramState] + bit 0, a + ret z + xor a + ld [hUsedSpriteIndex], a + ld a, [hOAMUpdate] + push af + ld a, 1 + ld [hOAMUpdate], a + call InitSprites + call .fill + pop af + ld [hOAMUpdate], a + ret + +.fill + ld a, [wVramState] + bit 1, a + ld b, LOW(wVirtualOAMEnd) + jr z, .ok + ld b, 28 * SPRITEOAMSTRUCT_LENGTH +.ok + ld a, [hUsedSpriteIndex] + cp b + ret nc + ld l, a + ld h, HIGH(wVirtualOAM) + ld de, SPRITEOAMSTRUCT_LENGTH + ld a, b + ld c, SCREEN_HEIGHT_PX + 2 * TILE_WIDTH +.loop + ld [hl], c ; y + add hl, de + cp l + jr nz, .loop + ret +; 5958 + +ApplyBGMapAnchorToObjects: ; 5958 + push hl + push de + push bc + ld a, [wPlayerBGMapOffsetX] + ld d, a + ld a, [wPlayerBGMapOffsetY] + ld e, a + ld bc, wObjectStructs + ld a, NUM_OBJECT_STRUCTS +.loop + push af + call DoesObjectHaveASprite + jr z, .skip + ld hl, OBJECT_SPRITE_X + add hl, bc + ld a, [hl] + add d + ld [hl], a + ld hl, OBJECT_SPRITE_Y + add hl, bc + ld a, [hl] + add e + ld [hl], a +.skip + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + pop af + dec a + jr nz, .loop + xor a + ld [wPlayerBGMapOffsetX], a + ld [wPlayerBGMapOffsetY], a + pop bc + pop de + pop hl + ret +; 5991 + + +PRIORITY_LOW EQU $10 +PRIORITY_NORM EQU $20 +PRIORITY_HIGH EQU $30 + +InitSprites: ; 5991 + call .DeterminePriorities + ld c, PRIORITY_HIGH + call .InitSpritesByPriority + ld c, PRIORITY_NORM + call .InitSpritesByPriority + ld c, PRIORITY_LOW + call .InitSpritesByPriority + ret + +.DeterminePriorities: + xor a + ld hl, wMovementPointer + ld bc, NUM_OBJECT_STRUCTS + call ByteFill + ld d, 0 + ld bc, wObjectStructs + ld hl, wMovementPointer +.loop + push hl + call DoesObjectHaveASprite + jr z, .skip + ld hl, OBJECT_FACING_STEP + add hl, bc + ld a, [hl] + cp STANDING + jr z, .skip +; Define the sprite priority. + ld e, PRIORITY_LOW + ld hl, OBJECT_FLAGS2 + add hl, bc + bit LOW_PRIORITY, [hl] + jr nz, .add + ld e, PRIORITY_NORM + bit HIGH_PRIORITY, [hl] + jr z, .add + ld e, PRIORITY_HIGH + jr .add + +.skip + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + pop hl + jr .next + +.add + ld hl, OBJECT_STRUCT_LENGTH + add hl, bc + ld b, h + ld c, l + pop hl + ld a, d + or e + ld [hli], a +.next + inc d + ld a, d + cp NUM_OBJECT_STRUCTS + jr nz, .loop + ret + +.InitSpritesByPriority: + ld hl, wMovementPointer +.next_sprite + ld a, [hli] + ld d, a + and $f0 + ret z + cp c + jr nz, .next_sprite + push bc + push hl + ld a, d + and $f + call .GetObjectStructPointer + call .InitSprite + pop hl + pop bc + jr .next_sprite + +.InitSprite: + ld hl, OBJECT_SPRITE_TILE + add hl, bc + ld a, [hl] + and %01111111 + ld [hFFC1], a + xor a + bit 7, [hl] + jr nz, .skip1 + or %00001000 +.skip1 + ld hl, OBJECT_FLAGS2 + add hl, bc + ld e, [hl] + bit 7, e + jr z, .skip2 + or %10000000 +.skip2 + bit 4, e + jr z, .skip3 + or %00010000 +.skip3 + ld hl, OBJECT_PALETTE + add hl, bc + ld d, a + ld a, [hl] + and %00000111 + or d + ld d, a + xor a + bit 3, e + jr z, .skip4 + or %10000000 +.skip4 + ld [hFFC2], a + ld hl, OBJECT_SPRITE_X + add hl, bc + ld a, [hl] + ld hl, OBJECT_SPRITE_X_OFFSET + add hl, bc + add [hl] + add 8 + ld e, a + ld a, [wPlayerBGMapOffsetX] + add e + ld [hFFBF], a + ld hl, OBJECT_SPRITE_Y + add hl, bc + ld a, [hl] + ld hl, OBJECT_SPRITE_Y_OFFSET + add hl, bc + add [hl] + add 12 + ld e, a + ld a, [wPlayerBGMapOffsetY] + add e + ld [hFFC0], a + ld hl, OBJECT_FACING_STEP + add hl, bc + ld a, [hl] + cp STANDING + jp z, .done + cp NUM_FACINGS + jp nc, .done + ld l, a + ld h, 0 + add hl, hl + ld bc, Facings + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [hUsedSpriteIndex] + ld c, a + ld b, HIGH(wVirtualOAM) + ld a, [hli] + ld [hUsedSpriteTile], a + add c + cp LOW(wVirtualOAMEnd) + jr nc, .full +.addsprite + ld a, [hFFC0] + add [hl] + inc hl + ld [bc], a ; y + inc c + ld a, [hFFBF] + add [hl] + inc hl + ld [bc], a ; x + inc c + ld e, [hl] + inc hl + ld a, [hFFC1] + bit 2, e + jr z, .nope1 + xor a +.nope1 + add [hl] + inc hl + ld [bc], a ; tile id + inc c + ld a, e + bit 1, a + jr z, .nope2 + ld a, [hFFC2] + or e +.nope2 + and OBP_NUM | X_FLIP | Y_FLIP | PRIORITY + or d + ld [bc], a ; attributes + inc c + ld a, [hUsedSpriteTile] + dec a + ld [hUsedSpriteTile], a + jr nz, .addsprite + ld a, c + ld [hUsedSpriteIndex], a +.done + xor a + ret + +.full + scf + ret + +.GetObjectStructPointer: + ld c, a + ld b, 0 + ld hl, .Addresses + add hl, bc + add hl, bc + ld c, [hl] + inc hl + ld b, [hl] + ret + +.Addresses: ; 5ace + dw wPlayerStruct + dw wObject1Struct + dw wObject2Struct + dw wObject3Struct + dw wObject4Struct + dw wObject5Struct + dw wObject6Struct + dw wObject7Struct + dw wObject8Struct + dw wObject9Struct + dw wObject10Struct + dw wObject11Struct + dw wObject12Struct +; 5ae8 |