local disablePlayerFiring = DisablePlayerFiring local isControlJustPressed = IsControlJustPressed local isDisabledControlJustPressed = IsDisabledControlJustPressed local isControlJustReleased = IsControlJustReleased local isDisabledControlJustReleased = IsDisabledControlJustReleased local getCursorHitCoords = Utils.getCursorHitCoords local decorateState = { active = false, currentObject = nil, hide = false, focus = false, keepInput = false, objects = {}, currentPage = "dynamic", mode = "mgizmo", freeCamera = false, cameraFocus = false } local decorateMeta = {} decorateMeta.__index = function(_, key) return decorateState[key] end decorateMeta.__newindex = function(_, key, value) decorateState[key] = value if key == "currentObject" then if value then if decorateState.currentPage == "stash" then SendReactMessage("select_stash_item", value.stashId) end if DoesEntityExist(value.handle) then decorate:selectEntity(value.handle) else decorate:deselectEntity() end else decorate:deselectEntity() end end end decorate = setmetatable({}, decorateMeta) local CAMERA_LERP_SPEED = 0.01 function decorate.instructional(self, extraActions) if not self.active then return end if DrawingInstructional then DrawingInstructional = false end local actions = { { key = "place_object_on_ground", label = "Place Object on Ground" }, { key = "toggle_cursor", label = "Toggle Cursor" }, { key = "toggle_free_mode", label = "Toggle Free Mode" }, { key = "toggle_editor_mode", label = "Toggle Editor Mode" }, { key = "toggle_gizmo_mode", label = "Toggle Gizmo Mode" }, { key = "toggle_free_camera", label = "Toggle Free Camera" } } local currentObj = self.currentObject if not (currentObj and currentObj.stashId) then actions[#actions + 1] = { key = "done", label = "Buy Object" } end if extraActions then for _, action in pairs(extraActions) do actions[#actions + 1] = action end end Utils.DrawInstructional(actions) end function decorate.open(self) if self.active then return Debug("decorate:open ::: decorate is already active") end if not currentlyInGarage then return Notification(i18n.t("decorate.not_in_garage"), "error") end local isAvailable = lib.callback.await("garages:decorate:getDecorationAvailable", false, currentlyInGarage) if not isAvailable then return Notification(i18n.t("decorate.decoration_not_available"), "error") end TriggerServerEvent("garages:decorate:updateDecorationUsedBy", currentlyInGarage, true) self.active = true self:toggleFreeCamera(true) self:setFocus(true) DisableIdleCamera(true) SendReactMessage("toggle_decorate_menu", { visible = true, navigation = Config.FurnitureNavigation, furniture = Config.Furniture, enableShop = Config.EnableF3Shop }) ToggleHud(false) TriggerServerEvent("garages:fiveguard:freecam", true) self:instructional() self:getObjects(currentlyInGarage) gizmo:handleCameraUpdate() mgizmo:loop() self:handleControls() self:checkDistance() end function decorate.close(self) if not self.active then return end self.active = false ToggleHud(true) DisableIdleCamera(false) self:removeCurrentObject() self.active = false Utils.RemoveInstructional() SetNuiFocus(false, false) SetNuiFocusKeepInput(false) SendReactMessage("toggle_decorate_menu", { visible = false }) self.focus = false self.keepInput = false TriggerServerEvent("garages:fiveguard:freecam", false) TriggerServerEvent("garages:decorate:updateDecorationUsedBy", currentlyInGarage, false) end function decorate.checkDistance(self) if not Config.MaximumDistanceForDecorate then return end local startCoords = GetEntityCoords(cache.ped) CreateThread(function() while self.active and currentlyInGarage do local camCoords = GetFinalRenderedCamCoord() local distance = #(camCoords - startCoords) if distance > Config.MaximumDistanceForDecorate then Notification(i18n.t("decorate.too_far"), "error") self:close() end Wait(500) end end) end function decorate.selectEntity(self, entityHandle) local activeGizmo = (self.mode == "gizmo") and gizmo or mgizmo if entityHandle then if not DoesEntityExist(entityHandle) then activeGizmo.entity = nil activeGizmo.decorateData = nil return end end local hitEntity = entityHandle if not hitEntity then local hitCoords, hitEnt = getCursorHitCoords() if hitCoords and hitEnt and hitEnt ~= 0 then hitEntity = hitEnt end end if not hitEntity then return end if self.currentPage ~= "stash" and not entityHandle then local currentHandle = self.currentObject and self.currentObject.handle if currentHandle ~= hitEntity then return Notification(i18n.t("decorate.you_cant_select_entity"), "error") end end local objectData = self:getObjectData(hitEntity) if not entityHandle and not objectData then return end activeGizmo.entity = hitEntity activeGizmo.decorateData = objectData local currentHandle = self.currentObject and self.currentObject.handle if currentHandle ~= hitEntity then self.currentObject = { handle = hitEntity, modelName = objectData and objectData.modelName, stashId = objectData and objectData.id } end activeGizmo:selectEntity(hitEntity) if self.mode == "gizmo" and self.freeCamera and not self.cameraFocus then self.cameraFocus = true end self:instructional() end function decorate.deselectEntity(self) gizmo:deselectEntity() self:instructional() end function decorate.getCamCoords(self) return GetFinalRenderedCamCoord() end function decorate.getCamRot(self) return GetFinalRenderedCamRot(2) end function decorate.toggleHideDecorate(self) self.hide = not self.hide SendReactMessage("toggle_hide_decorate", self.hide) if self.hide then self:setFocus(true, true) else self:setFocus(true, false) end end function decorate.setFocus(self, focusState, keepInputState) if focusState == nil then self.focus = not self.focus else self.focus = focusState end SetNuiFocus(self.focus, self.focus) if keepInputState ~= nil then self.keepInput = keepInputState else self.keepInput = not self.focus end self.keepInput = keepInputState SetNuiFocusKeepInput(self.keepInput) if not self.keepInput and self.mode == "mgizmo" then self:toggleGizmoMode("gizmo") Debug("setFocus ::: toggleGizmoMode to gizmo because keepInput is false") end end function decorate.placeObjectOnGround(self) local currentHandle = self.currentObject and self.currentObject.handle if not currentHandle then return end PlaceObjectOnGroundProperly(currentHandle) gizmo:updateGizmoEntity() end function decorate.toggleGizmoMode(self, targetMode) if self.mode == "gizmo" and not self.keepInput then return Debug("toggleGizmoMode ::: mgizmo mode is enabled and keepInput is true, so we do not toggle mode") end if targetMode then if targetMode == self.mode then return Debug("toggleGizmoMode ::: mode is already same", "mode", targetMode) end self.mode = targetMode else self.mode = (self.mode == "gizmo") and "mgizmo" or "gizmo" end SendReactMessage("toggle_gizmo_mode", self.mode) Notification(i18n.t("decorate.gizmo_mode_toggled", { mode = self.mode }), "info") gizmo:deselectEntity() mgizmo:deselectEntity() if self.mode == "gizmo" then gizmo:handleCameraUpdate() else mgizmo:loop() end end LIGHT_ITEMS = Config.Furniture.light.items local dynamicFurnituresBackup = table.deepclone(Config.DynamicFurnitures) function InitializeFurnitures() Config.DynamicFurnitures = table.deepclone(dynamicFurnituresBackup) Config.DoorModels = {} for categoryKey, category in pairs(Config.Furniture) do if categoryKey ~= "navigation" then for _, item in pairs(category.items) do if item.type then Config.DynamicFurnitures[item.object] = item end if item.isDoor then Config.DoorModels[item.object] = item end if item.colors then for _, colorVariant in pairs(item.colors) do if colorVariant.type then Config.DynamicFurnitures[colorVariant.object] = colorVariant end if item.isDoor then Config.DoorModels[colorVariant.object] = colorVariant end end end end end end end CreateThread(InitializeFurnitures) function decorate.handleControls(self) local lastOutlinedHandle = 0 CreateThread(function() while self.active do disablePlayerFiring(cache.playerId, true) local currentHandle = self.currentObject and self.currentObject.handle if lastOutlinedHandle ~= currentHandle then SetEntityDrawOutline(lastOutlinedHandle, false) SetEntityDrawOutline(currentHandle, true) SetEntityDrawOutlineColor(0, 180, 255, 255) end lastOutlinedHandle = currentHandle if isControlJustPressed(0, Keys.F5) or isDisabledControlJustPressed(0, Keys.F5) then self:setFocus(true) end if isControlJustPressed(0, Keys.F3) or isDisabledControlJustPressed(0, Keys.F3) then self:toggleFreeCamera() end if isControlJustPressed(0, Keys.Enter) or isDisabledControlJustPressed(0, Keys.Enter) then if not (self.currentObject and self.currentObject.stashId) then self:openBuyObjectModal() end end if currentHandle then if isControlJustPressed(0, Keys.Delete) or isDisabledControlJustPressed(0, Keys.Delete) then self:removeCurrentObject() end if isControlJustPressed(0, Keys.G) or isDisabledControlJustPressed(0, Keys.G) then self:placeObjectOnGround() end end Wait(0) end end) end RegisterNetEvent("garages:decorate:open") AddEventHandler("garages:decorate:open", function() if not currentlyInGarage then return Notification(i18n.t("decorate.not_in_garage"), "error") end local garageData = Config.Garages[currentlyInGarage] if not garageData then return Notification(i18n.t("decorate.invalid_garage"), "error") end if garageData.available or garageData.isImpound then return Notification(i18n.t("decorate.not_support_decoration"), "error") end local playerIdentifier = GetPlayerIdentifier() local isOwner = garageData.owner == playerIdentifier if Config.DecorateOnlyAccessForOwner and not isOwner then return Notification(i18n.t("decorate.not_owner"), "error") elseif not HasKey(currentlyInGarage) and not isOwner then return Notification(i18n.t("decorate.not_key_holder"), "error") end decorate:open() end) function decorate.toggleFreeCamera(self, forceState) if forceState ~= nil then self.freeCamera = forceState else self.freeCamera = not self.freeCamera end if not self.freeCamera then return end SetPlayerControl(cache.playerId, false, 0) local _, _, pedForward, pedPos = GetEntityMatrix(cache.ped) local cameraStartPos = pedPos + pedForward * 2 local pedRotation = GetEntityRotation(cache.ped) local freeCam = Utils.CreateCamera("DEFAULT_SCRIPTED_CAMERA", cameraStartPos, pedRotation, true) self:instructional({ { key = "focus_free_camera", label = "Focus Object" } }) self.cameraFocus = false CreateThread(function() local camPos = cameraStartPos local camRot = pedRotation while self.active and self.freeCamera do local newPos, newRot = Utils.HandleFlyCam(freeCam, { mouse = not self.cameraFocus }) camRot = newRot camPos = newPos DisableAllControlActions(0) if isDisabledControlJustPressed(0, Keys.F) then if self.mode == "gizmo" then self.cameraFocus = not self.cameraFocus else Notification(i18n.t("decorate.focus_object_not_supported"), "error") end end if self.cameraFocus and self.mode == "mgizmo" then self.cameraFocus = false end if self.cameraFocus then local currentObjHandle = self.currentObject and self.currentObject.handle if currentObjHandle and DoesEntityExist(currentObjHandle) then local objCoords = GetEntityCoords(currentObjHandle) local objModel = GetEntityModel(currentObjHandle) local minDim, maxDim = GetModelDimensions(objModel) local objSize = #(maxDim - minDim) local idealDist = math.max(objSize * 2.0, 3.0) local objHeight = maxDim.z - minDim.z local camToObj = camPos - objCoords local dist = #camToObj local pitch = math.deg(math.asin(camToObj.z / dist)) local yaw = math.deg(math.atan(-camToObj.x, camToObj.y)) local targetRot = vec3(pitch, 0.0, yaw) local lerpedRot = vec3( camRot.x + (targetRot.x - camRot.x) * CAMERA_LERP_SPEED, camRot.y + (targetRot.y - camRot.y) * CAMERA_LERP_SPEED, camRot.z + (targetRot.z - camRot.z) * CAMERA_LERP_SPEED ) SetCamRot(freeCam, lerpedRot.x, lerpedRot.y, lerpedRot.z, 2) if dist > idealDist * 1.5 or dist < idealDist * 0.5 then local dirToObj = camToObj / dist local targetPos = objCoords - dirToObj * idealDist local lerpedPos = vec3( camPos.x + (targetPos.x - camPos.x) * CAMERA_LERP_SPEED * 0.5, camPos.y + (targetPos.y - camPos.y) * CAMERA_LERP_SPEED * 0.5, camPos.z + (targetPos.z - camPos.z) * CAMERA_LERP_SPEED * 0.5 ) SetCamCoord(freeCam, lerpedPos.x, lerpedPos.y, lerpedPos.z) camPos = lerpedPos end if dist < idealDist * 0.7 then local orbitAngle = GetGameTimer() / 1000.0 * 0.3 local orbitRadius = objSize * 0.8 local targetOrbit = vec3( objCoords.x + math.cos(orbitAngle) * orbitRadius, objCoords.y + math.sin(orbitAngle) * orbitRadius, objCoords.z + objHeight ) local lerpedOrbit = vec3( camPos.x + (targetOrbit.x - camPos.x) * 0.05, camPos.y + (targetOrbit.y - camPos.y) * 0.05, camPos.z + (targetOrbit.z - camPos.z) * 0.05 ) SetCamCoord(freeCam, lerpedOrbit.x, lerpedOrbit.y, lerpedOrbit.z) end end end Wait(0) end Utils.DestroyFlyCam(freeCam, 1000) SetPlayerControl(cache.playerId, true, 0) self:instructional() end) end function decorate.removeCurrentObject(self) local currentObj = self.currentObject if not currentObj then return end if currentObj.handle and not currentObj.stashId then DeleteObject(currentObj.handle) end gizmo:deselectEntity() self.currentObject = nil SendReactMessage("remove_current_object") Debug("Removed current object", self.currentObject) end exports("inDecorate", function() return decorate.active end) function decorate.getObjectData(self, entityHandle) local currentHandle = self.currentObject and self.currentObject.handle if currentHandle == entityHandle then return self.currentObject end for _, objData in pairs(decorate.objects) do if objData.handle and DoesEntityExist(objData.handle) and objData.handle == entityHandle then return objData end end return false end function decorate.saveCurrentObject(self) Debug("saveCurrentObject", "Current object", decorate.currentObject) if not self.currentObject then return end local objToSave = { modelName = self.currentObject.modelName, coords = GetEntityCoords(self.currentObject.handle), rotation = GetEntityRotation(self.currentObject.handle), handle = self.currentObject.handle, inStash = false, inside = currentlyInGarage ~= nil, insideId = currentlyInGarage } self:removeCurrentObject() return lib.callback.await("garages:decorate:saveObject", false, currentlyInGarage, objToSave) end function decorate.destroyObjects(self) local objectsCopy = table.deepclone(decorate.objects) decorate.objects = {} for _, objData in pairs(objectsCopy) do RemoveSpawnedObject(objData) end Debug("Unloaded objects") end function decorate.refreshObjects(self) for _, objData in pairs(decorate.objects) do RemoveSpawnedObject(objData) end end function decorate.saveObjects(self) for _, objData in pairs(decorate.objects) do if objData.spawned and DoesEntityExist(objData.handle) then local newCoords = GetEntityCoords(objData.handle) local newRotation = GetEntityRotation(objData.handle) if newCoords.x ~= objData.coords.x or newRotation.x ~= objData.rotation.x then objData.coords = newCoords objData.rotation = newRotation TriggerServerEvent("garages:decorate:updateObject", currentlyInGarage, objData.id, { coords = json.encode(newCoords), rotation = json.encode(newRotation) }) end end end end function decorate.openBuyObjectModal(self) if not self.currentObject then return end SendReactMessage("open_buy_object_modal") end RegisterNetEvent("garages:decorate:updateObject") AddEventHandler("garages:decorate:updateObject", function(garageId, objectId, newData) if currentlyInGarage ~= garageId then return Debug("garages:decorate:updateObject ::: insideID is not same", "currentlyInGarage", currentlyInGarage, "insideID", garageId) end local foundObject = table.find(decorate.objects, function(obj) return obj.id == objectId end) if not foundObject then Error("garages:decorate:updateObject :: Object not found", "id", objectId) return end for key, value in pairs(newData) do if key == "coords" and foundObject.spawned then Debug("garages:decorate:updateObject ::: SetEntityCoords", "object", foundObject.handle, "coords", value) SetEntityCoords(foundObject.handle, value.x, value.y, value.z, false, false, false, false) elseif key == "rotation" and foundObject.spawned then Debug("garages:decorate:updateObject ::: SetEntityRotation", "object", foundObject.handle, "rotation", value) SetEntityRotation(foundObject.handle, value.x, value.y, value.z, 0, false) end foundObject[key] = value Debug("Updated object", "object", foundObject.id, "key", key, "value", value) end end) function RemoveSpawnedObject(objData) if not objData.spawned then return false end DeleteObject(objData.handle) objData.spawned = false end RegisterNetEvent("garages:decorate:sellFurniture") AddEventHandler("garages:decorate:sellFurniture", function(garageId, objectId) if currentlyInGarage ~= garageId then return Debug("garages:decorate:sellFurniture ::: decorateId is not same", "CurrentGarage", currentlyInGarage, "garage", garageId) end local foundObject = table.find(decorate.objects, function(obj) return obj.id == objectId end) if not foundObject then Error("garages:decorate:sellFurniture ::: Object not found", "id", objectId) return end RemoveSpawnedObject(foundObject) decorate.objects = table.filter(decorate.objects, function(obj) return obj.id ~= objectId end) Debug("garages:decorate:sellFurniture", "object is deleted from cache", foundObject.id) end) RegisterNetEvent("garages:decorate:addObject") AddEventHandler("garages:decorate:addObject", function(garageId, objectData) if currentlyInGarage ~= garageId then return Debug("garages:decorate:addObject ::: garage is not same", "Entered Garage", currentlyInGarage, "garage", garageId) end decorate.objects[#decorate.objects + 1] = objectData Debug("Added object to data", "data", objectData) end) function SpawnObject(modelName, coords, rotation) local modelHash = joaat(modelName) lib.requestModel(modelHash) local entity = CreateObject(modelHash, coords.x, coords.y, coords.z, false, false, false) SetEntityAlpha(entity, 0, false) CreateThread(function() for alpha = 0, 255, 51 do Wait(50) SetEntityAlpha(entity, alpha, false) end end) if rotation then SetEntityRotation(entity, rotation.x, rotation.y, rotation.z, 0, false) end SetEntityCompletelyDisableCollision(entity, true, false) if not (Config.DynamicDoors and Config.DoorModels[modelName]) then FreezeEntityPosition(entity, true) end SetModelAsNoLongerNeeded(modelHash) Wait(0) SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) return entity end function decorate.canAccessStash(self, stashUniq) if not currentlyInGarage then return false end return HasKey(currentlyInGarage) end function decorate.doorAnim(self) lib.playAnim(cache.ped, "anim@heists@keycard@", "exit") Wait(400) ClearPedTasks(cache.ped) end local TEXT_DYNAMIC = i18n.t("drawtext.dynamic") local TEXT_STASH = i18n.t("drawtext.stash") local TEXT_GARDROBE = i18n.t("drawtext.gardrobe") local TEXT_DELETE = i18n.t("drawtext.delete_illegal") function decorate.checkNearObjects(self) CreateThread(function() while self.objects and #self.objects > 0 do local waitTime = 500 local pedCoords = GetEntityCoords(cache.ped) for _, objData in pairs(self.objects) do local objCoords = vec3(objData.coords.x, objData.coords.y, objData.coords.z) local distance = #(objCoords - pedCoords) if distance <= 1.5 then local dynamicConfig = Config.DynamicFurnitures[objData.modelName] if dynamicConfig then local interactPos = GetOffsetFromEntityInWorldCoords( objData.handle, dynamicConfig.offset.x, dynamicConfig.offset.y, dynamicConfig.offset.z ) if dynamicConfig.event then waitTime = 0 DrawText3D(interactPos.x, interactPos.y, interactPos.z, TEXT_DYNAMIC, "Store", "interact", "E") if isControlJustPressed(0, Keys.E) then TriggerEvent(dynamicConfig.event, objData.uniq) end elseif dynamicConfig.type == "stash" then waitTime = 0 DrawText3D(interactPos.x, interactPos.y, interactPos.z, TEXT_STASH, "stash_access", "E") if isControlJustPressed(0, Keys.E) then if self:canAccessStash(objData.uniq) then openStash(dynamicConfig.stash, objData.uniq) end end elseif dynamicConfig.type == "gardrobe" then waitTime = 0 DrawText3D(interactPos.x, interactPos.y, interactPos.z, TEXT_GARDROBE, "open_wardrobe", "E") if isControlJustPressed(0, Keys.E) then openWardrobe() end end end end end Wait(waitTime) end end) end function decorate.getObjects(self, garageId) self:destroyObjects() Debug("decorate:getObjects", "id", garageId) local objects = lib.callback.await("garages:decorate:getDecorations", 0, garageId) self.objects = objects self:checkNearObjects() Debug("Loaded objects", "data", self.objects) end local lightObjectModels = {} local lightObjectsCache = {} CreateThread(function() for _, item in pairs(LIGHT_ITEMS) do table.insert(lightObjectModels, item.object) end while true do if not decorate.objects then lightObjectsCache = {} else local lightObjects = table.deepclone(table.filter(decorate.objects, function(obj) return table.includes(lightObjectModels, obj.modelName) end)) lightObjectsCache = lightObjects for idx, objData in pairs(lightObjectsCache) do if objData.handle and DoesEntityExist(objData.handle) then if not objData.inside or currentlyInGarage then local rotation = GetEntityRotation(objData.handle) local coords = GetEntityCoords(objData.handle) local direction = RotationToDirection(rotation) lightObjectsCache[idx].position = coords lightObjectsCache[idx].direction = direction end end end end Wait(500) end end) CreateThread(function() while true do local waitTime = 1250 for _, objData in pairs(lightObjectsCache) do if objData.handle and DoesEntityExist(objData.handle) then local lightData = objData.lightData if not lightData or not lightData.active then goto continue end if objData.position then waitTime = 0 local pos = objData.position local dir = objData.direction local rgb = (lightData and lightData.rgb) or { r = 255, g = 255, b = 255 } local intensity = ((lightData and lightData.intensity) or Config.DefaultLightIntensity) + 0.0 DrawSpotLight(pos.x, pos.y, pos.z, dir.x, dir.y, dir.z, rgb.r, rgb.g, rgb.b, 100.0, 20.0, 1.0, intensity, 0.0) end end ::continue:: end Wait(waitTime) end end) CreateThread(function() while true do local waitTime = decorate.active and 300 or 1250 local pedCoords = GetEntityCoords(cache.ped) if not decorate.objects then Wait(waitTime) else for _, objData in pairs(decorate.objects) do if objData.inStash then if objData.spawned then DeleteObject(objData.handle) objData.spawned = false Debug("Deleted object because its setted to inStash", "object", objData.handle) end else if not objData.coords then Error("Object coords is nil we skipping it.", "object", objData) else objData.coords = vec3(objData.coords.x, objData.coords.y, objData.coords.z) if objData.coords.x == 0.0 and objData.coords.y == 0.0 and objData.coords.z == 0.0 then if EditorCamera then local camData = Utils.GetCamera() local camForward = Utils.GetForwardVector(camData.rotation) * 5.0 local camPos = camData.coords + camForward Debug("Load Decorations : Object is from ikea. We setted it to camera center", "v", objData) objData.coords = vec3(camPos.x, camPos.y, camPos.z) decorate:saveObjects() end end local distance = #(pedCoords - objData.coords) if distance <= Config.SpawnDistance then if not objData.spawned then local entityHandle = SpawnObject(objData.modelName, objData.coords, objData.rotation) if entityHandle then objData.handle = entityHandle local stashId = decorate.currentObject and decorate.currentObject.stashId if stashId == objData.id then decorate.currentObject.handle = entityHandle decorate:selectEntity(entityHandle) end else objData.handle = 0 Warning("This model is not loaded. Please check if the model is valid. if its not delete it from the list", objData.modelName) end objData.spawned = true end elseif distance > Config.SpawnDistance then if objData.spawned then RemoveSpawnedObject(objData) Debug("Deleted object", "object", objData.handle) end end end end end Wait(waitTime) end end end) local function AddFurnitureToCategory(categoryName, itemData) local category = Config.Furniture[categoryName] if category then table.insert(category.items, itemData) InitializeFurnitures() else print("Error: Category " .. categoryName .. " does not exist in furniture settings") end end exports("AddFurniture", function(categoryName, itemData) return AddFurnitureToCategory(categoryName, itemData) end) exports("AddShell", function(shellData) Config.Shells[#Config.Shells + 1] = shellData Debug("Added shell", shellData) end) AddEventHandler("onResourceStop", function(resourceName) if GetCurrentResourceName() ~= resourceName then return end decorate:destroyObjects() decorate:close() end) RegisterCommand("garagedecorate", function() TriggerEvent("garages:decorate:open") end)