ed
This commit is contained in:
parent
8054759c73
commit
ffaf33c966
7 changed files with 338 additions and 12 deletions
245
resources/[Developer]/[Nordi]/nordi_kayaktrailer/client.lua
Normal file
245
resources/[Developer]/[Nordi]/nordi_kayaktrailer/client.lua
Normal file
|
@ -0,0 +1,245 @@
|
|||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
local loadedKayaks = {}
|
||||
local currentTrailer = nil
|
||||
|
||||
-- Function to check if a model is a kayak
|
||||
local function IsKayakModel(model)
|
||||
for _, kayakModel in ipairs(Config.KayakModels) do
|
||||
if GetHashKey(kayakModel) == model then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Function to get nearby kayak
|
||||
local function GetNearbyKayak()
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
local kayak = nil
|
||||
local minDistance = Config.InteractionRange
|
||||
|
||||
for _, entity in ipairs(GetGamePool('CVehicle')) do
|
||||
if IsKayakModel(GetEntityModel(entity)) then
|
||||
local distance = #(playerCoords - GetEntityCoords(entity))
|
||||
if distance < minDistance then
|
||||
minDistance = distance
|
||||
kayak = entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return kayak
|
||||
end
|
||||
|
||||
-- Function to get nearby trailer
|
||||
local function GetNearbyTrailer()
|
||||
local playerPed = PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
local trailer = nil
|
||||
local minDistance = Config.InteractionRange
|
||||
|
||||
for _, entity in ipairs(GetGamePool('CVehicle')) do
|
||||
if GetEntityModel(entity) == GetHashKey(Config.TrailerModel) then
|
||||
local distance = #(playerCoords - GetEntityCoords(entity))
|
||||
if distance < minDistance then
|
||||
minDistance = distance
|
||||
trailer = entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return trailer
|
||||
end
|
||||
|
||||
-- Function to load kayak onto trailer
|
||||
local function LoadKayakOntoTrailer(trailer, kayak)
|
||||
if not trailer or not kayak then return end
|
||||
|
||||
local trailerNetId = NetworkGetNetworkIdFromEntity(trailer)
|
||||
local kayakNetId = NetworkGetNetworkIdFromEntity(kayak)
|
||||
|
||||
-- Check if trailer already has max kayaks
|
||||
if #loadedKayaks >= Config.MaxKayaks then
|
||||
QBCore.Functions.Notify("Trailer rack is already fully loaded with kayaks", "error")
|
||||
return
|
||||
end
|
||||
|
||||
-- Add kayak to loaded kayaks
|
||||
table.insert(loadedKayaks, kayakNetId)
|
||||
|
||||
-- Update kayak position on trailer
|
||||
local position = Config.KayakPositions[#loadedKayaks]
|
||||
local trailerCoords = GetEntityCoords(trailer)
|
||||
local trailerHeading = GetEntityHeading(trailer)
|
||||
|
||||
-- Calculate world position based on trailer position and offset
|
||||
local kayakX = trailerCoords.x + (math.cos(math.rad(trailerHeading)) * position.x) - (math.sin(math.rad(trailerHeading)) * position.y)
|
||||
local kayakY = trailerCoords.y + (math.sin(math.rad(trailerHeading)) * position.x) + (math.cos(math.rad(trailerHeading)) * position.y)
|
||||
local kayakZ = trailerCoords.z + position.z
|
||||
local kayakHeading = trailerHeading + position.heading
|
||||
|
||||
-- Set kayak position and attach to trailer
|
||||
SetEntityCoords(kayak, kayakX, kayakY, kayakZ, false, false, false, false)
|
||||
SetEntityHeading(kayak, kayakHeading)
|
||||
|
||||
-- Attach kayak to trailer
|
||||
AttachEntityToEntity(kayak, trailer, 0, position.x, position.y, position.z, 0.0, 0.0, position.heading, true, false, true, false, 0, true)
|
||||
|
||||
-- Display which rack position was loaded
|
||||
local side = #loadedKayaks <= 3 and "left" or "right"
|
||||
local level = (#loadedKayaks - 1) % 3 + 1
|
||||
local levelNames = {"bottom", "middle", "top"}
|
||||
|
||||
QBCore.Functions.Notify("Kayak loaded onto " .. levelNames[level] .. " rack, " .. side .. " side", "success")
|
||||
|
||||
-- Save current trailer
|
||||
currentTrailer = trailerNetId
|
||||
|
||||
-- Sync with server
|
||||
TriggerServerEvent('kayak_trailer:syncLoadedKayaks', trailerNetId, loadedKayaks)
|
||||
end
|
||||
|
||||
-- Function to unload kayak from trailer
|
||||
local function UnloadKayakFromTrailer(trailer)
|
||||
if not trailer or #loadedKayaks == 0 then return end
|
||||
|
||||
local trailerNetId = NetworkGetNetworkIdFromEntity(trailer)
|
||||
|
||||
-- Get last kayak
|
||||
local kayakNetId = loadedKayaks[#loadedKayaks]
|
||||
local kayak = NetworkGetEntityFromNetworkId(kayakNetId)
|
||||
|
||||
-- Get position info for notification
|
||||
local side = #loadedKayaks <= 3 and "left" or "right"
|
||||
local level = (#loadedKayaks - 1) % 3 + 1
|
||||
local levelNames = {"bottom", "middle", "top"}
|
||||
|
||||
-- Remove from loaded kayaks
|
||||
table.remove(loadedKayaks, #loadedKayaks)
|
||||
|
||||
-- Detach kayak from trailer
|
||||
DetachEntity(kayak, true, true)
|
||||
|
||||
-- Place kayak behind trailer
|
||||
local trailerCoords = GetEntityCoords(trailer)
|
||||
local trailerHeading = GetEntityHeading(trailer)
|
||||
local offsetX = -3.0 -- 3 meters behind trailer
|
||||
|
||||
local kayakX = trailerCoords.x - (math.cos(math.rad(trailerHeading)) * offsetX)
|
||||
local kayakY = trailerCoords.y - (math.sin(math.rad(trailerHeading)) * offsetX)
|
||||
local kayakZ = trailerCoords.z
|
||||
|
||||
SetEntityCoords(kayak, kayakX, kayakY, kayakZ, false, false, false, false)
|
||||
SetEntityHeading(kayak, trailerHeading)
|
||||
|
||||
QBCore.Functions.Notify("Kayak unloaded from " .. levelNames[level] .. " rack, " .. side .. " side", "success")
|
||||
|
||||
-- Sync with server
|
||||
TriggerServerEvent('kayak_trailer:syncLoadedKayaks', trailerNetId, loadedKayaks)
|
||||
end
|
||||
|
||||
-- Initialize qb-target
|
||||
Citizen.CreateThread(function()
|
||||
-- Target for loading kayaks onto trailer
|
||||
exports['qb-target']:AddTargetModel(Config.TrailerModel, {
|
||||
options = {
|
||||
{
|
||||
type = "client",
|
||||
event = "kayak_trailer:loadKayak",
|
||||
icon = "fas fa-truck-loading",
|
||||
label = "Load Kayak to Rack",
|
||||
canInteract = function()
|
||||
local kayak = GetNearbyKayak()
|
||||
return kayak ~= nil and #loadedKayaks < Config.MaxKayaks
|
||||
end
|
||||
},
|
||||
{
|
||||
type = "client",
|
||||
event = "kayak_trailer:unloadKayak",
|
||||
icon = "fas fa-dolly",
|
||||
label = "Unload Kayak from Rack",
|
||||
canInteract = function()
|
||||
return #loadedKayaks > 0
|
||||
end
|
||||
}
|
||||
},
|
||||
distance = Config.InteractionRange
|
||||
})
|
||||
|
||||
-- Target for kayaks
|
||||
for _, model in ipairs(Config.KayakModels) do
|
||||
exports['qb-target']:AddTargetModel(model, {
|
||||
options = {
|
||||
{
|
||||
type = "client",
|
||||
event = "kayak_trailer:loadKayak",
|
||||
icon = "fas fa-truck-loading",
|
||||
label = "Load onto Trailer Rack",
|
||||
canInteract = function()
|
||||
local trailer = GetNearbyTrailer()
|
||||
return trailer ~= nil and #loadedKayaks < Config.MaxKayaks
|
||||
end
|
||||
}
|
||||
},
|
||||
distance = Config.InteractionRange
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Event handlers
|
||||
RegisterNetEvent('kayak_trailer:loadKayak', function()
|
||||
local trailer = GetNearbyTrailer()
|
||||
local kayak = GetNearbyKayak()
|
||||
|
||||
if trailer and kayak then
|
||||
LoadKayakOntoTrailer(trailer, kayak)
|
||||
else
|
||||
QBCore.Functions.Notify("No trailer or kayak nearby", "error")
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('kayak_trailer:unloadKayak', function()
|
||||
local trailer = GetNearbyTrailer()
|
||||
|
||||
if trailer then
|
||||
UnloadKayakFromTrailer(trailer)
|
||||
else
|
||||
QBCore.Functions.Notify("No trailer nearby", "error")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Sync loaded kayaks from server
|
||||
RegisterNetEvent('kayak_trailer:syncLoadedKayaksClient', function(trailerNetId, kayakList)
|
||||
if NetworkDoesNetworkIdExist(trailerNetId) then
|
||||
local trailer = NetworkGetEntityFromNetworkId(trailerNetId)
|
||||
|
||||
-- Clear existing kayaks
|
||||
for _, kayakNetId in ipairs(loadedKayaks) do
|
||||
if NetworkDoesNetworkIdExist(kayakNetId) then
|
||||
local kayak = NetworkGetEntityFromNetworkId(kayakNetId)
|
||||
if DoesEntityExist(kayak) then
|
||||
DetachEntity(kayak, true, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update loaded kayaks
|
||||
loadedKayaks = kayakList
|
||||
|
||||
-- Reattach kayaks
|
||||
for i, kayakNetId in ipairs(loadedKayaks) do
|
||||
if NetworkDoesNetworkIdExist(kayakNetId) then
|
||||
local kayak = NetworkGetEntityFromNetworkId(kayakNetId)
|
||||
if DoesEntityExist(kayak) then
|
||||
local position = Config.KayakPositions[i]
|
||||
AttachEntityToEntity(kayak, trailer, 0, position.x, position.y, position.z, 0.0, 0.0, position.heading, true, false, true, false, 0, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
currentTrailer = trailerNetId
|
||||
end
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue