diff --git a/client/clientFunctions.lua b/client/clientFunctions.lua new file mode 100644 index 0000000..7914650 --- /dev/null +++ b/client/clientFunctions.lua @@ -0,0 +1,87 @@ +--- Checks if the current player has a key for the specified vehicle. +---@param vehicle number The entity number of the vehicle to check for a key. +---@return boolean True if the player has a key for the vehicle, false otherwise. +function HasKey(vehicle) + return Entity(vehicle).state.keys[QBX.PlayerData.citizenid] +end + +--- Gives a key to a target player for the specified vehicle. +---@param targetPlayerId number The ID of the target player who will receive the key. +---@param vehicle number The entity number of the vehicle for which the key is being given. +function GiveKey(targetPlayerId, vehicle) + if not targetPlayerId or not vehicle then return end + if HasKey(vehicle) then + lib.callback('vehiclekeys:server:GiveKey', false, function(success) + if success then + lib.notify({ + description = Lang:t("notify.gave_keys"), + type = 'success' + }) + else + lib.notify({ + description = Lang:t("notify.failed_givekey"), + type = 'error' + }) + end + end, NetworkGetNetworkIdFromEntity(vehicle), targetPlayerId) + else + lib.notify({ + description = Lang:t("notify.no_keys"), + type = 'error' + }) + end +end + +--- Removes a key from a target player for the specified vehicle. +---@param targetPlayerId number The ID of the target player from whom the key is being removed. +---@param vehicle number The entity number of the vehicle from which the key is being removed. +function RemoveKey(targetPlayerId, vehicle) + if not targetPlayerId or not vehicle then return end + if HasKey(vehicle) then + lib.callback('vehiclekeys:server:RemoveKey', false, function(success) + if success then + lib.notify({ + description = Lang:t("notify.success_removekey"), + type = 'success' + }) + else + lib.notify({ + description = Lang:t("notify.failed_removekey"), + type = 'success' + }) + end + end, NetworkGetNetworkIdFromEntity(vehicle), targetPlayerId) + else + lib.notify({ + description = Lang:t("notify.no_keys"), + type = 'error' + }) + end +end + +function OpenCloseVehicleDoor(vehicle) + if not vehicle then return end + if HasKey(vehicle) then + lib.callback('vehiclekeys:server:SetDoorState', false, function(success) + if not success then + lib.notify({ + description = Lang:t("notify.failed_doorstate"), + type = 'error' + }) + else + if success == 0 then + -- You opened the door + -- call client natives here? + else + -- You closed the door + -- call client natives here? + end + end + end, NetworkGetNetworkIdFromEntity(vehicle)) + else + lib.notify({ + description = Lang:t("notify.no_keys"), + type = 'error' + }) + end +end diff --git a/fxmanifest.lua b/fxmanifest.lua index 72b8052..78b5123 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -1,6 +1,7 @@ fx_version 'cerulean' game 'gta5' lua54 'yes' +use_experimental_fxv2_oal 'yes' description 'https://github.com/Qbox-project/qbx-vehiclekeys' version '1.0.0' @@ -10,10 +11,18 @@ shared_scripts { '@qbx_core/shared/locale.lua', 'locales/en.lua', 'locales/*.lua', - 'config.lua', + 'shared/config.lua', + 'shared/functions.lua', +} +client_scripts { + 'client/main.lua', + 'client/clientFunctions.lua' +} +server_script { + 'server/main.lua', + 'server/serverFunctions.lua', + 'server/commands.lua', } -client_script 'client/main.lua' -server_script 'server/main.lua' modules { 'qbx_core:playerdata', diff --git a/server/commands.lua b/server/commands.lua new file mode 100644 index 0000000..eaa6060 --- /dev/null +++ b/server/commands.lua @@ -0,0 +1,67 @@ +lib.addCommand('givekeys', { + help = Lang:t("addcom.givekeys"), + params = { + { + name = Lang:t("addcom.givekeys_id"), + type = 'number', + help = Lang:t("addcom.givekeys_id_help"), + optional = true + }, + }, + restricted = false, +}, function (source, args) + local src = source + TriggerClientEvent('qb-vehiclekeys:client:GiveKeys', src, args.id) +end) + +lib.addCommand('addkeys', { + help = Lang:t("addcom.addkeys"), + params = { + { + name = 'id', + type = 'number', + help = Lang:t("addcom.addkeys_id_help"), + optional = true + }, + { + name = 'plate', + type = 'string', + help = Lang:t("addcom.addkeys_plate_help"), + optional = true + }, + }, + restricted = 'group.admin', +}, function (source, args) + local src = source + if not args.id or not args.plate then + exports.qbx_core:Notify(src, Lang:t("notify.fpid")) + return + end + GiveKeys(args.id, args.plate) +end) + +lib.addCommand('removekeys', { + help = Lang:t("addcom.remove_keys"), + params = { + { + name = 'id', + type = 'number', + help = Lang:t("addcom.remove_keys_id_help"), + optional = true + }, + { + name = 'plate', + type = 'string', + help = Lang:t("addcom.remove_keys_plate_help"), + optional = true + } + }, + restricted = 'group.admin', +}, function (source, args) + local src = source + if not args.id or not args.plate then + exports.qbx_core:Notify(src, Lang:t("notify.fpid")) + return + end + RemoveKeys(args.id, args.plate) +end) \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 7060235..a2c1143 100644 --- a/server/main.lua +++ b/server/main.lua @@ -87,72 +87,4 @@ function HasKeys(id, plate) return true end return false -end - -lib.addCommand('givekeys', { - help = Lang:t("addcom.givekeys"), - params = { - { - name = Lang:t("addcom.givekeys_id"), - type = 'number', - help = Lang:t("addcom.givekeys_id_help"), - optional = true - }, - }, - restricted = false, -}, function (source, args) - local src = source - TriggerClientEvent('qb-vehiclekeys:client:GiveKeys', src, args.id) -end) - -lib.addCommand('addkeys', { - help = Lang:t("addcom.addkeys"), - params = { - { - name = 'id', - type = 'number', - help = Lang:t("addcom.addkeys_id_help"), - optional = true - }, - { - name = 'plate', - type = 'string', - help = Lang:t("addcom.addkeys_plate_help"), - optional = true - }, - }, - restricted = 'group.admin', -}, function (source, args) - local src = source - if not args.id or not args.plate then - exports.qbx_core:Notify(src, Lang:t("notify.fpid")) - return - end - GiveKeys(args.id, args.plate) -end) - -lib.addCommand('removekeys', { - help = Lang:t("addcom.remove_keys"), - params = { - { - name = 'id', - type = 'number', - help = Lang:t("addcom.remove_keys_id_help"), - optional = true - }, - { - name = 'plate', - type = 'string', - help = Lang:t("addcom.remove_keys_plate_help"), - optional = true - } - }, - restricted = 'group.admin', -}, function (source, args) - local src = source - if not args.id or not args.plate then - exports.qbx_core:Notify(src, Lang:t("notify.fpid")) - return - end - RemoveKeys(args.id, args.plate) -end) +end \ No newline at end of file diff --git a/server/serverFunctions.lua b/server/serverFunctions.lua new file mode 100644 index 0000000..c32467a --- /dev/null +++ b/server/serverFunctions.lua @@ -0,0 +1,86 @@ +--- Checks for the existence of a key. +---@param entity number The entity (vehicle) where we check for the existence of a key. +---@param citizenid string The CitizenID of the player whose key we check for. +function HasKey(entity, citizenid) + return Entity(entity).state.keys[citizenid] +end + +--- Adds a key to the selected vehicle entity and returns a success status. +---@param entity number The entity (vehicle) to which the key is added. +---@param citizenid string The CitizenID of the player whose key is being added. +---@param doorState number | nil -- Sets the doorState of the vehicle if present +---@return boolean | nil `true` if the key was successfully added, `nil` otherwise. +function GiveKey(entity, citizenid, doorState) + if not entity or type(entity) ~= 'number' or not citizenid or type(citizenid) ~= 'string' then + return + end + + local ent = Entity(entity) + if not ent then return end + + if doorState then + ent.state:set('doorState', doorState, true) + end + + local keyholders = ent.state.keys or {} + + if not keyholders[citizenid] then + keyholders[citizenid] = true + ent.state:set('keys', keyholders, true) + return true + end +end + +--- Removes a key from the selected vehicle entity and returns a success status. +---@param entity number The entity (vehicle) from which the key is removed. +---@param citizenid string The CitizenID of the player whose key is being removed. +---@return boolean | nil `true` if the key was successfully removed, `nil` otherwise. +function RemoveKey(entity, citizenid) + if not entity or type(entity) ~= 'number' or not citizenid or type(citizenid) ~= 'string' then + return + end + + local ent = Entity(entity) + if not ent then return end + + local keyholders = ent.state.keys + if keyholders and keyholders[citizenid] then + keyholders[citizenid] = nil + ent.state:set('keys', keyholders, true) + return true + end +end + +--- Sets the door state of the vehicle. +---@param entity number The entity (vehicle) for which the door state is updated. +---@param doorState number The door state number to update. +---@return boolean | nil `true` if the door state was successfully updated, `nil` otherwise. +function SetDoorState(entity, doorState) + if not entity or type(entity) ~= 'number' or not doorState or type(doorState) ~= 'number' then + return + end + + local ent = Entity(entity) + if not ent then return end + + ent.state:set('doorState', doorState, true) + return true +end + +---@param entity number The entity (vehicle) for which the door state is updated. +---@return number | nil returns the new doorState of the vehicle +function OpenCloseDoorState(entity) + if not entity or type(entity) ~= 'number' then + return + end + + local ent = Entity(entity) + if not ent then return end + if ent.state.doorState and ent.state.doorState ~= 0 then + ent.state:set('doorState', 1, true) + return 1 + else + ent.state:set('doorState', 0, true) + return 0 + end +end \ No newline at end of file diff --git a/config.lua b/shared/config.lua similarity index 100% rename from config.lua rename to shared/config.lua diff --git a/shared/functions.lua b/shared/functions.lua new file mode 100644 index 0000000..7d7b159 --- /dev/null +++ b/shared/functions.lua @@ -0,0 +1,7 @@ +--- Checks if the given two coordinates are close to each other based on distance. +---@param coord1 vector3[] The first set of coordinates. +---@param coord2 vector3[] The second set of coordinates. +---@param distance number The maximum allowed distance for them to be considered close. +function IsCloseToCoords(coord1, coord2, distance) + return #(coord1 - coord2) < distance +end \ No newline at end of file