fixes etc

This commit is contained in:
Nordi98 2025-06-12 03:36:12 +02:00
parent 4a0c8c6204
commit 453b281a4b
644 changed files with 1907 additions and 2456 deletions

View file

@ -0,0 +1,501 @@
IsProne = false
local isCrouched = false
local isCrawling = false
local inAction = false
local proneType = 'onfront'
local lastKeyPress = 0
local forceEndProne = false

-- Crouching --

local function ResetCrouch()
local playerPed = PlayerPedId()

ResetPedStrafeClipset(playerPed)
ResetPedWeaponMovementClipset(playerPed)
SetPedMaxMoveBlendRatio(playerPed, 1.0)
SetPedCanPlayAmbientAnims(playerPed, true)

local walkstyle = GetResourceKvpString("walkstyle")
if walkstyle then
local toApply = RP[walkstyle]
if not toApply or type(toApply) ~= "table" or toApply.category ~= "Walks" then
ResetPedMovementClipset(playerPed, 0.5)
DeleteResourceKvp("walkstyle")
DebugPrint('Invalid walkstyle found in KVP, resetting to default.')
return
end
RequestWalking(toApply[1])
SetPedMovementClipset(PlayerPedId(), toApply[1], 0.5)
RemoveClipSet(toApply[1])
else
ResetPedMovementClipset(playerPed, 0.5)
end

RemoveAnimSet('move_ped_crouched')
end

local function CrouchLoop()
local playerId = PlayerId()

while isCrouched do
local playerPed = PlayerPedId()

if not CanPlayerCrouchCrawl(playerPed) then
isCrouched = false
break
end

if IsPlayerAiming(playerId) then
SetPedMaxMoveBlendRatio(playerPed, 0.15)
end

SetPedCanPlayAmbientAnims(playerPed, false)

DisableControlAction(0, 36, true)
if IsPedUsingActionMode(playerPed) == 1 then
SetPedUsingActionMode(playerPed, false, -1, 'DEFAULT_ACTION')
end

DisableFirstPersonCamThisFrame()

if Config.FpsMode == true then
DisableControlAction(2, 25, true) -- disables the aim control action entirely while crouched
end

Wait(0)
end

TriggerEvent('crouch_crawl:onCrouch', false)

ResetCrouch()
end

local function StartCrouch()
isCrouched = true
RequestWalking('move_ped_crouched')
local playerPed = PlayerPedId()

if GetPedStealthMovement(playerPed) ~= 0 then
SetPedStealthMovement(playerPed, false, 'DEFAULT_ACTION')
Wait(100)
end

if GetFollowPedCamViewMode() == 4 then
SetFollowPedCamViewMode(0) -- THIRD_PERSON_NEAR
end

SetPedMovementClipset(playerPed, 'move_ped_crouched', 0.6)
SetPedStrafeClipset(playerPed, 'move_ped_crouched_strafing')

-- For other scripts to use
TriggerEvent('crouch_crawl:onCrouch', true)

CreateThread(CrouchLoop)
end

---@param playerPed number
---@return boolean success
local function AttemptCrouch(playerPed)
if CanPlayerCrouchCrawl(playerPed) and IsPedHuman(playerPed) then
StartCrouch()
return true
else
return false
end
end

---Disables a control until it's key has been released
---@param padIndex integer
---@param control integer
local function DisableControlUntilReleased(padIndex, control)
CreateThread(function()
while IsDisabledControlPressed(padIndex, control) do
DisableControlAction(padIndex, control, true)
Wait(0)
end
end)
end

local function CrouchKeyPressed()
if not LocalPlayer.state.canEmote then return end

if inAction then
return
end

if IsPauseMenuActive() or IsNuiFocused() then
return
end

if isCrouched then
isCrouched = false
local crouchKey = GetControlInstructionalButton(0, `+crouch` | 0x80000000, false)
local lookBehindKey = GetControlInstructionalButton(0, 26, false) -- INPUT_LOOK_BEHIND

