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) | 
