@@ -109,31 +109,38 @@ local function isVehicleInRange(vehicle, maxDistance)
109
109
end
110
110
end
111
111
112
- --- Will be execuded when the opening of the lock succeeds.
113
- --- @param vehicle number The entity number of the vehicle.
114
- --- @param plate string The plate number of the vehicle.
115
- local function lockpickSuccessCallback (vehicle , plate )
116
- TriggerServerEvent (' hud:server:GainStress' , math.random (1 , 4 ))
117
-
118
- if cache .seat == - 1 then
119
- TriggerServerEvent (' qb-vehiclekeys:server:AcquireVehicleKeys' , plate )
112
+ --- Chance to destroy lockpick
113
+ --- @param isAdvancedLockedpick any
114
+ --- @param vehicleClass any
115
+ local function breakLockpick (isAdvancedLockedpick , vehicleClass )
116
+ local chance = math.random ()
117
+ if isAdvancedLockedpick then -- there is no benefit to using an advanced tool in the default configuration.
118
+ if chance <= config .removeAdvancedLockpickChance [vehicleClass ] then
119
+ TriggerServerEvent (" qb-vehiclekeys:server:breakLockpick" , " advancedlockpick" )
120
+ end
120
121
else
121
- exports . qbx_core : Notify ( locale ( " notify.vehicle_lockedpick " ), ' success ' )
122
- TriggerServerEvent (' qb-vehiclekeys:server:setVehLockState ' , NetworkGetNetworkIdFromEntity ( vehicle ), 1 )
123
- Entity ( vehicle ). state . isOpen = true
122
+ if chance <= config . removeNormalLockpickChance [ vehicleClass ] then
123
+ TriggerServerEvent (" qb-vehiclekeys:server:breakLockpick " , " lockpick " )
124
+ end
124
125
end
125
126
end
126
127
128
+ --- Will be executed when the lock opening is successful.
129
+ --- @param vehicle number The entity number of the vehicle.
130
+ local function lockpickSuccessCallback (vehicle )
131
+ TriggerServerEvent (' hud:server:GainStress' , math.random (1 , 4 ))
132
+ exports .qbx_core :Notify (locale (" notify.vehicle_lockedpick" ), ' success' )
133
+ TriggerServerEvent (' qb-vehiclekeys:server:setVehLockState' , NetworkGetNetworkIdFromEntity (vehicle ), 1 )
134
+ Entity (vehicle ).state .isOpen = true
135
+ end
136
+
127
137
--- Operations done after the LockpickDoor quickevent done.
128
138
--- @param vehicle number The entity number of the vehicle.
129
- --- @param plate string The plate number of the vehicle.
130
139
--- @param isAdvancedLockedpick boolean Determines whether an advanced lockpick was used.
131
- --- @param maxDistance number The max distance to check.
132
140
--- @param isSuccess boolean ? Determines whether the lock has been successfully opened.
133
- local function lockpickCallback (vehicle , plate , isAdvancedLockedpick , maxDistance , isSuccess )
134
- if not isVehicleInRange (vehicle , maxDistance ) then return end -- the action will be aborted if the opened vehicle is too far.
141
+ local function lockpickCallback (vehicle , isAdvancedLockedpick , isSuccess )
135
142
if isSuccess then
136
- lockpickSuccessCallback (vehicle , plate )
143
+ lockpickSuccessCallback (vehicle )
137
144
else -- if player fails quickevent
138
145
public .attemptPoliceAlert (' carjack' )
139
146
SetVehicleAlarm (vehicle , false )
@@ -142,20 +149,10 @@ local function lockpickCallback(vehicle, plate, isAdvancedLockedpick, maxDistanc
142
149
exports .qbx_core :Notify (locale (' notify.failed_lockedpick' ), ' error' )
143
150
end
144
151
145
- local chance = math.random ()
146
- if isAdvancedLockedpick then -- there is no benefit to using an advanced tool at this moment.
147
- if chance <= config .removeAdvancedLockpickChance [GetVehicleClass (vehicle )] then
148
- TriggerServerEvent (" qb-vehiclekeys:server:breakLockpick" , " advancedlockpick" )
149
- end
150
- else
151
- if chance <= config .removeNormalLockpickChance [GetVehicleClass (vehicle )] then
152
- TriggerServerEvent (" qb-vehiclekeys:server:breakLockpick" , " lockpick" )
153
- end
154
- end
152
+ breakLockpick (isAdvancedLockedpick , GetVehicleClass (vehicle ))
155
153
end
156
154
157
155
local islockpickingProcessLocked = false -- lock flag
158
-
159
156
--- Lockpicking quickevent.
160
157
--- @param isAdvancedLockedpick boolean Determines whether an advanced lockpick was used
161
158
--- @param maxDistance number ? The max distance to check.
@@ -167,6 +164,7 @@ function public.lockpickDoor(isAdvancedLockedpick, maxDistance, customChallenge)
167
164
168
165
if not vehicle then return end
169
166
167
+ local class = GetVehicleClass (vehicle )
170
168
local plate = qbx .getVehiclePlate (vehicle )
171
169
local isDriverSeatFree = IsVehicleSeatFree (vehicle , - 1 )
172
170
@@ -178,25 +176,72 @@ function public.lockpickDoor(isAdvancedLockedpick, maxDistance, customChallenge)
178
176
or Entity (vehicle ).state .isOpen -- the lock is locked
179
177
or not isCloseToAnyBone (pedCoords , vehicle , doorBones , maxDistance ) -- the player's ped is close enough to the driver's door
180
178
or GetVehicleDoorLockStatus (vehicle ) < 2 -- the vehicle is locked
179
+ or (not isAdvancedLockedpick and config .advancedLockpickVehicleClasses [class ])
181
180
then return end
182
181
183
182
if islockpickingProcessLocked then return end -- start of the critical section
184
-
185
183
islockpickingProcessLocked = true -- one call per player at a time
186
184
187
185
CreateThread (function ()
188
- -- lock opening animation
189
- lib .requestAnimDict (' veh@break_in@0h@p_m_one@' )
190
- TaskPlayAnim (cache .ped , ' veh@break_in@0h@p_m_one@' , " low_force_entry_ds" , 3.0 , 3.0 , - 1 , 16 , 0 , false , false , false )
191
-
186
+ lib .playAnim (cache .ped , ' veh@break_in@0h@p_m_one@' , " low_force_entry_ds" , 3.0 , 3.0 , - 1 , 16 , 0 , false , false , false ) -- lock opening animation
192
187
local isSuccess = customChallenge or lib .skillCheck ({ ' easy' , ' easy' , { areaSize = 60 , speedMultiplier = 1 }, ' medium' }, { ' 1' , ' 2' , ' 3' , ' 4' })
193
- lockpickCallback (vehicle , plate , isAdvancedLockedpick , maxDistance , isSuccess )
188
+
189
+ if isVehicleInRange (vehicle , maxDistance ) then -- the action will be aborted if the opened vehicle is too far.
190
+ lockpickCallback (vehicle , isAdvancedLockedpick , isSuccess )
191
+ end
192
+
194
193
Wait (config .lockpickCooldown )
195
194
end )
196
195
197
196
islockpickingProcessLocked = false -- end of the critical section
198
197
end
199
198
199
+ --- Will be executed when the lock opening is successful.
200
+ --- @param vehicle number The entity number of the vehicle.
201
+ local function hotwireSuccessCallback (vehicle )
202
+ local plate = qbx .getVehiclePlate (vehicle )
203
+ TriggerServerEvent (' qb-vehiclekeys:server:AcquireVehicleKeys' , plate )
204
+ end
205
+
206
+ --- Operations done after the LockpickDoor quickevent done.
207
+ --- @param vehicle number The entity number of the vehicle.
208
+ --- @param isAdvancedLockedpick boolean Determines whether an advanced lockpick was used.
209
+ --- @param isSuccess boolean ? Determines whether the lock has been successfully opened.
210
+ local function hotwireCallback (vehicle , isAdvancedLockedpick , isSuccess )
211
+ if isSuccess then
212
+ hotwireSuccessCallback (vehicle )
213
+ else -- if player fails quickevent
214
+ public .attemptPoliceAlert (' carjack' )
215
+ TriggerServerEvent (' hud:server:GainStress' , math.random (1 , 4 ))
216
+ exports .qbx_core :Notify (locale (' notify.failed_lockedpick' ), ' error' )
217
+ end
218
+
219
+ breakLockpick (isAdvancedLockedpick , GetVehicleClass (vehicle ))
220
+ end
221
+
222
+ local isHotwiringProcessLocked = false -- lock flag
223
+ --- Hotwiring with a tool quickevent.
224
+ --- @param isAdvancedLockedpick boolean Determines whether an advanced lockpick was used
225
+ --- @param customChallenge boolean ? lockpick challenge
226
+ function public .hotwire (isAdvancedLockedpick , customChallenge )
227
+ if not (cache .vehicle
228
+ and cache .seat
229
+ and cache .seat == - 1 )
230
+ then return end
231
+
232
+ if isHotwiringProcessLocked then return end -- start of the critical section
233
+ isHotwiringProcessLocked = true -- one call per player at a time
234
+
235
+ CreateThread (function ()
236
+ lib .playAnim (cache .ped , ' veh@break_in@0h@p_m_one@' , " low_force_entry_ds" , 3.0 , 3.0 , - 1 , 16 , 0 , false , false , false ) -- lock opening animation
237
+ local isSuccess = customChallenge or lib .skillCheck ({ ' easy' , ' easy' , { areaSize = 60 , speedMultiplier = 1 }, ' medium' }, { ' 1' , ' 2' , ' 3' , ' 4' })
238
+ hotwireCallback (cache .vehicle , isAdvancedLockedpick , isSuccess )
239
+ Wait (config .lockpickCooldown )
240
+ end )
241
+
242
+ isHotwiringProcessLocked = false -- end of the critical section
243
+ end
244
+
200
245
--- Get a vehicle in the players scope by the plate
201
246
--- @param plate string
202
247
--- @return integer ?
0 commit comments