if crouchKey == lookBehindKey then
DisableControlUntilReleased(0, 26) -- INPUT_LOOK_BEHIND
end

return
end

local playerPed = PlayerPedId()

if not CanPlayerCrouchCrawl(playerPed) or not IsPedHuman(playerPed) then
return
end

local crouchKey = GetControlInstructionalButton(0, `+crouch` | 0x80000000, false)
local lookBehindKey = GetControlInstructionalButton(0, 26, false) -- INPUT_LOOK_BEHIND
local duckKey = GetControlInstructionalButton(0, 36, false) -- INPUT_DUCK

if crouchKey == lookBehindKey then
DisableControlUntilReleased(0, 26) -- INPUT_LOOK_BEHIND
end

if crouchKey == duckKey then
if Config.CrouchOverrideStealthMode then
DisableControlAction(0, 36, true) -- Disable INPUT_DUCK this frame
elseif not IsProne then
local timer = GetGameTimer()

if GetPedStealthMovement(playerPed) ~= 0 and timer - lastKeyPress < 1000 then
DisableControlAction(0, 36, true) -- Disable INPUT_DUCK this frame
lastKeyPress = 0
else
lastKeyPress = timer
return
end
end
end

StartCrouch()

if IsProne then
inAction = true
IsProne = false
PlayAnimOnce(playerPed, 'get_up@directional@transition@prone_to_knees@crawl', 'front', nil, nil, 780)
Wait(780)
inAction = false
end
end


-- Crawling --

---@param playerPed number
---@return boolean
local function ShouldPlayerDiveToCrawl(playerPed)
if IsPedRunning(playerPed) or IsPedSprinting(playerPed) then
return true
end

return false
end

---Stops the player from being prone
---@param force boolean If forced then no exit anim is played
local function stopPlayerProne(force)
IsProne = false
forceEndProne = force
end

---@param playerPed number
---@param heading number|nil
---@param blendInSpeed number|nil
local function PlayIdleCrawlAnim(playerPed, heading, blendInSpeed)
local playerCoords = GetEntityCoords(playerPed)
TaskPlayAnimAdvanced(playerPed, 'move_crawl', proneType..'_fwd', playerCoords.x, playerCoords.y, playerCoords.z, 0.0, 0.0, heading or GetEntityHeading(playerPed), blendInSpeed or 2.0, 2.0, -1, 2, 1.0, false, false)
end

---@param forceEnd boolean
local function PlayExitCrawlAnims(forceEnd)
if not forceEnd then
inAction = true
local playerPed = PlayerPedId()
local animDict, animName, waitTime

if proneType == 'onfront' then
animDict, animName, waitTime = 'get_up@directional@transition@prone_to_knees@crawl', 'front', 780
else
animDict, animName, waitTime = 'get_up@directional@transition@prone_to_seated@crawl', 'back', 950
end

PlayAnimOnce(playerPed, animDict, animName, nil, nil, waitTime)

if not isCrouched then
Wait(waitTime)
PlayAnimOnce(playerPed, 'get_up@directional@movement@from_'..(proneType == 'onfront' and 'knees' or 'seated')..'@standard', 'getup_l_0', nil, nil, 1300)
end
end
end

-- Crawls one "step" forward/backward
---@param playerPed number
---@param type string
---@param direction string
local function Crawl(playerPed, type, direction)
isCrawling = true

TaskPlayAnim(playerPed, 'move_crawl', type..'_'..direction, 8.0, -8.0, -1, 2, 0.0, false, false, false)

local time = {
['onfront'] = {
['fwd'] = 820,
['bwd'] = 990
},
['onback'] = {
['fwd'] = 1200,
['bwd'] = 1200
}
}

SetTimeout(time[type][direction], function()
isCrawling = false
end)
end

-- Flips the player when crawling
---@param playerPed number
local function CrawlFlip(playerPed)
inAction = true
local heading = GetEntityHeading(playerPed)

proneType = proneType == 'onfront' and 'onback' or 'onfront'

