local camCache = {} --- Creates a temporary camera at a specified position, pointing towards given coordinates. -- -- This function creates a camera at a position relative to an entity or at a specified position and orients it to look at the target coordinates. -- The camera is only created if `Config.Crafting.craftCam` is enabled in the configuration. -- ---@param ent entityId|coords The base position for the camera. Can be an entity handle or a `vector3` position. -- If `ent` is an entity, the camera position is calculated as an offset from the entity's position using `GetOffsetFromEntityInWorldCoords`. -- If `ent` is a `vector3`, it is used directly as the camera's position. -- ---@param coords vector3|entityId The target `vector3` coordinates that the camera will point at. -- ---@return camID number The handle of the created camera, or `nil` if the camera was not created (e.g., if `Config.Crafting.craftCam` is `false`). -- ---@usage -- ```lua -- local cam = createTempCam(entity, targetCoords) -- ``` function createTempCam(ent, coords) local camID = nil if (Config.Crafting and Config.Crafting.craftCam) or Config.System.enableCam then -- if not ent or coords are provided, make a basic camera to control later if not ent and not coords then camID = CreateCam("DEFAULT_SCRIPTED_CAMERA", true) camCache[#camCache+1] = camID return camID end -- if received a vector3 or vector4 use those coords for origin point, otherwrise get offset from entity local camCoords = type(ent) ~= "number" and ent or GetOffsetFromEntityInWorldCoords(ent, 1.0, -0.3, 0.8) -- Create the camera camID = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", camCoords.x, camCoords.y, camCoords.z + 0.5, 1.0, 0.0, 0.0, 60.00, false, 0) camCache[#camCache+1] = camID debugPrint("^6Bridge^7: ^2Custom Camera Created", camID) --if type(coords) == "number" then -- SetCamCoord(camID, GetCamCoord(camID) + vec3(0, 0, 1.0)) --end if coords then camLookAt(camID, coords) end end return camID end local cacheCameraEffect = {} local cachePrevCam = nil --- Activates and starts rendering the temporary camera. -- -- This function sets the specified camera as active and begins rendering it with a smooth transition. -- The camera is only activated if `Config.Crafting.craftCam` is enabled in the configuration. -- ---@param cam number The handle of the camera to activate and render. ---@param renderTime number The handle of the camera to activate and render. ---@param loadScene boolean The handle of the camera to activate and render. ---@param filter table The filter or postFx to render when starting the camera. -- ---@usage -- ```lua -- startTempCam(camID, 1000, true, { postFx = "HeistCelebEnd" }) -- ``` function startTempCam(cam, renderTime, loadScene, filter, switchCam) if cam and DoesCamExist(cam) then debugPrint("Starting camera") -- if moving from a cached previous cam, or you've sent a camre id for it to switch from, interpolate to it if switchCam or cachePrevCam then SetCamActiveWithInterp(cam, cachePrevCam, renderTime or 1000, 0, 0) SetCamActive(cachePrevCam, false) -- Set previous cam inactive (shouldn't be needed but just in case) else SetCamActive(cam, true) end cachePrevCam = cam -- Clear previous filters if cacheCameraEffect.postFx then AnimpostfxStop(cacheCameraEffect.postFx) cacheCameraEffect.postFx = nil end if cacheCameraEffect.timecycle then ClearTimecycleModifier() cacheCameraEffect.timecycle = nil end -- Apply filters (timecycle) here as requested if filter and filter.modifier then SetTimecycleModifier(filter.modifier) SetTimecycleModifierStrength((filter.strength or 1.0) + 0.0) cacheCameraEffect.timecycle = true end if filter and filter.postFx then AnimpostfxPlay(filter.postFx, 0, filter.loop and true or false) cacheCameraEffect.postFx = filter.postFx end if loadScene then loadLocation(cam, nil, 100.0) end RenderScriptCams(true, true, renderTime or 1000, true, true) end end -- Follow cam or coords function camLookAt(cam, entCoords) if cam and DoesCamExist(cam) and entCoords then if type(entCoords) ~= "number" then PointCamAtCoord(cam, entCoords.xyz) else PointCamAtEntity(cam, entCoords) end end end function loadLocation(cam, pos, radius) local pos = pos or GetCamCoord(cam) SetFocusPosAndVel(pos.x, pos.y, pos.z, 0.0, 0.0, 0.0) RequestCollisionAtCoord(pos.x, pos.y, pos.z) NewLoadSceneStart(pos.x, pos.y, pos.z, 0.0, 0.0, 0.0, radius or 100.0, 0) local t0 = GetGameTimer() while not IsNewLoadSceneLoaded() and (GetGameTimer() - t0) < 2000 do RequestCollisionAtCoord(pos.x, pos.y, pos.z) Wait(0) end NewLoadSceneStop() end function clearLoadLocation() ClearFocus() NewLoadSceneStop() end --- Deactivates the temporary camera and stops rendering. -- -- This function waits for one second, then stops rendering script cameras and destroys all cameras. -- The delay allows for any transitions or animations to complete. -- -- The camera is only deactivated if `Config.Crafting.craftCam` is enabled in the configuration. -- ---@usage -- ```lua -- stopTempCam() -- ``` function stopTempCam(renderTime) CreateThread(function() Wait(1000) cachePrevCam = nil -- Clear previous filters if cacheCameraEffect.postFx then AnimpostfxStop(cacheCameraEffect.postFx) cacheCameraEffect.postFx = nil end if cacheCameraEffect.timecycle then ClearTimecycleModifier() cacheCameraEffect.timecycle = nil end RenderScriptCams(false, true, renderTime or 500, true, true) clearLoadLocation() Wait(renderTime or 500) for i = 1, #camCache do DestroyCam(camCache[i], true) end camCache = {} end) end function createCam(...) return createTempCam(...) end function startCam(...) return startTempCam(...) end function stopCam(...) return stopTempCam(...) end