1
0
Fork 0
forked from Simnation/Main
Main/resources/[carscripts]/community_bridge/lib/shells/client/shells.lua
2025-08-06 16:37:06 +02:00

269 lines
No EOL
9.2 KiB
Lua

local Target = Require('modules/target/_default/init.lua')
local ClientEntity = Require("lib/entities/client/client_entity.lua")
Shells = Shells or Require("lib/shells/client/config.lua")
Shells.All = Shells.All or {}
local insideShell = false
Shells.Events = {
OnSpawn = {},
OnRemove = {},
}
--Set Target lang or additionals
-- Shells.Target.Set('entrance', {
-- enter = {
-- label = 'yerp',
-- icon = 'fa-solid fa-door-open',
-- },
-- })
-- Shells.Target.Set('exit', {
-- leave = {
-- label = 'leerp',
-- icon = 'fa-solid fa-door-closed',
-- },
-- })
Shells.Event = {
Add = function(eventName, callback)
if Shells.Events[eventName] then
table.insert(Shells.Events[eventName], callback)
else
print(string.format("Shells.Event.Add: Invalid event name '%s'", eventName))
end
end,
Trigger = function(eventName, ...)
if Shells.Events[eventName] then
for _, callback in ipairs(Shells.Events[eventName]) do
callback(...)
end
else
print(string.format("Shells.Event.Trigger: Invalid event name '%s'", eventName))
end
end,
}
-- Shells.Event.Add('OnSpawn', function(pointData, entity)
-- print(string.format("Exterior point created with ID: %s, Type: %s, Entity: %s", pointData.id, pointData.type, entity))
-- end)
-- Shells.Event.Add('OnRemove', function(pointData)
-- print(string.format("Interior point created with ID: %s, Type: %s", pointData.id, pointData.type))
-- end)
function Shells.AddInteriorObject(shell, objectData)
objectData.OnSpawn = function(pointData)
Shells.Event.Trigger('OnSpawn', objectData, pointData.spawned)
local targetOptions = Shells.Target.Get(objectData.type, shell.id, objectData.id)
if targetOptions then
local size = vector3(objectData.distance / 2, objectData.distance / 2, objectData.distance / 2) -- this might need to be size
Target.AddBoxZone(objectData.id, objectData.coords, size, objectData.rotation.z, targetOptions, true)
end
end
objectData.OnRemove = function(pointData)
Shells.Event.Trigger('OnRemove', objectData, pointData.spawned)
Target.RemoveZone(objectData.id)
end
return ClientEntity.Register(objectData)
end
function Shells.SetupInterior(shell)
if not shell or not shell.interior then return end
for _, v in pairs(shell.interior) do
local pointData = Shells.AddInteriorObject(shell, v)
shell.interiorSpawned[pointData.id] = pointData
end
end
function Shells.SetupExterior(shell)
if not shell or not shell.exterior then return end
for k, v in pairs(shell.exterior) do
local pointData = Shells.AddInteriorObject(shell, v)
shell.exteriorSpawned[pointData.id] = pointData
end
end
function Shells.ClearInterior(shell)
if not shell or not shell.interiorSpawned then return end
for _, v in pairs(shell.interiorSpawned) do
ClientEntity.Unregister(v.id)
Target.RemoveZone(v.id)
end
shell.interiorSpawned = {}
end
function Shells.ClearExterior(shell)
if not shell or not shell.exteriorSpawned then return end
for _, v in pairs(shell.exteriorSpawned) do
ClientEntity.Unregister(v.id)
Target.RemoveZone(v.id)
end
shell.exteriorSpawned = {}
end
function Shells.New(data)
assert(data.id, "Shells.Create: 'id' is required")
assert(data.model, "Shells.Create: 'shellModel' is required")
assert(data.coords, "Shells.Create: 'coords' is required")
local exterior = data.exterior or {}
local exteriorSpawned = {}
for k, v in pairs(exterior or {}) do
v.OnSpawn = function(pointData)
Shells.Event.Trigger('OnSpawn', v, pointData.spawned)
local targetOptions = Shells.Target.Get(v.type, data.id, v.id)
if targetOptions then
local size = vector3(v.distance / 2, v.distance / 2, v.distance / 2)
Target.AddBoxZone(v.id, v.coords, size, v.rotation.z, targetOptions, true)
end
end
v.OnRemove = function(pointData)
Shells.Event.Trigger('OnRemove', v, pointData.spawned)
Target.RemoveZone(v.id)
end
local pointData = ClientEntity.Register(v)
exteriorSpawned[pointData.id] = pointData
end
data.interiorSpawned = {}
data.exteriorSpawned = exteriorSpawned
Shells.All[data.id] = data
return data
end
local returnPoint = nil
function Shells.Enter(id, entranceId)
local shell = Shells.All[id]
if not shell then
print(string.format("Shells.Spawn: Shell with ID '%s' not found", id))
return
end
local entrance = shell.interior[entranceId]
if not entrance then
print(string.format("Shells.Enter: Entrance with ID '%s' not found in shell '%s'", entranceId, id))
return
end
local ped = PlayerPedId()
returnPoint = GetEntityCoords(ped)
DoScreenFadeOut(1000)
Wait(1000)
local entranceCoords = entrance.coords
SetEntityCoords(ped, entranceCoords.x, entranceCoords.y, entranceCoords.z, false, false, false, true)
FreezeEntityPosition(ped, true)
local oldShell = insideShell and Shells.All[insideShell]
if oldShell?.id ~= id then
Shells.ClearExterior(oldShell)
Shells.ClearInterior(oldShell)
end
Shells.ClearExterior(shell)
Shells.SetupInterior(shell)
ClientEntity.Register(shell)
Wait(1000) -- Wait for the fade out to complete
FreezeEntityPosition(ped, false)
DoScreenFadeIn(1000)
insideShell = shell.id
end
function Shells.Exit(id, exitId)
local shell = Shells.All[id]
if not shell then
print(string.format("Shells.Exit: Shell with ID '%s' not found", id))
return
end
local oldCoords = GetEntityCoords(PlayerPedId())
local oldPoint = shell.exterior[exitId]
if not oldPoint then
print(string.format("Shells.Exit: Old point with ID '%s' not found in shell '%s'", exitId, id))
return
end
DoScreenFadeOut(1000)
Wait(1000)
SetEntityCoords(PlayerPedId(), oldPoint.coords.x, oldPoint.coords.y, oldPoint.coords.z, false, false, false, true)
FreezeEntityPosition(PlayerPedId(), true)
Shells.ClearInterior(shell)
ClientEntity.Unregister(shell.id)
Shells.SetupExterior(shell)
shell.interiorSpawned = {}
FreezeEntityPosition(PlayerPedId(), false)
DoScreenFadeIn(1000)
insideShell = false
end
function Shells.Inside()
return insideShell
end
RegisterNetEvent('community_bridge:client:CreateShell', function(shell)
Shells.New(shell)
end)
RegisterNetEvent('community_bridge:client:EnterShell', function(shellId, entranceId, oldId)
local shell = Shells.All[shellId]
if not shell then
print(string.format("Shells.EnterShell: Shell with ID '%s' not found", shellId))
return
end
Shells.Enter(shellId, entranceId, oldId)
end)
RegisterNetEvent('community_bridge:client:ExitShell', function(shellId, oldId)
local shell = Shells.All[shellId]
print(string.format("Shells.ExitShell: Exiting shell '%s'", shellId))
if not shell then
print(string.format("Shells.ExitShell: Shell with ID '%s' not found", shellId))
return
end
Shells.Exit(shellId, oldId)
end)
RegisterNetEvent('community_bridge:client:AddObjectsToShell', function (shellId, interiorObjects, exteriorObjects)
local shell = Shells.All[shellId]
print(string.format("Shells.AddObjectsToShell: Adding objects to shell '%s'", shellId),
json.encode({interiorObjects = interiorObjects, exteriorObjects = exteriorObjects}, { indent = true }))
if not shell then
print(string.format("Shells.AddObjectsToShell: Shell with ID '%s' not found", shellId))
return
end
local insideShell = Shells.Inside()
if interiorObjects then
for _, obj in pairs(interiorObjects) do
if not shell.interior[obj.id] then
shell.interior[obj.id] = obj
if insideShell and insideShell == shellId then
local pointData = Shells.AddInteriorObject(shell, obj)
shell.interiorSpawned[pointData.id] = pointData
end
end
end
end
if exteriorObjects then
for _, obj in pairs(exteriorObjects) do
if not shell.exterior[obj.id] then
shell.exterior[obj.id] = obj
if not insideShell then
local pointData = Shells.AddInteriorObject(shell, obj)
shell.exteriorSpawned[pointData.id] = pointData
end
end
end
end
end)
RegisterNetEvent('community_bridge:client:CreateShells', function(shells)
print("Shells.CreateShells: Creating shells")
for _, shell in pairs(shells) do
Shells.New(shell)
end
end)
-- TriggerClientEvent('community_bridge:client:CreateShells', -1, toClient)
-- TriggerClientEvent('community_bridge:client:ExitShell', src, oldId)
AddEventHandler('onResourceStart', function(resource)
if resource == GetCurrentResourceName() then
DoScreenFadeIn(1000) -- Fade in when resource stops
if not returnPoint then return end
SetEntityCoords(PlayerPedId(), returnPoint.x, returnPoint.y, returnPoint.z, false, false, false, true)
end
end)