if proneType == 'onback' then
PlayAnimOnce(playerPed, 'get_up@directional_sweep@combat@pistol@front', 'front_to_prone', 2.0)
ChangeHeadingSmooth(playerPed, -18.0, 3600)
else
PlayAnimOnce(playerPed, 'move_crawlprone2crawlfront', 'back', 2.0, nil, -1)
ChangeHeadingSmooth(playerPed, 12.0, 1700)
end

PlayIdleCrawlAnim(playerPed, heading + 180.0)
Wait(400)
inAction = false
end

local function CrawlLoop()
Wait(400)

while IsProne do
local playerPed = PlayerPedId()

if not CanPlayerCrouchCrawl(playerPed) or IsEntityInWater(playerPed) then
ClearPedTasks(playerPed)
stopPlayerProne(true)
break
end

local forward, backwards = IsControlPressed(0, 32), IsControlPressed(0, 33) -- INPUT_MOVE_UP_ONLY, INPUT_MOVE_DOWN_ONLY
if not isCrawling then
if forward then -- Forward
Crawl(playerPed, proneType, 'fwd')
elseif backwards then -- Back
Crawl(playerPed, proneType, 'bwd')
end
end

-- Moving left/right
if IsControlPressed(0, 34) then -- INPUT_MOVE_LEFT_ONLY
if isCrawling then
local headingDiff = forward and 1.0 or -1.0
SetEntityHeading(playerPed, GetEntityHeading(playerPed) + headingDiff)
else
inAction = true
if proneType == 'onfront' then
local playerCoords = GetEntityCoords(playerPed)
TaskPlayAnimAdvanced(playerPed, 'move_crawlprone2crawlfront', 'left', playerCoords.x, playerCoords.y, playerCoords.z, 0.0, 0.0, GetEntityHeading(playerPed), 2.0, 2.0, -1, 2, 0.1, false, false)
ChangeHeadingSmooth(playerPed, -10.0, 300)
Wait(700)
else
PlayAnimOnce(playerPed, 'get_up@directional_sweep@combat@pistol@left', 'left_to_prone')
ChangeHeadingSmooth(playerPed, 25.0, 400)
PlayIdleCrawlAnim(playerPed)
Wait(600)
end
inAction = false
end
elseif IsControlPressed(0, 35) then -- INPUT_MOVE_RIGHT_ONLY
if isCrawling then
local headingDiff = backwards and 1.0 or -1.0
SetEntityHeading(playerPed, GetEntityHeading(playerPed) + headingDiff)
else
inAction = true
if proneType == 'onfront' then
local playerCoords = GetEntityCoords(playerPed)
TaskPlayAnimAdvanced(playerPed, 'move_crawlprone2crawlfront', 'right', playerCoords.x, playerCoords.y, playerCoords.z, 0.0, 0.0, GetEntityHeading(playerPed), 2.0, 2.0, -1, 2, 0.1, false, false)
ChangeHeadingSmooth(playerPed, 10.0, 300)
Wait(700)
else
PlayAnimOnce(playerPed, 'get_up@directional_sweep@combat@pistol@right', 'right_to_prone')
ChangeHeadingSmooth(playerPed, -25.0, 400)
PlayIdleCrawlAnim(playerPed)
Wait(600)
end
inAction = false
end
end

if not isCrawling then
if IsControlPressed(0, 22) then -- INPUT_JUMP
CrawlFlip(playerPed)
end
end

Wait(0)
end

TriggerEvent('crouch_crawl:onCrawl', false)

PlayExitCrawlAnims(forceEndProne)

isCrawling = false
inAction = false
forceEndProne = false
proneType = 'onfront'
SetPedConfigFlag(PlayerPedId(), 48, false) -- CPED_CONFIG_FLAG_BlockWeaponSwitching

RemoveAnimDict('move_crawl')
RemoveAnimDict('move_crawlprone2crawlfront')
end

local function CrawlKeyPressed()
if not LocalPlayer.state.canEmote then return end

if inAction then
return
end

if IsPauseMenuActive() or IsNuiFocused() then
return
end

