Feat: ESX_Ambulancejob: Allow Camera movement while dead

This commit is contained in:
Mycroft
2022-08-01 17:55:02 +01:00
parent 3f8097cd9c
commit e2a6cde40b
+364 -261
View File
@@ -4,375 +4,478 @@ isDead, isSearched, medic = false, false, 0
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer)
ESX.PlayerLoaded = true
ESX.PlayerLoaded = true
end)
RegisterNetEvent('esx:onPlayerLogout')
AddEventHandler('esx:onPlayerLogout', function()
ESX.PlayerLoaded = false
firstSpawn = true
ESX.PlayerLoaded = false
firstSpawn = true
end)
AddEventHandler('esx:onPlayerSpawn', function()
isDead = false
isDead = false
ClearTimecycleModifier()
SetPedMotionBlur(PlayerPedId(), false)
ClearExtraTimecycleModifier()
EndDeathCam()
if firstSpawn then
firstSpawn = false
if firstSpawn then
firstSpawn = false
if Config.SaveDeathStatus then
while not ESX.PlayerLoaded do
Wait(1000)
end
if Config.SaveDeathStatus then
while not ESX.PlayerLoaded do
Wait(1000)
end
ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie)
if shouldDie then
Wait(1000)
SetEntityHealth(PlayerPedId(), 0)
end
end)
end
end
ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie)
if shouldDie then
Wait(1000)
SetEntityHealth(PlayerPedId(), 0)
end
end)
end
end
end)
-- Create blips
CreateThread(function()
for k,v in pairs(Config.Hospitals) do
local blip = AddBlipForCoord(v.Blip.coords)
for k, v in pairs(Config.Hospitals) do
local blip = AddBlipForCoord(v.Blip.coords)
SetBlipSprite(blip, v.Blip.sprite)
SetBlipScale(blip, v.Blip.scale)
SetBlipColour(blip, v.Blip.color)
SetBlipAsShortRange(blip, true)
SetBlipSprite(blip, v.Blip.sprite)
SetBlipScale(blip, v.Blip.scale)
SetBlipColour(blip, v.Blip.color)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(_U('blip_hospital'))
EndTextCommandSetBlipName(blip)
end
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(_U('blip_hospital'))
EndTextCommandSetBlipName(blip)
end
while true do
local Sleep = 1500
if isDead then
Sleep = 0
DisableAllControlActions(0)
EnableControlAction(0, 47, true) -- G
EnableControlAction(0, 245, true) -- T
EnableControlAction(0, 38, true) -- E
while true do
local Sleep = 1500
if isSearched then
local playerPed = PlayerPedId()
local ped = GetPlayerPed(GetPlayerFromServerId(medic))
isSearched = false
AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
Wait(1000)
DetachEntity(playerPed, true, false)
ClearPedTasksImmediately(playerPed)
end
end
if isDead then
Sleep = 0
DisableAllControlActions(0)
EnableControlAction(0, 47, true) -- G
EnableControlAction(0, 245, true) -- T
EnableControlAction(0, 38, true) -- E
Wait(Sleep)
end
ProcessCamControls()
if isSearched then
local playerPed = PlayerPedId()
local ped = GetPlayerPed(GetPlayerFromServerId(medic))
isSearched = false
AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
Wait(1000)
DetachEntity(playerPed, true, false)
ClearPedTasksImmediately(playerPed)
end
end
Wait(Sleep)
end
end)
RegisterNetEvent('esx_ambulancejob:clsearch')
AddEventHandler('esx_ambulancejob:clsearch', function(medicId)
local playerPed = PlayerPedId()
local playerPed = PlayerPedId()
if isDead then
local coords = GetEntityCoords(playerPed)
local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0)
if isDead then
local coords = GetEntityCoords(playerPed)
local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0)
for i=1, #playersInArea, 1 do
local player = playersInArea[i]
if player == GetPlayerFromServerId(medicId) then
medic = tonumber(medicId)
isSearched = true
break
end
end
end
for i = 1, #playersInArea, 1 do
local player = playersInArea[i]
if player == GetPlayerFromServerId(medicId) then
medic = tonumber(medicId)
isSearched = true
break
end
end
end
end)
function OnPlayerDeath()
isDead = true
ESX.UI.Menu.CloseAll()
ESX.HideUI()
TriggerServerEvent('esx_ambulancejob:setDeathStatus', true)
StartDeathTimer()
StartDistressSignal()
isDead = true
ESX.UI.Menu.CloseAll()
ClearTimecycleModifier()
SetTimecycleModifier("REDMIST_blend")
SetTimecycleModifierStrength(0.7)
SetExtraTimecycleModifier("fp_vig_red")
SetExtraTimecycleModifierStrength(1.0)
SetPedMotionBlur(PlayerPedId(), true)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', true)
StartDeathTimer()
StartDeathCam()
StartDistressSignal()
end
RegisterNetEvent('esx_ambulancejob:useItem')
AddEventHandler('esx_ambulancejob:useItem', function(itemName)
ESX.UI.Menu.CloseAll()
ESX.UI.Menu.CloseAll()
if itemName == 'medikit' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
if itemName == 'medikit' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
RemoveAnimDict(lib)
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
RemoveAnimDict(lib)
Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Wait(0)
DisableAllControlActions(0)
end
Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Wait(0)
DisableAllControlActions(0)
end
TriggerEvent('esx_ambulancejob:heal', 'big', true)
ESX.ShowNotification(_U('used_medikit'))
end)
TriggerEvent('esx_ambulancejob:heal', 'big', true)
ESX.ShowNotification(_U('used_medikit'))
end)
elseif itemName == 'bandage' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
elseif itemName == 'bandage' then
local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations
local playerPed = PlayerPedId()
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
RemoveAnimDict(lib)
ESX.Streaming.RequestAnimDict(lib, function()
TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false)
RemoveAnimDict(lib)
Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Wait(0)
DisableAllControlActions(0)
end
Wait(500)
while IsEntityPlayingAnim(playerPed, lib, anim, 3) do
Wait(0)
DisableAllControlActions(0)
end
TriggerEvent('esx_ambulancejob:heal', 'small', true)
ESX.ShowNotification(_U('used_bandage'))
end)
end
TriggerEvent('esx_ambulancejob:heal', 'small', true)
ESX.ShowNotification(_U('used_bandage'))
end)
end
end)
function StartDistressSignal()
CreateThread(function()
local timer = Config.BleedoutTimer
CreateThread(function()
local timer = Config.BleedoutTimer
while timer > 0 and isDead do
Wait(0)
timer = timer - 30
while timer > 0 and isDead do
Wait(0)
timer = timer - 30
SetTextFont(4)
SetTextScale(0.5, 0.5)
SetTextColour(200, 50, 50, 255)
SetTextDropshadow(0.1, 3, 27, 27 , 255)
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(_U('distress_send'))
EndTextCommandDisplayText(0.43, 0.77)
SetTextFont(4)
SetTextScale(0.5, 0.5)
SetTextColour(200, 50, 50, 255)
SetTextDropshadow(0.1, 3, 27, 27, 255)
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(_U('distress_send'))
EndTextCommandDisplayText(0.43, 0.77)
if IsControlJustReleased(0, 47) then
SendDistressSignal()
break
end
end
end)
if IsControlJustReleased(0, 47) then
SendDistressSignal()
break
end
end
end)
end
function SendDistressSignal()
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
ESX.ShowNotification(_U('distress_sent'))
TriggerServerEvent('esx_ambulancejob:onPlayerDistress')
ESX.ShowNotification(_U('distress_sent'))
TriggerServerEvent('esx_ambulancejob:onPlayerDistress')
end
function DrawGenericTextThisFrame()
SetTextFont(4)
SetTextScale(0.0, 0.5)
SetTextColour(255, 255, 255, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
SetTextCentre(true)
SetTextFont(4)
SetTextScale(0.0, 0.5)
SetTextColour(255, 255, 255, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
SetTextCentre(true)
end
function secondsToClock(seconds)
local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0
local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0
if seconds <= 0 then
return 0, 0
else
local hours = string.format('%02.f', math.floor(seconds / 3600))
local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60)))
local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60))
if seconds <= 0 then
return 0, 0
else
local hours = string.format('%02.f', math.floor(seconds / 3600))
local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60)))
local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60))
return mins, secs
end
return mins, secs
end
end
function StartDeathTimer()
local canPayFine = false
local canPayFine = false
if Config.EarlyRespawnFine then
ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay)
canPayFine = canPay
end)
end
if Config.EarlyRespawnFine then
ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay)
canPayFine = canPay
end)
end
local earlySpawnTimer = ESX.Math.Round(Config.EarlyRespawnTimer / 1000)
local bleedoutTimer = ESX.Math.Round(Config.BleedoutTimer / 1000)
local earlySpawnTimer = ESX.Math.Round(Config.EarlyRespawnTimer / 1000)
local bleedoutTimer = ESX.Math.Round(Config.BleedoutTimer / 1000)
CreateThread(function()
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Wait(1000)
CreateThread(function()
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Wait(1000)
if earlySpawnTimer > 0 then
earlySpawnTimer = earlySpawnTimer - 1
end
end
if earlySpawnTimer > 0 then
earlySpawnTimer = earlySpawnTimer - 1
end
end
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Wait(1000)
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Wait(1000)
if bleedoutTimer > 0 then
bleedoutTimer = bleedoutTimer - 1
end
end
end)
if bleedoutTimer > 0 then
bleedoutTimer = bleedoutTimer - 1
end
end
end)
CreateThread(function()
local text, timeHeld
CreateThread(function()
local text, timeHeld
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Wait(0)
text = _U('respawn_available_in', secondsToClock(earlySpawnTimer))
-- early respawn timer
while earlySpawnTimer > 0 and isDead do
Wait(0)
text = _U('respawn_available_in', secondsToClock(earlySpawnTimer))
DrawGenericTextThisFrame()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(text)
EndTextCommandDisplayText(0.5, 0.8)
end
DrawGenericTextThisFrame()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(text)
EndTextCommandDisplayText(0.5, 0.8)
end
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Wait(0)
text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer))
-- bleedout timer
while bleedoutTimer > 0 and isDead do
Wait(0)
text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer))
if not Config.EarlyRespawnFine then
text = text .. _U('respawn_bleedout_prompt')
if not Config.EarlyRespawnFine then
text = text .. _U('respawn_bleedout_prompt')
if IsControlPressed(0, 38) and timeHeld > 120 then
RemoveItemsAfterRPDeath()
break
end
elseif Config.EarlyRespawnFine and canPayFine then
text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount))
if IsControlPressed(0, 38) and timeHeld > 120 then
RemoveItemsAfterRPDeath()
break
end
elseif Config.EarlyRespawnFine and canPayFine then
text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount))
if IsControlPressed(0, 38) and timeHeld > 120 then
TriggerServerEvent('esx_ambulancejob:payFine')
RemoveItemsAfterRPDeath()
break
end
end
if IsControlPressed(0, 38) and timeHeld > 120 then
TriggerServerEvent('esx_ambulancejob:payFine')
RemoveItemsAfterRPDeath()
break
end
end
if IsControlPressed(0, 38) then
timeHeld += 1
else
timeHeld = 0
end
if IsControlPressed(0, 38) then
timeHeld += 1
else
timeHeld = 0
end
DrawGenericTextThisFrame()
DrawGenericTextThisFrame()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(text)
EndTextCommandDisplayText(0.5, 0.8)
end
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(text)
EndTextCommandDisplayText(0.5, 0.8)
end
if bleedoutTimer < 1 and isDead then
RemoveItemsAfterRPDeath()
end
end)
if bleedoutTimer < 1 and isDead then
RemoveItemsAfterRPDeath()
end
end)
end
function GetClosestRespawnPoint()
local PlyCoords = GetEntityCoords(PlayerPedId())
local ClosestDist, ClosestHospital, ClosestCoord = 10000, {}, nil
local PlyCoords = GetEntityCoords(PlayerPedId())
local ClosestDist, ClosestHospital, ClosestCoord = 10000, {}, nil
for k,v in pairs(Config.RespawnPoints) do
local Distance = #(PlyCoords - vector3(v.coords.x, v.coords.y, v.coords.z))
if Distance <= ClosestDist then
ClosestDist = Distance
ClosestHospital = v
ClosestCoord = vector3(v.coords.x, v.coords.y, v.coords.z)
end
end
for k, v in pairs(Config.RespawnPoints) do
local Distance = #(PlyCoords - vector3(v.coords.x, v.coords.y, v.coords.z))
if Distance <= ClosestDist then
ClosestDist = Distance
ClosestHospital = v
ClosestCoord = vector3(v.coords.x, v.coords.y, v.coords.z)
end
end
return ClosestCoord, ClosestHospital
return ClosestCoord, ClosestHospital
end
function RemoveItemsAfterRPDeath()
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
CreateThread(function()
ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function()
local RespawnCoords, ClosestHospital = GetClosestRespawnPoint()
ESX.SetPlayerData('loadout', {})
CreateThread(function()
ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function()
local RespawnCoords, ClosestHospital = GetClosestRespawnPoint()
DoScreenFadeOut(800)
RespawnPed(PlayerPedId(), RespawnCoords, ClosestHospital.heading)
while not IsScreenFadedOut() do
Wait(0)
end
DoScreenFadeIn(800)
end)
end)
ESX.SetPlayerData('loadout', {})
DoScreenFadeOut(800)
RespawnPed(PlayerPedId(), RespawnCoords, ClosestHospital.heading)
while not IsScreenFadedOut() do
Wait(0)
end
DoScreenFadeIn(800)
end)
end)
end
function RespawnPed(ped, coords, heading)
SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false)
SetPlayerInvincible(ped, false)
ClearPedBloodDamage(ped)
SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false)
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false)
SetPlayerInvincible(ped, false)
ClearPedBloodDamage(ped)
TriggerServerEvent('esx:onPlayerSpawn')
TriggerEvent('esx:onPlayerSpawn')
TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon
TriggerServerEvent('esx:onPlayerSpawn')
TriggerEvent('esx:onPlayerSpawn')
TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon
end
RegisterNetEvent('esx_phone:loaded')
AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts)
local specialContact = {
name = 'Ambulance',
number = 'ambulance',
base64Icon = 'data:image/png;base64,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'
}
local specialContact = {name = 'Ambulance', number = 'ambulance',
base64Icon = 'data:image/png;base64,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'}
TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
end)
AddEventHandler('esx:onPlayerDeath', function(data)
OnPlayerDeath()
OnPlayerDeath()
end)
RegisterNetEvent('esx_ambulancejob:revive')
AddEventHandler('esx_ambulancejob:revive', function()
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
DoScreenFadeOut(800)
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
TriggerServerEvent('esx_ambulancejob:setDeathStatus', false)
while not IsScreenFadedOut() do
Wait(50)
end
DoScreenFadeOut(800)
local formattedCoords = {
x = ESX.Math.Round(coords.x, 1),
y = ESX.Math.Round(coords.y, 1),
z = ESX.Math.Round(coords.z, 1)
}
while not IsScreenFadedOut() do
Wait(50)
end
RespawnPed(playerPed, formattedCoords, 0.0)
isDead = false
DoScreenFadeIn(800)
local formattedCoords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)}
RespawnPed(playerPed, formattedCoords, 0.0)
isDead = false
ClearTimecycleModifier()
SetPedMotionBlur(playerPed, false)
ClearExtraTimecycleModifier()
EndDeathCam()
DoScreenFadeIn(800)
end)
-- Load unloaded IPLs
if Config.LoadIpl then
RequestIpl('Coroner_Int_on') -- Morgue
RequestIpl('Coroner_Int_on') -- Morgue
end
local cam = nil
local isDead = false
local angleY = 0.0
local angleZ = 0.0
-------------------------------------------------------
-----------------DEATH CAMERA FUNCTIONS ---------------
--------------------------------------------------------
-- initialize camera
function StartDeathCam()
ClearFocus()
local playerPed = PlayerPedId()
cam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", GetEntityCoords(playerPed), 0, 0, 0, GetGameplayCamFov())
SetCamActive(cam, true)
RenderScriptCams(true, true, 1000, true, false)
end
-- destroy camera
function EndDeathCam()
ClearFocus()
RenderScriptCams(false, false, 0, true, false)
DestroyCam(cam, false)
cam = nil
end
-- process camera controls
function ProcessCamControls()
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
-- disable 1st person as the 1st person camera can cause some glitches
DisableFirstPersonCamThisFrame()
-- calculate new position
local newPos = ProcessNewPosition()
SetFocusArea(newPos.x, newPos.y, newPos.z, 0.0, 0.0, 0.0)
-- set coords of cam
SetCamCoord(cam, newPos.x, newPos.y, newPos.z)
-- set rotation
PointCamAtCoord(cam, playerCoords.x, playerCoords.y, playerCoords.z + 0.5)
end
function ProcessNewPosition()
local mouseX = 0.0
local mouseY = 0.0
-- keyboard
if (IsInputDisabled(0)) then
-- rotation
mouseX = GetDisabledControlNormal(1, 1) * 8.0
mouseY = GetDisabledControlNormal(1, 2) * 8.0
-- controller
else
mouseX = GetDisabledControlNormal(1, 1) * 1.5
mouseY = GetDisabledControlNormal(1, 2) * 1.5
end
angleZ = angleZ - mouseX -- around Z axis (left / right)
angleY = angleY + mouseY -- up / down
-- limit up / down angle to 90°
if (angleY > 89.0) then
angleY = 89.0
elseif (angleY < -89.0) then
angleY = -89.0
end
local pCoords = GetEntityCoords(PlayerPedId())
local behindCam = {x = pCoords.x + ((Cos(angleZ) * Cos(angleY)) + (Cos(angleY) * Cos(angleZ))) / 2 * (5.5 + 0.5),
y = pCoords.y + ((Sin(angleZ) * Cos(angleY)) + (Cos(angleY) * Sin(angleZ))) / 2 * (5.5 + 0.5),
z = pCoords.z + ((Sin(angleY))) * (5.5 + 0.5)}
local rayHandle = StartShapeTestRay(pCoords.x, pCoords.y, pCoords.z + 0.5, behindCam.x, behindCam.y, behindCam.z, -1, PlayerPedId(), 0)
local a, hitBool, hitCoords, surfaceNormal, entityHit = GetShapeTestResult(rayHandle)
local maxRadius = 1.9
if (hitBool and Vdist(pCoords.x, pCoords.y, pCoords.z + 0.5, hitCoords) < 5.5 + 0.5) then
maxRadius = Vdist(pCoords.x, pCoords.y, pCoords.z + 0.5, hitCoords)
end
local offset = {x = ((Cos(angleZ) * Cos(angleY)) + (Cos(angleY) * Cos(angleZ))) / 2 * maxRadius,
y = ((Sin(angleZ) * Cos(angleY)) + (Cos(angleY) * Sin(angleZ))) / 2 * maxRadius, z = ((Sin(angleY))) * maxRadius}
local pos = {x = pCoords.x + offset.x, y = pCoords.y + offset.y, z = pCoords.z + offset.z}
return pos
end