1024 lines
46 KiB
Lua
1024 lines
46 KiB
Lua
|
--[[ ===================================================== ]]--
|
||
|
--[[ MH NPC Services Script by MaDHouSe ]]--
|
||
|
--[[ ===================================================== ]]--
|
||
|
|
||
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||
|
local stuckTimerCheck = Config.StuckTimerCheck
|
||
|
local stuckResetTimer = Config.StuckResetTimer
|
||
|
local company = {}
|
||
|
local count = 0
|
||
|
local phoneProp = 0
|
||
|
local waitTime = 60
|
||
|
local cooldownTime = Config.Cooldown
|
||
|
local jailTime = math.random(Config.MinJailTime, Config.MaxJailTime)
|
||
|
local isInJail = false
|
||
|
local followPedCamMode
|
||
|
local lastCoords = nil
|
||
|
|
||
|
local function DeletePhoneProp()
|
||
|
if phoneProp ~= 0 then
|
||
|
Citizen.InvokeNative(0xAE3CBE5BF394C9C9 , Citizen.PointerValueIntInitialized(phoneProp))
|
||
|
phoneProp = 0
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function CreatePhoneProp()
|
||
|
DeletePhoneProp()
|
||
|
RequestModel(Config.PhoneModel)
|
||
|
while not HasModelLoaded(Config.PhoneModel) do Citizen.Wait(1) end
|
||
|
phoneProp = CreateObject(Config.PhoneModel, 1.0, 1.0, 1.0, 1, 1, 0)
|
||
|
local bone = GetPedBoneIndex(PlayerPedId(), 28422)
|
||
|
AttachEntityToEntity(phoneProp, PlayerPedId(), bone, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 1, 0, 0, 2, 1)
|
||
|
end
|
||
|
|
||
|
local function loadAnimDict(dict)
|
||
|
while (not HasAnimDictLoaded(dict)) do
|
||
|
RequestAnimDict(dict)
|
||
|
Wait(5)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function loadModel(model)
|
||
|
RequestModel(model)
|
||
|
while not HasModelLoaded(model) do Wait(1) end
|
||
|
end
|
||
|
|
||
|
local function CallAnimation(job)
|
||
|
if not QBCore.Functions.GetPlayerData().metadata['isdead'] then
|
||
|
local dictionary = Config.CallAnimation.call.dictionary
|
||
|
local animation = Config.CallAnimation.call.animation
|
||
|
if not QBCore.Functions.GetPlayerData().job.name == "taxi" or not QBCore.Functions.GetPlayerData().job.name == "limousine" then
|
||
|
if QBCore.Functions.GetPlayerData().job.name == "police" or QBCore.Functions.GetPlayerData().job.name == "ambulance" or QBCore.Functions.GetPlayerData().job.name == "mechanic" then
|
||
|
dictionary = Config.CallAnimation.jobcall.dictionary
|
||
|
animation = Config.CallAnimation.jobcall.animation
|
||
|
end
|
||
|
end
|
||
|
loadAnimDict(dictionary)
|
||
|
CreatePhoneProp()
|
||
|
QBCore.Functions.Notify(Lang:t('notify.you_are_calling', {job = job}), "success")
|
||
|
TaskPlayAnim(PlayerPedId(), dictionary, animation, 1.5, 1.0, -1, 50, 2.0, 0, 0, 0)
|
||
|
Wait(8100)
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
DeletePhoneProp()
|
||
|
Wait(500)
|
||
|
if job == "mechanic" and IsPedInAnyVehicle(PlayerPedId(), false) then
|
||
|
local vehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
SetVehicleDoorsLocked(vehicle, 0)
|
||
|
TaskLeaveVehicle(PlayerPedId(), vehicle, 1)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function CalculateTaxiPrice(job, from, to)
|
||
|
local route = CalculateTravelDistanceBetweenPoints(from.x, from.y, from.z, to.x, to.y, to.z)
|
||
|
local price = math.floor((route / 1000) * Config.Service[job].price + 0.5)
|
||
|
return price
|
||
|
end
|
||
|
|
||
|
local function TempDisableControl()
|
||
|
DisableAllControlActions(0)
|
||
|
EnableControlAction(0, 1, true)
|
||
|
EnableControlAction(0, 2, true)
|
||
|
EnableControlAction(0, 245, true)
|
||
|
EnableControlAction(0, 38, true)
|
||
|
EnableControlAction(0, 322, true)
|
||
|
EnableControlAction(0, 249, true)
|
||
|
EnableControlAction(0, 46, true)
|
||
|
end
|
||
|
|
||
|
local function GetDistance(pos1, pos2)
|
||
|
return #(vector3(pos1.x, pos1.y, pos1.z) - vector3(pos2.x, pos2.y, pos2.z))
|
||
|
end
|
||
|
|
||
|
local function SetCompanyData(job)
|
||
|
company = {
|
||
|
name = Config.Service[job].name,
|
||
|
job = Config.Service[job].job,
|
||
|
ped = Config.JobPeds[job].models[math.random(1, #Config.JobPeds[job].models)],
|
||
|
plate = Config.Service[job].plate,
|
||
|
home = Config.Service[job].home,
|
||
|
color = Config.Service[job].color,
|
||
|
checkin = Config.Service[job].checkin,
|
||
|
vehicleDrop = Config.Service[job].vehicleDrop,
|
||
|
playerDrop = Config.Service[job].playerDrop,
|
||
|
driveStyle = Config.Service[job].driveStyle,
|
||
|
walkStyle = Config.Service[job].walkStyle,
|
||
|
speed = Config.Service[job].speed,
|
||
|
price = Config.Service[job].price,
|
||
|
truck_offset = Config.Service[job].truck_offset,
|
||
|
spawnRadius = Config.Service[job].spawnRadius,
|
||
|
spotRadius = Config.Service[job].spotRadius,
|
||
|
passengerSeat = Config.Service[job].passengerSeat,
|
||
|
isCalled = false,
|
||
|
isWaiting = false,
|
||
|
isReadyToGo = false,
|
||
|
driveToPlayer = false,
|
||
|
driveToCompany = false,
|
||
|
driveToLocation = false,
|
||
|
driveToMechanic = false,
|
||
|
driverIsInVehicle = false,
|
||
|
playerIsInVehicle = false,
|
||
|
driveAway = false,
|
||
|
isHandcuffed = false,
|
||
|
isDriving = false,
|
||
|
isEscorted = false,
|
||
|
damage_vehicle = nil,
|
||
|
coords = nil,
|
||
|
vehicle = nil,
|
||
|
driver = nil,
|
||
|
codriver = nil,
|
||
|
blip = nil,
|
||
|
}
|
||
|
count = 0
|
||
|
end
|
||
|
|
||
|
local function DriveToLocation(from, to)
|
||
|
if company.driver ~= nil and company.vehicle ~= nil then
|
||
|
company.coords = to
|
||
|
if GetDistance(from, to) < 500 then
|
||
|
TaskVehicleDriveToCoord(company.driver, company.vehicle, to.x, to.y, to.z, company.speed, 0, GetEntityModel(company.vehicle), company.driveStyle, 2.0, true)
|
||
|
else
|
||
|
TaskVehicleDriveToCoordLongrange(company.driver, company.vehicle, to.x, to.y, to.z, company.speed, company.driveStyle, 2.0)
|
||
|
end
|
||
|
SetPedKeepTask(company.driver, true)
|
||
|
if company.job == "police" then SetVehicleSiren(company.vehicle, true) end
|
||
|
if company.job == "ambulance" then SetVehicleSiren(company.vehicle, true) end
|
||
|
company.isDriving = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function DrawTxt(x, y, width, height, scale, text, r, g, b, a)
|
||
|
SetTextFont(4)
|
||
|
SetTextProportional(0)
|
||
|
SetTextScale(scale, scale)
|
||
|
SetTextColour(r, g, b, a)
|
||
|
SetTextDropShadow(0, 0, 0, 0,255)
|
||
|
SetTextEdge(2, 0, 0, 0, 255)
|
||
|
SetTextDropShadow()
|
||
|
SetTextOutline()
|
||
|
SetTextEntry("STRING")
|
||
|
AddTextComponentString(text)
|
||
|
DrawText(x - width/2, y - height/2 + 0.005)
|
||
|
end
|
||
|
|
||
|
local function Reset()
|
||
|
if company.vehicle ~= nil then DeleteEntity(company.vehicle) end
|
||
|
if company.driver ~= nil then DeleteEntity(company.driver) end
|
||
|
if company.codriver ~= nil then DeleteEntity(company.codriver) end
|
||
|
company = {}
|
||
|
company.isCalled = false
|
||
|
company.isWaiting = false
|
||
|
company.driveToPlayer = false
|
||
|
company.driveToCompany = false
|
||
|
company.driveToLocation = false
|
||
|
company.driveToMechanic = false
|
||
|
company.driverIsInVehicle = false
|
||
|
company.playerIsInVehicle = false
|
||
|
company.isHandcuffed = false
|
||
|
company.isDriving = false
|
||
|
company.isEscorted = false
|
||
|
if QBCore.Functions.GetPlayerData().metadata['isdead'] or QBCore.Functions.GetPlayerData().metadata['inlaststand'] then
|
||
|
company.sendNotify = true
|
||
|
else
|
||
|
company.sendNotify = false
|
||
|
end
|
||
|
lastCoords = nil
|
||
|
end
|
||
|
|
||
|
local function VehicleStuckCheck()
|
||
|
if company.driver ~= nil and company.vehicle ~= nil and lastCoords ~= nil then
|
||
|
if GetEntitySpeed(company.vehicle) < 0.9 then
|
||
|
stuckTimerCheck = stuckTimerCheck - 1
|
||
|
if stuckTimerCheck <= 0 then
|
||
|
if GetDistance(GetEntityCoords(company.vehicle), lastCoords) <= 1.0 then
|
||
|
local coords = GetEntityCoords(company.vehicle)
|
||
|
local haeding = GetEntityHeading(company.vehicle)
|
||
|
local _, spawnPosition, spawnHeading = GetClosestVehicleNodeWithHeading(coords.x + 5.0, coords.y, coords.z, 0, 3, 0)
|
||
|
ClearAreaOfVehicles(spawnPosition, 15000, false, false, false, false, false)
|
||
|
SetEntityCoords(company.vehicle, spawnPosition, false, false, false, true)
|
||
|
SetEntityHeading(company.vehicle, haeding)
|
||
|
DriveToLocation(coords, company.coords)
|
||
|
end
|
||
|
stuckTimerCheck = stuckResetTimer
|
||
|
end
|
||
|
end
|
||
|
lastCoords = nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function CreateServicesBlips(entity, label)
|
||
|
local blip = GetBlipFromEntity(entity)
|
||
|
if not DoesBlipExist(blip) then
|
||
|
blip = AddBlipForEntity(entity)
|
||
|
SetBlipSprite(blip, 161)
|
||
|
SetBlipScale(blip, 1.0)
|
||
|
SetBlipColour(blip, company.color)
|
||
|
SetBlipAsShortRange(blip, true)
|
||
|
BeginTextCommandSetBlipName('STRING')
|
||
|
AddTextComponentString(label)
|
||
|
EndTextCommandSetBlipName(blip)
|
||
|
end
|
||
|
if GetBlipFromEntity(PlayerPedId()) == blip then
|
||
|
RemoveBlip(blip)
|
||
|
end
|
||
|
return blip
|
||
|
end
|
||
|
|
||
|
local function LeaveTarget()
|
||
|
if company.driver ~= nil and company.vehicle ~= nil then
|
||
|
ClearPedTasks(company.driver)
|
||
|
SetPedKeepTask(company.driver, true)
|
||
|
company.coords = vector3(127.2708, 642.6805, 207.4947)
|
||
|
DriveToLocation(GetEntityCoords(company.vehicle), company.coords) -- From To
|
||
|
company.driveAway = true
|
||
|
SetTimeout(15000, function()
|
||
|
Reset()
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function CheckIfCompanyPedIsDeath()
|
||
|
if company.vehile ~= nil or company.driver ~= nil or company.codriver ~= nil then
|
||
|
if DoesEntityExist(company.driver) then
|
||
|
if IsEntityDead(company.driver) then
|
||
|
if company.codriver ~= nil then DeleteEntity(company.codriver) end
|
||
|
DeleteEntity(company.driver)
|
||
|
DeleteEntity(company.vehile)
|
||
|
Reset()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function GoToMechanicShop()
|
||
|
QBCore.Functions.TriggerCallback("qb-npcservices:server:CanIPayTheBill", function(isPaid)
|
||
|
if isPaid then
|
||
|
SetVehicleDoorOpen(company.damage_vehicle, 4, false, false)
|
||
|
TaskTurnPedToFaceCoord(company.driver, GetEntityCoords(company.damage_vehicle), -1)
|
||
|
TaskStartScenarioInPlace(company.driver, "PROP_HUMAN_BUM_BIN", 0, false)
|
||
|
QBCore.Functions.Progressbar("towtruck", company.job.." is helping...", 10000, false, false, {
|
||
|
disableMovement = false,
|
||
|
disableCarMovement = false,
|
||
|
disableMouse = false,
|
||
|
disableCombat = false,
|
||
|
}, {}, {}, {}, function() -- Done
|
||
|
ClearPedTasks(company.driver)
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
AttachEntityToEntity(company.damage_vehicle, company.vehicle, 20, company.truck_offset.x, company.truck_offset.y, company.truck_offset.z, 0.0, 0.0, 0.0, false, false, false, false, 20, true)
|
||
|
company.isWaiting = true
|
||
|
end)
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t('notify.cant_pay',{price = company.price}), "error")
|
||
|
end
|
||
|
end, company.job, company.price)
|
||
|
end
|
||
|
|
||
|
local function HelpOnLocation()
|
||
|
QBCore.Functions.TriggerCallback("qb-npcservices:server:CanIPayTheBill", function(isPaid)
|
||
|
if isPaid then
|
||
|
if company.job == "ambulance" then
|
||
|
local dictionary = "mini@cpr@char_a@cpr_str"
|
||
|
local animation = "cpr_pumpchest"
|
||
|
loadAnimDict(dictionary)
|
||
|
TaskTurnPedToFaceCoord(company.driver, GetEntityCoords(PlayerPedId()), -1)
|
||
|
TaskPlayAnim(company.driver, dictionary, animation, 1.0, 1.0, -1, 9, 1.0, 0, 0, 0)
|
||
|
end
|
||
|
if company.job == "mechanic" then
|
||
|
local animation = "PROP_HUMAN_BUM_BIN"
|
||
|
SetVehicleUndriveable(company.damage_vehicle, true)
|
||
|
SetVehicleDoorOpen(company.damage_vehicle, 4, false, false)
|
||
|
TaskTurnPedToFaceCoord(company.driver, GetEntityCoords(company.damage_vehicle), -1)
|
||
|
TaskStartScenarioInPlace(company.driver, animation, 0, false)
|
||
|
end
|
||
|
QBCore.Functions.Progressbar("jobstuff", company.job.." is helping", 10000, false, false, {
|
||
|
disableMovement = false,
|
||
|
disableCarMovement = false,
|
||
|
disableMouse = false,
|
||
|
disableCombat = true,
|
||
|
}, {}, {}, {}, function() -- Done
|
||
|
ClearPedTasks(company.driver)
|
||
|
if company.job == "ambulance" then
|
||
|
ClearPedTasks(company.codriver)
|
||
|
TaskWarpPedIntoVehicle(company.codriver, company.vehicle, 0)
|
||
|
TriggerEvent("hospital:client:Revive")
|
||
|
StopScreenEffect('DeathFailOut')
|
||
|
end
|
||
|
if company.job == "mechanic" then
|
||
|
SetVehicleDoorShut(company.damage_vehicle, 4, false, false)
|
||
|
Wait(1000)
|
||
|
SetVehicleFixed(company.damage_vehicle)
|
||
|
SetVehicleEngineHealth(company.damage_vehicle, 1000.0)
|
||
|
SetVehicleBodyHealth(company.damage_vehicle, 1000.0)
|
||
|
SetVehicleOnGroundProperly(company.damage_vehicle)
|
||
|
SetVehicleUndriveable(company.damage_vehicle, false)
|
||
|
end
|
||
|
company.coords = company.home
|
||
|
TriggerServerEvent('qb-npcservices:server:pay', company.job, company.price)
|
||
|
LeaveTarget()
|
||
|
end)
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t('notify.cant_pay',{price = company.price}), "error")
|
||
|
end
|
||
|
end, company.job, company.price)
|
||
|
end
|
||
|
|
||
|
local function GoToLocation()
|
||
|
if DoesBlipExist(GetFirstBlipInfoId(8)) and not company.driveToLocation and not company.isDriving then
|
||
|
SetBlockingOfNonTemporaryEvents(company.driver, true)
|
||
|
local x, y, z = table.unpack(Citizen.InvokeNative(0xFA7C7F0AADF25D09, GetFirstBlipInfoId(8), Citizen.ResultAsVector()))
|
||
|
PlayAmbientSpeech1(company.driver, "TAXID_BEGIN_JOURNEY", "SPEECH_PARAMS_FORCE_NORMAL")
|
||
|
company.coords = vector3(x, y, z)
|
||
|
DriveToLocation(GetEntityCoords(company.vehicle), company.coords)
|
||
|
company.driveToLocation = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function GoToCompany()
|
||
|
QBCore.Functions.TriggerCallback("qb-npcservices:server:canPay", function(canPay)
|
||
|
if canPay then
|
||
|
company.coords = company.home
|
||
|
if company.job == "police" or company.job == "ambulance" then
|
||
|
SetVehicleSiren(company.vehicle, true)
|
||
|
SetVehicleDoorsLocked(company.vehicle, 1)
|
||
|
TaskWarpPedIntoVehicle(company.codriver, company.vehicle, 1)
|
||
|
if company.job == "ambulance" then TaskWarpPedIntoVehicle(company.codriver, company.vehicle, 2) end
|
||
|
if company.job == "police" then TaskWarpPedIntoVehicle(company.codriver, company.vehicle, 0) end
|
||
|
end
|
||
|
if company.job == 'mechanic' then
|
||
|
PlayAmbientSpeech1(company.driver, "THANKS", "SPEECH_PARAMS_FORCE_NORMAL")
|
||
|
end
|
||
|
company.driveToCompany = true
|
||
|
DriveToLocation(GetEntityCoords(company.vehicle), company.home)
|
||
|
else
|
||
|
PlayAmbientSpeech1(company.driver, "TAXID_NO_MONEY", "SPEECH_PARAMS_FORCE_NORMAL")
|
||
|
QBCore.Functions.Notify(Lang:t('notify.cant_pay',{price = company.price}), "error")
|
||
|
end
|
||
|
end, company.job, company.price)
|
||
|
end
|
||
|
|
||
|
local function CreateServicesPed(coords, vehicle, seat)
|
||
|
local model = GetHashKey(company.ped)
|
||
|
loadModel(model)
|
||
|
local ped = CreatePed(4, model, coords.x, coords.y, coords.z, 0, true, true)
|
||
|
if company.job == 'police' then GiveWeaponToPed(ped, Config.Weapons[math.random(1, #Config.Weapons)], 999, false, true) end
|
||
|
SetPedIntoVehicle(ped, vehicle, seat)
|
||
|
SetEntityAsMissionEntity(ped, true, true)
|
||
|
SetModelAsNoLongerNeeded(model)
|
||
|
SetPedKeepTask(ped, true)
|
||
|
SetBlockingOfNonTemporaryEvents(ped, true)
|
||
|
SetPedSweat(ped, 100.0)
|
||
|
return ped
|
||
|
end
|
||
|
|
||
|
local function SelectVehicleModel()
|
||
|
local model = Config.Vehicles[company.job].models[math.random(1, #Config.Vehicles[company.job].models)]
|
||
|
loadModel(model)
|
||
|
if company.job == "mechanic" and company.damage_vehicle ~= nil then
|
||
|
if GetVehicleEngineHealth(company.damage_vehicle) < Config.MinDamageForFlatbed then
|
||
|
model = Config.Vehicles[company.job].models[1]
|
||
|
else
|
||
|
model = Config.Vehicles[company.job].models[2]
|
||
|
end
|
||
|
end
|
||
|
return model
|
||
|
end
|
||
|
|
||
|
local function CreateServicesVehicle(coords, heading)
|
||
|
ClearAreaOfVehicles(coords, 10000, false, false, false, false, false)
|
||
|
local model = SelectVehicleModel()
|
||
|
loadModel(model)
|
||
|
local vehicle = CreateVehicle(model, coords, heading, true, true)
|
||
|
SetEntityInvincible(vehicle, true)
|
||
|
NetworkSetEntityInvisibleToNetwork(vehicle, true)
|
||
|
SetEntityAsMissionEntity(vehicle, true, true)
|
||
|
SetVehicleDirtLevel(vehicle, 0)
|
||
|
SetVehicleBodyHealth(vehicle, 1000.0)
|
||
|
SetVehicleEngineHealth(vehicle, 1000.0)
|
||
|
SetVehicleFuelLevel(vehicle, 100.0)
|
||
|
SetVehicleDoorsLocked(vehicle, 1)
|
||
|
DecorSetFloat(vehicle, "_FUEL_LEVEL", GetVehicleFuelLevel(vehicle))
|
||
|
SetEntityHeading(vehicle, heading)
|
||
|
SetVehicleOnGroundProperly(vehicle)
|
||
|
SetVehicleHasUnbreakableLights(vehicle, true)
|
||
|
SetVehicleNumberPlateText(vehicle, company.plate)
|
||
|
SetVehicleEngineOn(vehicle, true, true, false)
|
||
|
SetVehicleLights(vehicle, 2)
|
||
|
SetModelAsNoLongerNeeded(model)
|
||
|
return vehicle
|
||
|
end
|
||
|
|
||
|
local function CallServices()
|
||
|
if isInJail then return end
|
||
|
if company.job == "taxi" or company.job == "limousine" then
|
||
|
local waypoint = GetFirstBlipInfoId(8)
|
||
|
if not DoesBlipExist(GetFirstBlipInfoId(8)) then
|
||
|
if company.job == 'taxi' then
|
||
|
return QBCore.Functions.Notify(Lang:t('job.taxi.missing_waypoint'), "error")
|
||
|
else
|
||
|
return QBCore.Functions.Notify(Lang:t('job.limousine.missing_waypoint'), "error")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
local coords = GetEntityCoords(PlayerPedId())
|
||
|
if Config.ForceFirstperson then followPedCamMode = GetFollowPedCamViewMode() end
|
||
|
local _, spawnPosition, spawnHeading = GetClosestVehicleNodeWithHeading(coords.x + math.random(-company.spawnRadius, company.spawnRadius), coords.y + math.random(-company.spawnRadius, company.spawnRadius), coords.z, 0, 3, 0)
|
||
|
company.vehicle = CreateServicesVehicle(spawnPosition, spawnHeading)
|
||
|
company.driver = CreateServicesPed(spawnPosition, company.vehicle, -1)
|
||
|
SetEntityAsMissionEntity(company.vehicle, true, true)
|
||
|
SetEntityAsMissionEntity(company.driver, true, true)
|
||
|
if company.job == "ambulance" then
|
||
|
company.codriver = CreateServicesPed(spawnPosition, company.vehicle, 0)
|
||
|
elseif company.job == "police" then
|
||
|
company.codriver = CreateServicesPed(spawnPosition, company.vehicle, 0)
|
||
|
end
|
||
|
if company.driver ~= nil and company.vehicle ~= nil then
|
||
|
if company.job == "police" or company.job == "ambulance" then SetVehicleSiren(vehicle, true) end
|
||
|
company.blip = CreateServicesBlips(company.vehicle, company.name)
|
||
|
DriveToLocation(spawnPosition, coords) -- From To
|
||
|
company.driveToPlayer = true
|
||
|
company.driverIsInVehicle = true
|
||
|
if company.job == "police" then SetFakeWantedLevel(6) end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function WalkToVehicle()
|
||
|
if isInJail then return end
|
||
|
if not company.isEscorted then
|
||
|
company.isEscorted = true
|
||
|
company.isHandcuffed = false
|
||
|
if company.job == "police" then
|
||
|
local heading = GetEntityHeading(PlayerPedId())
|
||
|
TriggerServerEvent("InteractSound_SV:PlayOnSource", "Cuff", 0.2)
|
||
|
loadAnimDict("mp_arrest_paired")
|
||
|
Wait(1000)
|
||
|
TaskPlayAnim(PlayerPedId(), "mp_arrest_paired", "crook_p2_back_right", 3.0, 3.0, -1, 32, 0, 0, 0, 0 ,true, true, true)
|
||
|
company.isHandcuffed = true
|
||
|
Wait(2500)
|
||
|
end
|
||
|
TaskGoToCoordAnyMeans(company.driver, GetEntityCoords(company.vehicle), 2.0, 0, 0, company.walkStyle, 0xbf800000)
|
||
|
AttachEntityToEntity(PlayerPedId(), company.driver, 11816, 0.0, -0.45, 0.0, 0.0, 0.0, 0.0, false, false, false, true, 2, true)
|
||
|
GoToCompany()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
AddEventHandler('onResourceStart', function(resource)
|
||
|
if resource == GetCurrentResourceName() then
|
||
|
SetFakeWantedLevel(0)
|
||
|
company = {}
|
||
|
Reset()
|
||
|
lastCoords = nil
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-npcservices:client:sendService', function(callData)
|
||
|
if isInJail then return end
|
||
|
if #company == 0 and not company.isCalled then
|
||
|
CallAnimation(callData.job)
|
||
|
SetCompanyData(callData.job)
|
||
|
company.isCalled = true
|
||
|
company.price = callData.price
|
||
|
if callData.job == "mechanic" then
|
||
|
local vehicle, _ = QBCore.Functions.GetClosestVehicle(GetEntityCoords(PlayerPedId()))
|
||
|
local props = QBCore.Functions.GetVehicleProperties(vehicle)
|
||
|
QBCore.Functions.TriggerCallback('qb-npcservices:server:IsVehicleOwner', function(owned)
|
||
|
if owned then
|
||
|
company.coords = GetEntityCoords(vehicle)
|
||
|
company.damage_vehicle = vehicle
|
||
|
QBCore.Functions.Notify(Lang:t('notify.call_company', {company = company.name}), "success", 8000)
|
||
|
Wait(8500)
|
||
|
CallServices()
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t('error.not_the_owner'), "error")
|
||
|
end
|
||
|
end, props.plate)
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t('notify.call_company', {company = company.name}), "success", 8000)
|
||
|
Wait(8500)
|
||
|
CallServices()
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-npcservices:client:menu', function()
|
||
|
if isInJail then return end
|
||
|
local playerlist = {}
|
||
|
QBCore.Functions.TriggerCallback('qb-npcservices:server:GetOnlinePlayers', function(online)
|
||
|
for key, v in pairs(online) do
|
||
|
if v.source == GetPlayerServerId(PlayerId()) then
|
||
|
playerlist[#playerlist + 1] = {value = v.source, text = "(ID:"..v.source..") "..v.fullname}
|
||
|
end
|
||
|
local player, distance = QBCore.Functions.GetClosestPlayer()
|
||
|
if player ~= -1 and distance < 2.5 then
|
||
|
local playerId = GetPlayerServerId(player)
|
||
|
if v.source ~= GetPlayerServerId(PlayerId()) then
|
||
|
playerlist[#playerlist + 1] = {value = v.source, text = "(ID:"..v.source..") "..v.fullname}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if playerlist == nil then
|
||
|
return
|
||
|
else
|
||
|
QBCore.Functions.TriggerCallback("qb-npcservices:server:isEMSServices", function(isService)
|
||
|
local menuData = {}
|
||
|
if not IsPedInAnyVehicle(PlayerPedId()) then
|
||
|
if DoesBlipExist(GetFirstBlipInfoId(8)) then
|
||
|
menuData[#menuData + 1] = {value = "taxi", text = Lang:t('job.taxi.label') }
|
||
|
menuData[#menuData + 1] = {value = "limousine", text = Lang:t('job.limousine.label') }
|
||
|
end
|
||
|
end
|
||
|
if IsPedInAnyVehicle(PlayerPedId()) then
|
||
|
menuData[#menuData + 1] = {value = "mechanic", text = Lang:t('job.mechanic.label') }
|
||
|
end
|
||
|
menuData[#menuData + 1] = {value = "ambulance", text = Lang:t('job.ambulance.label') }
|
||
|
if Config.UsePoliceAssist and QBCore.Functions.GetPlayerData().job.name == "police" and isService then
|
||
|
menuData[#menuData + 1] = { value = "police", text = Lang:t('job.police.label')}
|
||
|
end
|
||
|
local menu = exports["qb-input"]:ShowInput({
|
||
|
header = Lang:t('menu.title'),
|
||
|
submitText = "",
|
||
|
inputs = {
|
||
|
{
|
||
|
text = Lang:t('menu.select_player'),
|
||
|
name = "id",
|
||
|
type = "select",
|
||
|
options = playerlist,
|
||
|
isRequired = true
|
||
|
},
|
||
|
{
|
||
|
text = Lang:t('menu.select_company'),
|
||
|
name = "company",
|
||
|
type = "select",
|
||
|
options = menuData,
|
||
|
isRequired = true
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
if menu then
|
||
|
if not menu.id or not menu.company then return end
|
||
|
local call_data = {}
|
||
|
call_data.job = tostring(menu.company)
|
||
|
call_data.callerId = GetPlayerServerId(PlayerId())
|
||
|
call_data.price = Config.Service[call_data.job].price
|
||
|
if tonumber(menu.id) == GetPlayerServerId(PlayerId()) then
|
||
|
call_data.targetId = GetPlayerServerId(PlayerId())
|
||
|
else
|
||
|
call_data.targetId = tonumber(menu.id)
|
||
|
end
|
||
|
if call_data.job == 'taxi' or call_data.job == 'limousine' then
|
||
|
if DoesBlipExist(GetFirstBlipInfoId(8)) then
|
||
|
local x, y, z = table.unpack(Citizen.InvokeNative(0xFA7C7F0AADF25D09, GetFirstBlipInfoId(8), Citizen.ResultAsVector()))
|
||
|
local from = GetEntityCoords(PlayerPedId())
|
||
|
local to = vector3(x, y, z)
|
||
|
call_data.price = CalculateTaxiPrice(call_data.job, from, to)
|
||
|
end
|
||
|
end
|
||
|
TriggerServerEvent('qb-npcservices:server:sendService', call_data)
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
|
||
|
if MenuItemId ~= nil then
|
||
|
exports['qb-radialmenu']:RemoveOption(MenuItemId)
|
||
|
MenuItemId = nil
|
||
|
end
|
||
|
MenuItemId = exports['qb-radialmenu']:AddOption(
|
||
|
{
|
||
|
id = 'callemsservices',
|
||
|
title = Lang:t('menu.title'),
|
||
|
icon = Config.RadialMenuIcone,
|
||
|
type = 'client',
|
||
|
event = 'qb-npcservices:client:menu',
|
||
|
shouldClose = true
|
||
|
},
|
||
|
MenuItemId)
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
Wait(1)
|
||
|
if company.isEscorted then
|
||
|
DisableAllControlActions(0)
|
||
|
EnableControlAction(0, 1, true)
|
||
|
EnableControlAction(0, 2, true)
|
||
|
EnableControlAction(0, 245, true)
|
||
|
EnableControlAction(0, 38, true)
|
||
|
EnableControlAction(0, 322, true)
|
||
|
EnableControlAction(0, 249, true)
|
||
|
EnableControlAction(0, 46, true)
|
||
|
end
|
||
|
if company.isHandcuffed then
|
||
|
DisableControlAction(0, 24, true) -- Attack
|
||
|
DisableControlAction(0, 257, true) -- Attack 2
|
||
|
DisableControlAction(0, 25, true) -- Aim
|
||
|
DisableControlAction(0, 263, true) -- Melee Attack 1
|
||
|
DisableControlAction(0, 45, true) -- Reload
|
||
|
DisableControlAction(0, 22, true) -- Jump
|
||
|
DisableControlAction(0, 44, true) -- Cover
|
||
|
DisableControlAction(0, 37, true) -- Select Weapon
|
||
|
DisableControlAction(0, 23, true) -- Also 'enter'?
|
||
|
DisableControlAction(0, 288, true) -- Disable phone
|
||
|
DisableControlAction(0, 289, true) -- Inventory
|
||
|
DisableControlAction(0, 170, true) -- Animations
|
||
|
DisableControlAction(0, 167, true) -- Job
|
||
|
DisableControlAction(0, 26, true) -- Disable looking behind
|
||
|
DisableControlAction(0, 73, true) -- Disable clearing animation
|
||
|
DisableControlAction(2, 199, true) -- Disable pause screen
|
||
|
DisableControlAction(0, 59, true) -- Disable steering in vehicle
|
||
|
DisableControlAction(0, 71, true) -- Disable driving forward in vehicle
|
||
|
DisableControlAction(0, 72, true) -- Disable reversing in vehicle
|
||
|
DisableControlAction(2, 36, true) -- Disable going stealth
|
||
|
DisableControlAction(0, 264, true) -- Disable melee
|
||
|
DisableControlAction(0, 257, true) -- Disable melee
|
||
|
DisableControlAction(0, 140, true) -- Disable melee
|
||
|
DisableControlAction(0, 141, true) -- Disable melee
|
||
|
DisableControlAction(0, 142, true) -- Disable melee
|
||
|
DisableControlAction(0, 143, true) -- Disable melee
|
||
|
DisableControlAction(0, 75, true) -- Disable exit vehicle
|
||
|
DisableControlAction(27, 75, true) -- Disable exit vehicle
|
||
|
EnableControlAction(0, 249, true) -- Added for talking while cuffed
|
||
|
EnableControlAction(0, 46, true) -- Added for talking while cuffed
|
||
|
end
|
||
|
if not company.isHandcuffed and not company.isEscorted then
|
||
|
Wait(2000)
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- npc is driving (Taxi/Police/Ambulance/Mechanic/TowTruck)
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if company.driveToPlayer then
|
||
|
local coords = nil
|
||
|
if company.job == 'mechanic' then
|
||
|
coords = GetEntityCoords(company.damage_vehicle)
|
||
|
else
|
||
|
coords = GetEntityCoords(PlayerPedId())
|
||
|
end
|
||
|
local vdistance = GetDistance(coords, GetEntityCoords(company.vehicle))
|
||
|
local ddistance = GetDistance(coords, GetEntityCoords(company.driver))
|
||
|
if company.job == 'mechanic' or company.job == 'taxi' or company.job == 'limousine' then
|
||
|
if QBCore.Functions.GetPlayerData().metadata['isdead'] or QBCore.Functions.GetPlayerData().metadata['inlaststand'] then
|
||
|
company.driveToPlayer = false
|
||
|
company.isDriving = false
|
||
|
ClearPedTasks(company.driver)
|
||
|
RemoveBlip(company.blip)
|
||
|
LeaveTarget()
|
||
|
end
|
||
|
end
|
||
|
if vdistance < company.spotRadius then
|
||
|
company.driverIsInVehicle = false
|
||
|
if company.job == "mechanic" then
|
||
|
local engine = GetWorldPositionOfEntityBone(company.damage_vehicle, GetEntityBoneIndexByName(company.damage_vehicle, "engine"))
|
||
|
TaskGoToCoordAnyMeans(company.driver, engine, 1.0, 0, 0, company.walkStyle, 0xbf800000)
|
||
|
ddistance = GetDistance(vector3(engine.x, engine.y, engine.z), GetEntityCoords(company.driver))
|
||
|
else
|
||
|
if company.job == "police" or company.job == "ambulance" then
|
||
|
if company.job == "police" then FreezeEntityPosition(PlayerPedId(), true) end
|
||
|
TaskGoToCoordAnyMeans(company.driver, coords, 2.0, 0, 0, company.walkStyle, 0xbf800000)
|
||
|
else
|
||
|
TaskGoToCoordAnyMeans(company.driver, coords, 1.0, 0, 0, company.walkStyle, 0xbf800000)
|
||
|
end
|
||
|
end
|
||
|
if company.job == 'police' or company.job == 'ambulance' then SetVehicleSiren(company.vehicle, false) end
|
||
|
if ddistance < Config.InteractDiustance then
|
||
|
ClearPedTasks(company.driver)
|
||
|
RemoveBlip(company.blip)
|
||
|
company.driveToPlayer = false
|
||
|
company.isDriving = false
|
||
|
if company.job == 'police' then
|
||
|
SetFakeWantedLevel(0)
|
||
|
if not company.isEscorted then WalkToVehicle() end
|
||
|
elseif company.job == 'ambulance' then
|
||
|
if QBCore.Functions.GetPlayerData().metadata['isdead'] or QBCore.Functions.GetPlayerData().metadata['inlaststand'] then
|
||
|
if not company.isEscorted then WalkToVehicle() end
|
||
|
else
|
||
|
HelpOnLocation()
|
||
|
end
|
||
|
elseif company.job == 'mechanic' then
|
||
|
if GetVehicleEngineHealth(company.damage_vehicle) < Config.MinDamageForFlatbed then
|
||
|
GoToMechanicShop()
|
||
|
else
|
||
|
HelpOnLocation()
|
||
|
end
|
||
|
elseif company.job == 'taxi' then
|
||
|
company.isWaiting = true
|
||
|
elseif company.job == 'limousine' then
|
||
|
company.isWaiting = true
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
elseif company.isReadyToGo then
|
||
|
if not IsPedInVehicle(PlayerPedId(), company.vehicle, false) then TempDisableControl() end
|
||
|
SetVehicleDoorsLocked(company.vehicle, 0)
|
||
|
if IsPedInVehicle(company.driver, company.vehicle, false) and IsPedInVehicle(PlayerPedId(), company.vehicle, false) then
|
||
|
company.isReadyToGo = false
|
||
|
if company.job == 'taxi' or company.job == 'limousine' then GoToLocation() end
|
||
|
if company.job == 'mechanic' then
|
||
|
DriveToLocation(GetEntityCoords(company.vehicle), company.home)
|
||
|
company.driveToMechanic = true
|
||
|
end
|
||
|
end
|
||
|
elseif company.isEscorted then
|
||
|
local distance = GetDistance(GetEntityCoords(company.driver), GetEntityCoords(company.vehicle))
|
||
|
if company.job == "police" then
|
||
|
loadAnimDict("mp_arresting")
|
||
|
TaskPlayAnim(PlayerPedId(), "mp_arresting", "idle", 8.0, -8, -1, 16, 0, 0, 0, 0)
|
||
|
end
|
||
|
if distance <= 5 then
|
||
|
company.isEscorted = false
|
||
|
company.coords = company.home
|
||
|
DoScreenFadeOut(500)
|
||
|
Wait(700)
|
||
|
DetachEntity(PlayerPedId(), true, false)
|
||
|
TaskWarpPedIntoVehicle(PlayerPedId(), company.vehicle, company.passengerSeat)
|
||
|
TaskWarpPedIntoVehicle(company.driver, company.vehicle, -1)
|
||
|
Wait(1000)
|
||
|
DoScreenFadeIn(500)
|
||
|
company.driveToCompany = true
|
||
|
DriveToLocation(GetEntityCoords(company.vehicle), company.home)
|
||
|
end
|
||
|
elseif company.driveToCompany then
|
||
|
local distance = GetDistance(GetEntityCoords(company.vehicle), company.home)
|
||
|
lastCoords = GetEntityCoords(company.vehicle)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(4) end
|
||
|
if distance <= 5 then
|
||
|
company.driveToCompany = false
|
||
|
company.isDriving = false
|
||
|
BringVehicleToHalt(company.vehicle, 5.0, 1000, true)
|
||
|
Wait(1100)
|
||
|
ClearPedTasks(company.driver)
|
||
|
SetVehicleSiren(company.vehicle, false)
|
||
|
DoScreenFadeOut(500)
|
||
|
Wait(600)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(followPedCamMode) end
|
||
|
SetEntityCoords(PlayerPedId(), vector3(company.checkin.x, company.checkin.y, company.checkin.z), false, false, false, true)
|
||
|
if company.job == "police" then
|
||
|
if Config.UseAutoJail then
|
||
|
isInJail = true
|
||
|
jailTime = math.random(Config.MinJailTime, Config.MaxJailTime)
|
||
|
end
|
||
|
FreezeEntityPosition(PlayerPedId(), false)
|
||
|
company.isHandcuffed = false
|
||
|
end
|
||
|
|
||
|
if company.job == "ambulance" then FreezeEntityPosition(PlayerPedId(), false) end
|
||
|
Wait(1000)
|
||
|
DoScreenFadeIn(500)
|
||
|
Wait(500)
|
||
|
LeaveTarget()
|
||
|
end
|
||
|
elseif company.driveToMechanic then
|
||
|
local distance = GetDistance(GetEntityCoords(company.vehicle), company.home)
|
||
|
lastCoords = GetEntityCoords(company.vehicle)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(4) end
|
||
|
if distance <= 5 then
|
||
|
company.driveToMechanic = false
|
||
|
company.isDriving = false
|
||
|
BringVehicleToHalt(company.vehicle, 5.0, 1000, true)
|
||
|
ClearPedTasks(company.driver)
|
||
|
TaskLeaveVehicle(PlayerPedId(), company.vehicle, 1)
|
||
|
TriggerServerEvent('qb-npcservices:server:pay', company.job, company.price)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(followPedCamMode) end
|
||
|
Wait(3000)
|
||
|
DetachEntity(company.damage_vehicle, false, false)
|
||
|
Wait(100)
|
||
|
SetEntityCoords(company.damage_vehicle, vector3(company.vehicleDrop.x, company.vehicleDrop.y, company.vehicleDrop.z), false, false, false, true)
|
||
|
Wait(2000)
|
||
|
LeaveTarget()
|
||
|
end
|
||
|
elseif company.driveToLocation then
|
||
|
local distance = GetDistance(GetEntityCoords(company.vehicle), company.coords)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(4) end
|
||
|
lastCoords = GetEntityCoords(company.vehicle)
|
||
|
if distance <= 5 or not DoesBlipExist(GetFirstBlipInfoId(8)) then
|
||
|
company.driveToLocation = false
|
||
|
company.isDriving = false
|
||
|
BringVehicleToHalt(company.vehicle, 5.0, 1000, true)
|
||
|
Wait(1100)
|
||
|
ClearPedTasks(company.driver)
|
||
|
TriggerServerEvent('qb-npcservices:server:pay', company.job, company.price)
|
||
|
PlayAmbientSpeech1(company.driver, "TAXID_CLOSE_AS_POSS", "SPEECH_PARAMS_FORCE_NORMAL")
|
||
|
Wait(100)
|
||
|
if Config.ForceFirstperson then SetFollowVehicleCamViewMode(followPedCamMode) end
|
||
|
TriggerServerEvent('qb-npcservices:server:leavevehicle', company.vehicle)
|
||
|
Wait(3100)
|
||
|
LeaveTarget()
|
||
|
end
|
||
|
elseif company.driveAway then
|
||
|
lastCoords = GetEntityCoords(company.vehicle)
|
||
|
local distance = GetDistance(GetEntityCoords(company.vehicle), GetEntityCoords(PlayerPedId()))
|
||
|
if distance > 100 then
|
||
|
company.driveAway = false
|
||
|
Reset()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(100)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if Config.UseUnlimitHealth then
|
||
|
if company.job ~= nil then
|
||
|
if company.vehicle ~= nil then
|
||
|
SetVehicleBodyHealth(company.vehicle, 1000.0)
|
||
|
SetVehicleEngineHealth(company.vehicle, 1000.0)
|
||
|
SetVehicleFuelLevel(company.vehicle, 100.0)
|
||
|
DecorSetFloat(company.vehicle, "_FUEL_LEVEL", GetVehicleFuelLevel(company.vehicle))
|
||
|
end
|
||
|
if company.driver ~= nil then SetEntityHealth(company.driver, 200) end
|
||
|
if company.codriver ~= nil then SetEntityHealth(company.codriver, 200) end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(500)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if Config.AutoCallAmbulance and not company.sendNotify and not company.isCalled then
|
||
|
if QBCore.Functions.GetPlayerData().metadata['inlaststand'] then
|
||
|
if not company.sendNotify then
|
||
|
local call_data = {}
|
||
|
call_data.job = 'ambulance'
|
||
|
call_data.callerId = GetPlayerServerId(PlayerId())
|
||
|
call_data.targetId = GetPlayerServerId(PlayerId())
|
||
|
call_data.price = Config.Service['ambulance'].price
|
||
|
Wait(Config.AutoCallTimer)
|
||
|
CallAnimation(call_data.job)
|
||
|
TriggerServerEvent('qb-npcservices:server:sendService', call_data)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
CheckIfCompanyPedIsDeath()
|
||
|
end
|
||
|
Wait(1000)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if company.job ~= nil then
|
||
|
if company.driveToCompany or company.driveToLocation or company.driveToMechanic or company.driveToPlayer or company.driveAway then
|
||
|
if company.driverIsInVehicle then VehicleStuckCheck() end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(1000)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
local sleep = 1000
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if isInJail and Config.UseAutoJail then
|
||
|
jailTime = jailTime - 1
|
||
|
if jailTime <= 0 then
|
||
|
isInJail = false
|
||
|
SetEntityCoords(PlayerPedId(), vector3(Config.Service['police'].checkout.x, Config.Service['police'].checkout.y, Config.Service['police'].checkout.z), false, false, false, true)
|
||
|
SetEntityHeading(PlayerPedId(), Config.Service['police'].checkout.w)
|
||
|
Reset()
|
||
|
end
|
||
|
elseif company.isWaiting then
|
||
|
waitTime = waitTime - 1
|
||
|
if waitTime <= 0 then LeaveTarget() end
|
||
|
|
||
|
elseif company.cooldown then
|
||
|
cooldownTime = cooldownTime - 1
|
||
|
if cooldownTime <= 0 then company.cooldown = false end
|
||
|
end
|
||
|
end
|
||
|
Wait(sleep)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
local sleep = 1000
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if isInJail and Config.UseAutoJail then
|
||
|
sleep = 5
|
||
|
if jailTime > 0 then
|
||
|
GetEntityHealth(PlayerPedId(), 200.0)
|
||
|
DrawTxt(0.93, 1.44, 1.0, 1.0, 0.6, Lang:t('notify.jail_free_time', {freetime = math.ceil(jailTime)}), 255, 255, 255, 255)
|
||
|
end
|
||
|
elseif company.isWaiting then
|
||
|
sleep = 5
|
||
|
if waitTime > 0 then
|
||
|
DrawTxt(0.83, 1.44, 1.0, 1.0, 0.6, Lang:t('notify.press_e_to_enter',{waitTime = math.ceil(waitTime), job = company.job}), 255, 255, 255, 255)
|
||
|
if IsControlJustPressed(0, 38) then -- press E to get in the taxi
|
||
|
if not IsPedInVehicle(PlayerPedId(), company.vehicle, false) then
|
||
|
company.isWaiting = false
|
||
|
company.isReadyToGo = true
|
||
|
SetVehicleDoorsLocked(company.vehicle, 0)
|
||
|
TriggerServerEvent('qb-vehiclekeys:server:setVehLockState', NetworkGetNetworkIdFromEntity(company.vehicle), 0)
|
||
|
TriggerServerEvent('qb-npcservices:server:getin', company.job, company.vehicle)
|
||
|
TaskEnterVehicle(company.driver, company.vehicle, -1, -1, 1.0, 1, 0)
|
||
|
end
|
||
|
end
|
||
|
elseif company.cooldown then
|
||
|
sleep = 5
|
||
|
if waitTime > 0 then
|
||
|
DrawTxt(0.93, 1.44, 1.0, 1.0, 0.6, Lang:t('notify.cooldown',{cooldownTime = math.ceil(cooldownTime), job = company.job}), 255, 255, 255, 255)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(sleep)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- Debug Stuff
|
||
|
CreateThread(function()
|
||
|
local count = 0
|
||
|
while true do
|
||
|
count = count + 1
|
||
|
if LocalPlayer.state.isLoggedIn then
|
||
|
if Config.Debug and company.job ~= nil then
|
||
|
if company.driveToCompany or company.driveToLocation or company.driveToMechanic or company.driveToPlayer or company.driveAway or company.isEscorted or isInJail or not isInJail then
|
||
|
-- print("-----------"..count.."-----------")
|
||
|
-- print("Driver "..company.job.." Debugger")
|
||
|
-- print("Driver in Vehicle: "..tostring(company.driverIsInVehicle))
|
||
|
-- print("Driver Is Driving: "..tostring(company.isDriving))
|
||
|
-- print("Driver is Escorted: "..tostring(company.isEscorted))
|
||
|
-- print("Drive to Company: "..tostring(company.driveToCompany))
|
||
|
-- print("Drive to Location: "..tostring(company.driveToLocation))
|
||
|
-- print("Drive to Mechanic: "..tostring(company.driveToMechanic))
|
||
|
-- print("Drive to Player: "..tostring(company.driveToPlayer))
|
||
|
-- print("Drive Away: "..tostring(company.driveAway))
|
||
|
-- print("Player is in Jail: "..tostring(isInJail))
|
||
|
else
|
||
|
count = 0
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Wait(2000)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-npcservices:client:getinvehicle', function(vehicle)
|
||
|
for i = 1, 7 do
|
||
|
if IsVehicleSeatFree(vehicle, i) then
|
||
|
TriggerServerEvent('qb-vehiclekeys:server:setVehLockState', NetworkGetNetworkIdFromEntity(vehicle), 0)
|
||
|
SetVehicleDoorsLocked(vehicle, 0)
|
||
|
TaskEnterVehicle(PlayerPedId(), vehicle, -1, i, 1.0, 1, 0)
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-npcservices:client:leavevehicle', function()
|
||
|
local vehicle = GetVehiclePedIsIn(PlayerPedId())
|
||
|
if IsPedInAnyVehicle(PlayerPedId(), false) then
|
||
|
SetVehicleDoorsLocked(vehicle, 0)
|
||
|
TaskLeaveVehicle(PlayerPedId(), vehicle, 1)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- for taxi and limousine
|
||
|
if Config.UseTarget then
|
||
|
RegisterNetEvent('qb-npcservices:client:taxi', function(vehicle)
|
||
|
local vehicle, distance = QBCore.Functions.GetClosestVehicle(GetEntityCoords(PlayerPedId()))
|
||
|
TriggerServerEvent('qb-npcservices:server:getin', 'taxi', vehicle)
|
||
|
end)
|
||
|
RegisterNetEvent('qb-npcservices:client:limousine', function(vehicle)
|
||
|
local vehicle, distance = QBCore.Functions.GetClosestVehicle(GetEntityCoords(PlayerPedId()))
|
||
|
TriggerServerEvent('qb-npcservices:server:getin', 'limousine', vehicle)
|
||
|
end)
|
||
|
for _, model in pairs(Config.Vehicles['taxi']) do
|
||
|
exports['qb-target']:AddTargetModel(model, {
|
||
|
options = {
|
||
|
{
|
||
|
type = "client",
|
||
|
event = "qb-npcservices:client:taxi",
|
||
|
icon = "fas fa-car",
|
||
|
label = Lang:t('target.get_in'),
|
||
|
},
|
||
|
},
|
||
|
distance = 2.5
|
||
|
})
|
||
|
end
|
||
|
for _, model in pairs(Config.Vehicles['limousine']) do
|
||
|
exports['qb-target']:AddTargetModel(model, {
|
||
|
options = {
|
||
|
{
|
||
|
type = "client",
|
||
|
event = "qb-npcservices:client:limousine",
|
||
|
icon = "fas fa-car",
|
||
|
label = Lang:t('target.get_in'),
|
||
|
},
|
||
|
},
|
||
|
distance = 2.5
|
||
|
})
|
||
|
end
|
||
|
end
|