if IsProne then
IsProne = false
return
end

if IsInAnimation then
EmoteCancel()
end

local wasCrouched = false
if isCrouched then
isCrouched = false
wasCrouched = true
end

local playerPed = PlayerPedId()
if not CanPlayerCrouchCrawl(playerPed) or IsEntityInWater(playerPed) or not IsPedHuman(playerPed) then
return
end
inAction = true

if Pointing then
Pointing = false
end

if InHandsup then
return
end

if IsInActionWithErrorMessage({['IsProne'] = true}) then
return
end

IsProne = true
SetPedConfigFlag(playerPed, 48, true) -- CPED_CONFIG_FLAG_BlockWeaponSwitching

if GetPedStealthMovement(playerPed) ~= 0 then
SetPedStealthMovement(playerPed, false, 'DEFAULT_ACTION')
Wait(100)
end

LoadAnim('move_crawl')
LoadAnim('move_crawlprone2crawlfront')

if ShouldPlayerDiveToCrawl(playerPed) then
PlayAnimOnce(playerPed, 'explosions', 'react_blown_forwards', nil, 3.0)
Wait(1100)
elseif wasCrouched then
PlayAnimOnce(playerPed, 'amb@world_human_sunbathe@male@front@enter', 'enter', nil, nil, -1, 0.3)
Wait(1500)
else
PlayAnimOnce(playerPed, 'amb@world_human_sunbathe@male@front@enter', 'enter')
Wait(3000)
end

if CanPlayerCrouchCrawl(playerPed) and not IsEntityInWater(playerPed) then
PlayIdleCrawlAnim(playerPed, nil, 3.0)
end

TriggerEvent('crouch_crawl:onCrawl', true)

inAction = false
CreateThread(CrawlLoop)
end


-- Commands & KeyMapping --
if Config.CrouchEnabled then
if Config.CrouchKeybindEnabled then
RegisterKeyMapping('+crouch', Translate('register_crouch'), 'keyboard', Config.CrouchKeybind)
RegisterCommand('+crouch', function() CrouchKeyPressed() end, false)
RegisterCommand('-crouch', function() end, false) -- This needs to be here to prevent warnings in chat
end
RegisterCommand('crouch', function()
if not LocalPlayer.state.canEmote then return end

if isCrouched then
isCrouched = false
return
end

AttemptCrouch(PlayerPedId())
end, false)
TriggerEvent('chat:addSuggestion', '/crouch', Translate('crouch'))
end

if Config.CrawlEnabled then
if Config.CrawlKeybindEnabled then
RegisterKeyMapping('+crawl', Translate('register_crawl'), 'keyboard', Config.CrawlKeybind)
RegisterCommand('+crawl', function() CrawlKeyPressed() end, false)
RegisterCommand('-crawl', function() end, false) -- This needs to be here to prevent warnings in chat
end
RegisterCommand('crawl', function() CrawlKeyPressed() end, false)
TriggerEvent('chat:addSuggestion', '/crawl', Translate('crawl'))
end

---Returns if the player is crouched
---@return boolean
local function IsPlayerCrouched()
return isCrouched
end
CreateExport('IsPlayerCrouched', IsPlayerCrouched)

---Returns if the player is prone (both when laying still and when moving)
---@return boolean
local function IsPlayerProne()
return IsProne
end
CreateExport('IsPlayerProne', IsPlayerProne)

---Returns if the player is crawling (only when moving forward/backward)
---@return boolean
local function IsPlayerCrawling()
return isCrawling
end
CreateExport('IsPlayerCrawling', IsPlayerCrawling)

---Returns either "onfront" or "onback", this can be used to check if the player is on his back or on his stomach. NOTE: This will still return a string even if the player is not prone. Use IsPlayerProne() to check if the player is prone.
---@return string
local function GetPlayerProneType()
return proneType
end
CreateExport('GetPlayerProneType', GetPlayerProneType)

-- Useful to call if the player gets handcuffed etc.
CreateExport('StopPlayerProne', stopPlayerProne)