269 lines
		
	
	
		
			No EOL
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			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) |