Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: miscl fixes #146

Merged
merged 3 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bridge/qb/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ function CreateQbExport(name, cb)
end

function GetVehiclesFromPlate(plate)
Wait(500) -- delay needed to give client spawned vehicles time to be known to the server
local vehicles = GetAllVehicles()
local vehEntityFromPlate = {}

for i = 1, #vehicles do
local vehicle = vehicles[i]
local vehPlate = qbx.getVehiclePlate(vehicle)
if plate == vehPlate then
if plate == vehPlate or GetVehicleNumberPlateText(vehicle) then
vehEntityFromPlate[#vehEntityFromPlate + 1] = vehicle
end
end
Expand Down
13 changes: 7 additions & 6 deletions client/functions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ function AreKeysJobShared(vehicle)
if not jobInfo or (jobInfo.requireOnduty and not QBX.PlayerData.job.onduty) then return end

assert(jobInfo.vehicles, string.format('Vehicles not configured for the %s job.', job))

return jobInfo.vehicles[GetEntityModel(vehicle)]
return jobInfo.vehicles and jobInfo.vehicles[GetEntityModel(vehicle)] or jobInfo.classes and jobInfo.classes[GetVehicleClass(vehicle)]
end

---Checks if player has vehicle keys
Expand Down Expand Up @@ -48,7 +47,7 @@ function GetIsVehicleAccessible(vehicle)
end

local alertSend = false --Variable strictly related to sendPoliceAlertAttempt, not used elsewhere
function SendPoliceAlertAttempt(type)
function SendPoliceAlertAttempt(crime, vehicle)
if alertSend then return end
alertSend = true

Expand All @@ -58,7 +57,7 @@ function SendPoliceAlertAttempt(type)
or config.policeNightAlertChance

if math.random() <= chance then
TriggerServerEvent('police:server:policeAlert', locale("info.vehicle_theft") .. type)
config.alertPolice(crime, vehicle)
end

SetTimeout(config.alertCooldown, function()
Expand Down Expand Up @@ -145,7 +144,7 @@ local function lockpickCallback(vehicle, isAdvancedLockedpick, isSuccess)
if isSuccess then
lockpickSuccessCallback(vehicle)
else -- if player fails quickevent
SendPoliceAlertAttempt('carjack')
SendPoliceAlertAttempt('carjack', vehicle)
SetVehicleAlarm(vehicle, false)
SetVehicleAlarmTimeLeft(vehicle, config.vehicleAlarmDuration)
TriggerServerEvent('hud:server:GainStress', math.random(1, 4))
Expand Down Expand Up @@ -182,6 +181,7 @@ function LockpickDoor(isAdvancedLockedpick, maxDistance, customChallenge)
skillCheckConfig = skillCheckConfig.model[GetEntityModel(vehicle)]
or skillCheckConfig.class[GetVehicleClass(vehicle)]
or skillCheckConfig.default
if not next(skillCheckConfig) then return end

if islockpickingProcessLocked then return end -- start of the critical section
islockpickingProcessLocked = true -- one call per player at a time
Expand Down Expand Up @@ -216,7 +216,7 @@ local function hotwireCallback(vehicle, isAdvancedLockedpick, isSuccess)
if isSuccess then
hotwireSuccessCallback(vehicle)
else -- if player fails quickevent
SendPoliceAlertAttempt('carjack')
SendPoliceAlertAttempt('carjack', vehicle)
TriggerServerEvent('hud:server:GainStress', math.random(1, 4))
exports.qbx_core:Notify(locale('notify.failed_lockedpick'), 'error')
end
Expand All @@ -236,6 +236,7 @@ function Hotwire(vehicle, isAdvancedLockedpick, customChallenge)
skillCheckConfig = skillCheckConfig.model[GetEntityModel(vehicle)]
or skillCheckConfig.class[GetVehicleClass(vehicle)]
or skillCheckConfig.default
if not next(skillCheckConfig) then return end

if isHotwiringProcessLocked then return end -- start of the critical section
isHotwiringProcessLocked = true -- one call per player at a time
Expand Down
44 changes: 34 additions & 10 deletions client/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ local getIsVehicleCarjackingImmune = sharedFunctions.getIsVehicleCarjackingImmun
---manages the opening of locks
---@param vehicle number? The entity number of the vehicle.
---@param state boolean? State of the vehicle lock.
---@param anim any Aniation
---@param anim any Animation
local function setVehicleDoorLock(vehicle, state, anim)
if not vehicle or getIsVehicleAlwaysUnlocked(vehicle) or getIsVehicleShared(vehicle) then return end
if GetIsVehicleAccessible(vehicle) then
Expand Down Expand Up @@ -58,6 +58,15 @@ exports('SetVehicleDoorLock', setVehicleDoorLock)
---disable the engine and listen for search keys if applicable to the vehicle
local function onEnteringDriverSeat()
local vehicle = cache.vehicle
EngineBind:disable(false)
CreateThread(function()
while cache.seat == -1 do
if IsControlJustPressed(0, 23) then -- vehicle enter/leave input
EngineBind:disable(true)
end
Wait(0)
end
end)
if getIsVehicleShared(vehicle) then return end

local isVehicleAccessible = GetIsVehicleAccessible(vehicle)
Expand Down Expand Up @@ -123,25 +132,38 @@ local function toggleEngine(vehicle)
local anim = config.anims.toggleEngine.model[vehicleModel]
or config.anims.toggleEngine.class[vehicleClass]
or config.anims.toggleEngine.default
if anim then
if next(anim) then
lib.playAnim(cache.ped, anim.dict, anim.clip, 8.0, 8.0,-1, 48, 0)
Wait(400) -- for aesthetic purposes so the engine toggles when the player appears to touch the button/key
Wait(0)
CreateThread(function()
while IsEntityPlayingAnim(cache.ped, anim.dict, anim.clip, 3) do
if IsControlJustPressed(0, 23) then -- enter/exit vehicle input
ClearPedTasks(cache.ped)
return
end
Wait(0)
end
end)

--- aethestic wait so that the engine toggles when the player appears to touch the button/key
Wait(anim.delay or 0)
end

SetVehicleEngineOn(vehicle, not engineOn, false, true)
if cache.vehicle then
SetVehicleEngineOn(vehicle, not engineOn, false, true)
end
end

local engineBind
engineBind = lib.addKeybind({
EngineBind = lib.addKeybind({
name = 'toggleengine',
description = locale('info.engine'),
defaultKey = 'G',
defaultKey = config.keySearchBind,
onPressed = function()
if cache.vehicle then
engineBind:disable(true)
if cache.seat == -1 then
EngineBind:disable(true)
toggleEngine(cache.vehicle)
Wait(1000)
engineBind:disable(false)
EngineBind:disable(false)
end
end
})
Expand Down Expand Up @@ -183,6 +205,8 @@ RegisterNetEvent('lockpicks:UseLockpick', function(isAdvanced)
DisableKeySearch()
Hotwire(vehicle, isAdvanced)
EnableKeySearch()
else
Hotwire(vehicle, isAdvanced)
end
else
LockpickDoor(isAdvanced)
Expand Down
6 changes: 3 additions & 3 deletions client/searchkeys.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ end
local function findKeys(vehicleModel, vehicleClass, vehicle)
local hotwireTime = math.random(config.minKeysSearchTime, config.maxKeysSearchTime)

local anim = config.anims.lockpick.model[vehicleModel]
or config.anims.lockpick.model[vehicleClass]
or config.anims.lockpick.default
local anim = config.anims.searchKeys.model[vehicleModel]
or config.anims.searchKeys.model[vehicleClass]
or config.anims.searchKeys.default

local searchingForKeys = true
CreateThread(function()
Expand Down
37 changes: 30 additions & 7 deletions config/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ local hardLockpickSkillCheck = {
inputs = { '1', '2', '3', '4' }
}

---@alias Anim {dict: string, clip: string}
---@alias Anim {dict: string, clip: string, delay?: integer}

---@type Anim
local defaultHotwireAnim = { dict = 'anim@veh@plane@howard@front@ds@base', clip = 'hotwire' }
Expand All @@ -37,9 +37,6 @@ local defaultLockpickAnim = { dict = 'veh@break_in@0h@p_m_one@', clip = 'low_for
---@type Anim
local defaultHoldupAnim = { dict = 'mp_am_hold_up', clip = 'holdup_victim_20s' }

---@type Anim
local defaultEngineToggleAnim = { dict = 'oddjobs@towing', clip = 'start_engine' }

return {
vehicleMaximumLockingDistance = 5.0, -- Minimum distance for vehicle locking

Expand All @@ -63,6 +60,12 @@ return {
policeNightAlertChance = 0.50, -- Chance of alerting the police at night (times: 01-06)
policeAlertNightStartHour = 1,
policeAlertNightDuration = 5,
---Sends an alert to police
---@param crime string
---@param vehicle number entity
alertPolice = function(crime, vehicle)
TriggerServerEvent('police:server:policeAlert', locale("info.vehicle_theft") .. crime)
end,

vehicleAlarmDuration = 10000,
lockpickCooldown = 1000,
Expand All @@ -72,12 +75,21 @@ return {
sharedKeys = { -- Share keys amongst employees. Employees can lock/unlock any job-listed vehicle
police = { -- Job name
enableAutolock = true,
requireOnduty = false,
requireOnduty = true,
classes = {},
vehicles = {
[`police`] = true, -- Vehicle model
[`police2`] = true, -- Vehicle model
}
},
ambulance = {
enableAutolock = true,
requireOnduty = true,
classes = {},
vehicles = {
[`ambulance`] = true,
},
},
mechanic = {
requireOnduty = false,
vehicles = {
Expand Down Expand Up @@ -356,8 +368,19 @@ return {
}
},
toggleEngine = {
default = defaultEngineToggleAnim,
class = {},
default = {
dict = 'oddjobs@towing',
clip = 'start_engine',
delay = 400, -- how long it takes to start the engine
},
class = {
[VehicleClass.MOTORCYCLES] = {
dict = 'veh@bike@quad@front@base',
clip = 'start_engine',
delay = 1000,
},
[VehicleClass.CYCLES] = {}, -- does not have an engine
},
model = {},
},
}
Expand Down