Skip to content

Commit

Permalink
fix: open bugs with carjacking (#106)
Browse files Browse the repository at this point in the history
* chore: remove duplicated classes

* perf: load module when we need to

* fix: hot wiring/searching for keys causes ped to leave car occasionally

* fix: carjacking ped will just return to their car once car jack is done, ped should run away in fear

* chore: ped leaves vehicle without closing the door which is realistic, and why wait?

* fix: this makes ped doesn't leave the car, so we stop carjacking when progress finish

* perf: code improvements

* fix: findKeysChance is always a number

* perf: we don't need this

* docs: available vehicle types and categories with examples

* fix: prevent from executing the file twice, we use require

* fix: this throw error vehicle being 0, so we need to check

* Revert "fix: hot wiring/searching for keys causes ped to leave car occasionally"

This reverts commit 3f24871.
  • Loading branch information
Frowmza authored Aug 25, 2024
1 parent d23f314 commit a796ad6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 54 deletions.
6 changes: 4 additions & 2 deletions client/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ local function giveKeys(id, plate)
end
end

RegisterNetEvent('qb-vehiclekeys:client:GiveKeys', function(id, plate)
local function handKeys(id, plate)
local vehicle = plate and getVehicleByPlate(plate) or cache.vehicle or getVehicleInFront()
if not vehicle then return end
plate = plate or qbx.getVehiclePlate(vehicle)
Expand All @@ -56,4 +56,6 @@ RegisterNetEvent('qb-vehiclekeys:client:GiveKeys', function(id, plate)
local playerId = lib.getClosestPlayer(GetEntityCoords(cache.ped), 3, false)
giveKeys(playerId, plate)
end
end)
end

return handKeys
26 changes: 5 additions & 21 deletions client/functions.lua
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
local config = require 'config.client'
local functions = require 'shared.functions'
local getIsCloseToCoords = functions.getIsCloseToCoords
local getIsBlacklistedWeapon = functions.getIsBlacklistedWeapon
local getIsVehicleLockpickImmune = functions.getIsVehicleLockpickImmune
local getIsVehicleCarjackingImmune = functions.getIsVehicleCarjackingImmune
local getIsVehicleShared = functions.getIsVehicleShared

local public = {}

public.getIsVehicleCarjackingImmune = getIsVehicleCarjackingImmune -- to prevent circular-dependency error
public.getIsBlacklistedWeapon = getIsBlacklistedWeapon
public.getIsCloseToCoords = getIsCloseToCoords

function public.getIsVehicleShared(vehicle)
return getIsVehicleShared(vehicle)
end

---Grants keys for job shared vehicles
---@param vehicle number The entity number of the vehicle.
---@return boolean? `true` if the vehicle is shared for a player's job, `nil` otherwise.
Expand Down Expand Up @@ -125,11 +111,9 @@ end
local function getBoneCoords(entity, boneName)
local boneIndex = GetEntityBoneIndexByName(entity, boneName)

if boneIndex ~= -1 then
return GetWorldPositionOfEntityBone(entity, boneIndex)
else
return GetEntityCoords(entity)
end
return boneIndex ~= -1
and GetWorldPositionOfEntityBone(entity, boneIndex)
or GetEntityCoords(entity)
end

---Checks if any of the bones are close enough to the coords
Expand All @@ -141,7 +125,7 @@ end
local function getIsCloseToAnyBone(coords, entity, bones, maxDistance)
for i = 1, #bones do
local boneCoords = getBoneCoords(entity, bones[i])
if getIsCloseToCoords(coords, boneCoords, maxDistance) then
if functions.getIsCloseToCoords(coords, boneCoords, maxDistance) then
return true
end
end
Expand Down Expand Up @@ -227,7 +211,7 @@ function public.lockpickDoor(isAdvancedLockedpick, maxDistance, customChallenge)
if not isDriverSeatFree -- no one in the driver's seat
or not getIsCloseToAnyBone(pedCoords, vehicle, doorBones, maxDistance) -- the player's ped is close enough to the driver's door
or GetVehicleDoorLockStatus(vehicle) < 2 -- the vehicle is locked
or getIsVehicleLockpickImmune(vehicle)
or functions.getIsVehicleLockpickImmune(vehicle)
then return end

local skillCheckConfig = config.skillCheck[isAdvancedLockedpick and 'advancedLockpick' or 'lockpick']
Expand Down
34 changes: 19 additions & 15 deletions client/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ local toggleEngine = functions.toggleEngine
local lockpickDoor = functions.lockpickDoor
local areKeysJobShared = functions.areKeysJobShared
local getVehicleInFront = functions.getVehicleInFront
local getIsCloseToCoords = functions.getIsCloseToCoords
local getIsVehicleShared = functions.getIsVehicleShared
local getNPCPedsInVehicle = functions.getNPCPedsInVehicle
local sendPoliceAlertAttempt = functions.sendPoliceAlertAttempt
local getIsVehicleAccessible = functions.getIsVehicleAccessible
local getIsBlacklistedWeapon = functions.getIsBlacklistedWeapon

local getIsVehicleShared = sharedFunctions.getIsVehicleShared
local getIsCloseToCoords = sharedFunctions.getIsCloseToCoords
local getIsBlacklistedWeapon = sharedFunctions.getIsBlacklistedWeapon
local getIsVehicleAlwaysUnlocked = sharedFunctions.getIsVehicleAlwaysUnlocked
local getIsVehicleCarjackingImmune = functions.getIsVehicleCarjackingImmune
local getIsVehicleCarjackingImmune = sharedFunctions.getIsVehicleCarjackingImmune

-----------------------
---- Functions ----
Expand All @@ -36,12 +37,9 @@ local function setVehicleDoorLock(vehicle, state, anim)
lib.playAnim(cache.ped, 'anim@mp_player_intmenu@key_fob@', 'fob_click', 3.0, 3.0, -1, 49)
end

local lockstate
if state ~= nil then
lockstate = state and 2 or 1
else
lockstate = (GetVehicleDoorLockStatus(vehicle) % 2) + 1 -- (1 % 2) + 1 -> 2 (2 % 2) + 1 -> 1
end
local lockstate = state ~= nil
and (state and 2 or 1)
or (GetVehicleDoorLockStatus(vehicle) % 2) + 1 -- use ternary

TriggerServerEvent('qb-vehiclekeys:server:setVehLockState', NetworkGetNetworkIdFromEntity(vehicle), lockstate)
exports.qbx_core:Notify(locale(lockstate == 2 and 'notify.vehicle_locked' or 'notify.vehicle_unlocked'))
Expand Down Expand Up @@ -81,7 +79,7 @@ local function findKeys(vehicleModel, vehicleClass, plate, vehicle)
combat = true,
}
}) then
if math.random() <= vehicleConfig.findKeysChance[vehicle] then
if math.random() <= vehicleConfig.findKeysChance then
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
return true
else
Expand Down Expand Up @@ -145,6 +143,8 @@ local function makePedFlee(ped)
ClearPedTasks(ped)
SetPedFleeAttributes(ped, 0, false)
TaskReactAndFleePed(ped, cache.ped)
TaskSmartFleePed(ped, cache.ped, 100.0, -1, false, false)
ResetPedLastVehicle(ped) -- make ped forget about his last car, so he cant return to it
end

local function makePedsPutHandsUpAndScream(occupants, vehicle)
Expand All @@ -166,8 +166,7 @@ local function onCarjackSuccess(occupants, vehicle)
for p = 1, #occupants do
local ped = occupants[p]
CreateThread(function()
Wait(math.random(100, 500))
TaskLeaveVehicle(ped, vehicle, 0)
TaskLeaveVehicle(ped, vehicle, 256) -- flag 256 to leave door open
PlayPain(ped, 6, 0)
Wait(1250)
PlayPain(ped, math.random(7, 8), 0)
Expand Down Expand Up @@ -221,6 +220,7 @@ local function carjackVehicle(driver, vehicle)
}) then
if cache.weapon and isCarjacking then
local carjackChance = config.carjackChance[GetWeapontypeGroup(cache.weapon) --[[@as string]]] or 0.5
isCarjacking = false -- make this false to stop TaskVehicleTempAction from preventing ped to leave the car

if math.random() <= carjackChance then
onCarjackSuccess(occupants, vehicle)
Expand Down Expand Up @@ -378,8 +378,8 @@ AddEventHandler('ox_lib:cache:vehicle', function()
showHotwiringLabel(cache.vehicle)
end)

lib.onCache('vehicle', function (vehicle) ---for some reason the autolock works with this
end)
-- lib.onCache('vehicle', function (vehicle) ---for some reason the autolock works with this
-- end)

for _, info in pairs(config.sharedKeys) do
if info.enableAutolock then
Expand Down Expand Up @@ -414,6 +414,10 @@ AddEventHandler('onResourceStart', function(resourceName)
end
end)

RegisterNetEvent('qb-vehiclekeys:client:GiveKeys', function(id, plate)
require 'client.commands'(id, plate) -- we load command module when we actually need it

This comment has been minimized.

Copy link
@BerkieBb

BerkieBb Aug 25, 2024

Contributor

Reloading the file each time for a command seems very weird to me. Why would you do that?

This comment has been minimized.

Copy link
@BerkieBb

BerkieBb Aug 25, 2024

Contributor

Also, why not just add that to functions.lua since it's now only functions and doesn't do anything with commands on the client?

end)

--#region Backwards Compatibility ONLY -- Remove at some point --
RegisterNetEvent('qb-vehiclekeys:client:AddKeys', function(plate)
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
Expand Down
8 changes: 0 additions & 8 deletions config/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ return {
lockpick = {
default = normalLockpickSkillCheck,
class = {
[VehicleClass.COMPACTS] = normalLockpickSkillCheck,
[VehicleClass.SEDANS] = normalLockpickSkillCheck,
[VehicleClass.SUVS] = normalLockpickSkillCheck,
[VehicleClass.COUPES] = normalLockpickSkillCheck,
[VehicleClass.COMPACTS] = normalLockpickSkillCheck,
[VehicleClass.SEDANS] = normalLockpickSkillCheck,
[VehicleClass.SUVS] = normalLockpickSkillCheck,
Expand Down Expand Up @@ -219,10 +215,6 @@ return {
hotwire = {
default = normalLockpickSkillCheck,
class = {
[VehicleClass.COMPACTS] = normalLockpickSkillCheck,
[VehicleClass.SEDANS] = normalLockpickSkillCheck,
[VehicleClass.SUVS] = normalLockpickSkillCheck,
[VehicleClass.COUPES] = normalLockpickSkillCheck,
[VehicleClass.COMPACTS] = normalLockpickSkillCheck,
[VehicleClass.SEDANS] = normalLockpickSkillCheck,
[VehicleClass.SUVS] = normalLockpickSkillCheck,
Expand Down
27 changes: 22 additions & 5 deletions config/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,33 @@ return {
findKeysChance = 0.5,
},
---@type table<string, VehicleConfig>
categories = {

categories = { -- known categories: super, service, utility, helicopters, motorcycles, suvs, planes, sports, emergency, military, sportsclassics, compacts, sedans
-- super = {
-- noLock = false,
-- spawnLocked = 1.0,
-- carjackingImmune = false,
-- lockpickImmune = false,
-- shared = false,
-- removeNormalLockpickChance = 1.0,
-- removeAdvancedLockpickChance = 1.0,
-- findKeysChance = 0.5,
-- }
},
---@type table<VehicleType, VehicleConfig>
types = {

types = { -- known types: automobile, bike, boat, heli, plane, submarine, trailer, train
-- automobile = {
-- noLock = false,
-- spawnLocked = 1.0,
-- carjackingImmune = false,
-- lockpickImmune = false,
-- shared = false,
-- removeNormalLockpickChance = 1.0,
-- removeAdvancedLockpickChance = 1.0,
-- findKeysChance = 0.5,
-- }
},
---@type table<Hash, VehicleConfig>
models = {
-- Example:
-- [`stockade`] = {
-- spawnLocked = 0.5
-- }
Expand Down
7 changes: 4 additions & 3 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ ox_lib 'locale'
shared_scripts {
'@ox_lib/init.lua',
'@qbx_core/modules/lib.lua',
'shared/*.lua'
}

client_scripts {
'@qbx_core/modules/playerdata.lua',
'client/*.lua'
'client/main.lua'
}

server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/*.lua'
'server/main.lua'
}

files {
'client/*.lua',
'shared/*.lua',
'locales/*.json',
'config/client.lua',
'config/shared.lua'
Expand Down
2 changes: 2 additions & 0 deletions server/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ AddEventHandler('entityCreated', function (entity)

local vehicle = type == EntityType.Ped and GetVehiclePedIsIn(entity, false) or entity

if not DoesEntityExist(vehicle) then return end -- ped can be not in vehicle, so we need to check if vehicle is a entity, otherwise it will return 0

local chance = math.random()
local isLocked = (getIsVehicleInitiallyLocked(vehicle)
or (type == EntityType.Ped and chance < config.lockNPCDrivenCarsChance)
Expand Down

0 comments on commit a796ad6

Please sign in to comment.