diff --git a/server-data/resources/[esx_addons]/esx_property/client/cctv.lua b/server-data/resources/[esx_addons]/esx_property/client/cctv.lua index ef9551e5d..e884da4db 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/cctv.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/cctv.lua @@ -1,259 +1,262 @@ function CCTV(PropertyID) - DoScreenFadeOut(500) - Wait(500) - local PlyCoordsBefore = GetEntityCoords(PlayerPedId()) - local Property = Properties[PropertyID] - local CamTakePic = true - if Property.cctv.enabled then - ESX.TriggerServerCallback("esx_property:CCTV", function(CanCCTV) - if CanCCTV then - InCCTV = true - local NightVision = false - local function InstructionButtonMessage(text) - BeginTextCommandScaleformString("STRING") - AddTextComponentScaleform(text) - EndTextCommandScaleformString() - end + DoScreenFadeOut(500) + Wait(500) + local PlyCoordsBefore = GetEntityCoords(PlayerPedId()) + local Property = Properties[PropertyID] + local CamTakePic = true + if Property.cctv.enabled then + ESX.TriggerServerCallback("esx_property:CCTV", function(CanCCTV) + if CanCCTV then + InCCTV = true + local NightVision = false + local function InstructionButtonMessage(text) + BeginTextCommandScaleformString("STRING") + AddTextComponentScaleform(text) + EndTextCommandScaleformString() + end + + local function CreateInstuctionScaleform(scaleform) + local scaleform = RequestScaleformMovie(scaleform) + while not HasScaleformMovieLoaded(scaleform) do + Wait(0) + end + PushScaleformMovieFunction(scaleform, "CLEAR_ALL") + PopScaleformMovieFunctionVoid() - local function CreateInstuctionScaleform(scaleform) - local scaleform = RequestScaleformMovie(scaleform) - while not HasScaleformMovieLoaded(scaleform) do - Wait(0) - end - PushScaleformMovieFunction(scaleform, "CLEAR_ALL") - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_CLEAR_SPACE") + PushScaleformMovieFunctionParameterInt(200) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_CLEAR_SPACE") - PushScaleformMovieFunctionParameterInt(200) - PopScaleformMovieFunctionVoid() + if Config.CCTV.PictureWebook ~= "" then + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(1) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Screenshot, true)) + InstructionButtonMessage(_U("take_picture")) + PopScaleformMovieFunctionVoid() + end - if Config.CCTV.PictureWebook ~= "" then - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(1) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Screenshot, true)) - InstructionButtonMessage(_U("take_picture")) - PopScaleformMovieFunctionVoid() - end + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(2) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Right, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Left, true)) + InstructionButtonMessage(_U("rot_left_right")) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(2) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Right, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Left, true)) - InstructionButtonMessage(_U("rot_left_right")) - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(3) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Down, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Up, true)) + InstructionButtonMessage(_U("rot_up_down")) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(3) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Down, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Up, true)) - InstructionButtonMessage(_U("rot_up_down")) - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(4) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomOut, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomIn, true)) + InstructionButtonMessage(_U("Zoom")) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(4) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomOut, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomIn, true)) - InstructionButtonMessage(_U("Zoom")) - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(5) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.NightVision, true)) + InstructionButtonMessage(_U("night_vision")) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(5) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.NightVision, true)) - InstructionButtonMessage(_U("night_vision")) - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(0) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Exit, true)) + InstructionButtonMessage(_U("exit")) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(0) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Exit, true)) - InstructionButtonMessage(_U("exit")) - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "DRAW_INSTRUCTIONAL_BUTTONS") + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "DRAW_INSTRUCTIONAL_BUTTONS") - PopScaleformMovieFunctionVoid() + PushScaleformMovieFunction(scaleform, "SET_BACKGROUND_COLOUR") + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(80) + PopScaleformMovieFunctionVoid() - PushScaleformMovieFunction(scaleform, "SET_BACKGROUND_COLOUR") - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(80) - PopScaleformMovieFunctionVoid() + return scaleform + end + ESX.CloseContext() + local cctvcam = nil + local angleZ = 0.0 + ClearFocus() + local playerPed = PlayerPedId() + cctvcam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + Config.CCTV.HeightAboveDoor), 0, 0, 0, Config.CCTV.FOV) + SetCamRot(cctvcam, Property.cctv.rot.x, Property.cctv.rot.y, Property.cctv.rot.z, 2) + SetCamActive(cctvcam, true) + SetTimecycleModifier("scanline_cam_cheap") + TriggerServerEvent("p_instance:s:leave") + DisableAllControlActions(0) + FreezeEntityPosition(playerPed, true) + SetEntityCollision(playerPed, false, true) + local ShowButtons = true + SetEntityVisible(playerPed, false) + SetTimecycleModifierStrength(2.0) + SetFocusArea(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z, 0.0, 0.0, 0.0) + PointCamAtCoord(cctvcam, vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + Config.CCTV.HeightAboveDoor)) + RenderScriptCams(true, false, 1, true, false) + Wait(1000) + DoScreenFadeIn(500) + RequestAmbientAudioBank("Phone_Soundset_Franklin", 0, 0) + RequestAmbientAudioBank("HintCamSounds", 0, 0) + while IsCamActive(cctvcam) do + Wait(5) + DisableAllControlActions(0) + EnableControlAction(0, 245, true) + EnableControlAction(0, 246, true) + EnableControlAction(0, 249, true) + HideHudComponentThisFrame(7) + HideHudComponentThisFrame(8) + HideHudComponentThisFrame(9) + HideHudComponentThisFrame(6) + HideHudComponentThisFrame(19) + HideHudAndRadarThisFrame() - return scaleform - end - ESX.CloseContext() - local cctvcam = nil - local angleZ = 0.0 - ClearFocus() - local playerPed = PlayerPedId() - cctvcam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", - vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + Config.CCTV.HeightAboveDoor), 0, 0, 0, Config.CCTV.FOV) - SetCamRot(cctvcam, Property.cctv.rot.x, Property.cctv.rot.y, Property.cctv.rot.z, 2) - SetCamActive(cctvcam, true) - SetTimecycleModifier("scanline_cam_cheap") - TriggerServerEvent("p_instance:s:leave") - DisableAllControlActions(0) - FreezeEntityPosition(playerPed, true) - SetEntityCollision(playerPed, false, true) - local ShowButtons = true - SetEntityVisible(playerPed, false) - SetTimecycleModifierStrength(2.0) - SetFocusArea(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z, 0.0, 0.0, 0.0) - PointCamAtCoord(cctvcam, vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + Config.CCTV.HeightAboveDoor)) - RenderScriptCams(true, false, 1, true, false) - Wait(1000) - DoScreenFadeIn(500) - RequestAmbientAudioBank("Phone_Soundset_Franklin", 0, 0) - RequestAmbientAudioBank("HintCamSounds", 0, 0) - while IsCamActive(cctvcam) do - Wait(5) - DisableAllControlActions(0) - EnableControlAction(0, 245, true) - EnableControlAction(0, 246, true) - EnableControlAction(0, 249, true) - HideHudComponentThisFrame(7) - HideHudComponentThisFrame(8) - HideHudComponentThisFrame(9) - HideHudComponentThisFrame(6) - HideHudComponentThisFrame(19) - HideHudAndRadarThisFrame() + if ShowButtons then + local instructions = CreateInstuctionScaleform("instructional_buttons") + DrawScaleformMovieFullscreen(instructions, 255, 255, 255, 255, 0) + end + -- ROTATE LEFT + local getCameraRot = GetCamRot(cctvcam, 2) - if ShowButtons then - local instructions = CreateInstuctionScaleform("instructional_buttons") - DrawScaleformMovieFullscreen(instructions, 255, 255, 255, 255, 0) - end - -- ROTATE LEFT - local getCameraRot = GetCamRot(cctvcam, 2) + if IsDisabledControlPressed(0, Config.CCTV.Controls.Left) and getCameraRot.z < Property.cctv.maxleft then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x, 0.0, getCameraRot.z + Config.CCTV.RotateSpeed, 2) + end + -- ROTATE RIGHT + if IsDisabledControlPressed(0, Config.CCTV.Controls.Right) and getCameraRot.z > Property.cctv.maxright then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x, 0.0, getCameraRot.z - Config.CCTV.RotateSpeed, 2) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.Left) and getCameraRot.z < Property.cctv.maxleft then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x, 0.0, getCameraRot.z + Config.CCTV.RotateSpeed, 2) - end - -- ROTATE RIGHT - if IsDisabledControlPressed(0, Config.CCTV.Controls.Right) and getCameraRot.z > Property.cctv.maxright then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x, 0.0, getCameraRot.z - Config.CCTV.RotateSpeed, 2) - end + -- ROTATE UP + if IsDisabledControlPressed(0, Config.CCTV.Controls.Up) and getCameraRot.x < Config.CCTV.MaxUpRotation then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x + Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) + end - -- ROTATE UP - if IsDisabledControlPressed(0, Config.CCTV.Controls.Up) and getCameraRot.x < Config.CCTV.MaxUpRotation then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x + Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) - end + if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) - end + if IsDisabledControlPressed(0, Config.CCTV.Controls.ZoomIn) and GetCamFov(cctvcam) > Config.CCTV.MaxZoom then + SetCamFov(cctvcam, GetCamFov(cctvcam) - 1.0) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.ZoomIn) and GetCamFov(cctvcam) > Config.CCTV.MaxZoom then - SetCamFov(cctvcam, GetCamFov(cctvcam) - 1.0) - end + if IsDisabledControlPressed(0, Config.CCTV.Controls.ZoomOut) and GetCamFov(cctvcam) < Config.CCTV.MinZoom then + SetCamFov(cctvcam, GetCamFov(cctvcam) + 1.0) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.ZoomOut) and GetCamFov(cctvcam) < Config.CCTV.MinZoom then - SetCamFov(cctvcam, GetCamFov(cctvcam) + 1.0) - end + if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) - end + SetTextFont(4) + SetTextScale(0.8, 0.8) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0.1, 3, 27, 27, 255) + BeginTextCommandDisplayText("STRING") + AddTextComponentSubstringPlayerName(Property.setName ~= "" and Property.setName or Property.Name) + EndTextCommandDisplayText(0.01, 0.01) - SetTextFont(4) - SetTextScale(0.8, 0.8) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0.1, 3, 27, 27, 255) - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(Property.setName ~= "" and Property.setName or Property.Name) - EndTextCommandDisplayText(0.01, 0.01) + SetTextFont(4) + SetTextScale(0.7, 0.7) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0.1, 3, 27, 27, 255) + BeginTextCommandDisplayText("STRING") + local year, --[[ integer ]] + month, --[[ integer ]] + day, --[[ integer ]] + hour, --[[ integer ]] + minute, --[[ integer ]] + second --[[ integer ]] = GetPosixTime() + AddTextComponentSubstringPlayerName("" .. day .. "/" .. month .. "/" .. year .. " " .. hour .. ":" .. minute .. ":" .. second) + EndTextCommandDisplayText(0.01, 0.055) - SetTextFont(4) - SetTextScale(0.7, 0.7) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0.1, 3, 27, 27, 255) - BeginTextCommandDisplayText('STRING') - local year --[[ integer ]] , month --[[ integer ]] , day --[[ integer ]] , hour --[[ integer ]] , minute --[[ integer ]] , second --[[ integer ]] = - GetPosixTime() - AddTextComponentSubstringPlayerName("" .. day .. "/" .. month .. "/" .. year .. " " .. hour .. ":" .. minute .. ":" .. second) - EndTextCommandDisplayText(0.01, 0.055) + SetTextFont(4) + SetTextScale(0.6, 0.6) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0.1, 3, 27, 27, 255) + BeginTextCommandDisplayText("STRING") + local Zoom = ((Config.CCTV.FOV - GetCamFov(cctvcam)) / GetCamFov(cctvcam)) * 100 + AddTextComponentSubstringPlayerName(_U("zoom_level", math.floor(Zoom))) + EndTextCommandDisplayText(0.01, 0.09) - SetTextFont(4) - SetTextScale(0.6, 0.6) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0.1, 3, 27, 27, 255) - BeginTextCommandDisplayText('STRING') - local Zoom = ((Config.CCTV.FOV - GetCamFov(cctvcam)) / GetCamFov(cctvcam)) * 100 - AddTextComponentSubstringPlayerName(_U("zoom_level", math.floor(Zoom))) - EndTextCommandDisplayText(0.01, 0.09) + SetTextFont(4) + SetTextScale(0.6, 0.6) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0.1, 3, 27, 27, 255) + BeginTextCommandDisplayText("STRING") + AddTextComponentSubstringPlayerName(NightVision and "Night Vision: Active" or "CCTV System: Active") + EndTextCommandDisplayText(0.01, 0.12) - SetTextFont(4) - SetTextScale(0.6, 0.6) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0.1, 3, 27, 27, 255) - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(NightVision and "Night Vision: Active" or "CCTV System: Active") - EndTextCommandDisplayText(0.01, 0.12) + if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then + PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) + SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) + end - if IsDisabledControlPressed(0, Config.CCTV.Controls.Down) and getCameraRot.x > Config.CCTV.MaxDownRotation then - PlaySoundFrontend(-1, " FocusIn", "HintCamSounds", false) - SetCamRot(cctvcam, getCameraRot.x - Config.CCTV.RotateSpeed, 0.0, getCameraRot.z, 2) - end + if IsDisabledControlJustPressed(0, 38) then + NightVision = not NightVision + SetNightvision(NightVision) + SetTimecycleModifier("scanline_cam") + end - if IsDisabledControlJustPressed(0, 38) then - NightVision = not NightVision - SetNightvision(NightVision) - SetTimecycleModifier("scanline_cam") - end + if Config.CCTV.PictureWebook ~= "" and IsDisabledControlJustPressed(0, 201) then + if CamTakePic then + ShowButtons = false + Wait(1) + PlaySoundFrontend(-1, "Camera_Shoot", "Phone_Soundset_Franklin", 1) + ESX.TriggerServerCallback("esx_property:GetWebhook", function(hook) + if hook then + exports["screenshot-basic"]:requestScreenshotUpload(hook, "files[]", function(data) + local image = json.decode(data) + ESX.ShowNotification(_U("picture_taken"), "success") + SendNUIMessage({ link = image.attachments[1].proxy_url }) + ESX.ShowNotification(_U("clipboard"), "success") + ShowButtons = true + CamTakePic = false + SetTimeout(5000, function() + CamTakePic = true + end) + end) + end + end) + else + ESX.ShowNotification(_U("please_wait"), "error") + end + end - if Config.CCTV.PictureWebook ~= "" and IsDisabledControlJustPressed(0, 201) then - if CamTakePic then - ShowButtons = false - Wait(1) - PlaySoundFrontend(-1, "Camera_Shoot", "Phone_Soundset_Franklin", 1) - ESX.TriggerServerCallback("esx_property:GetWebhook", function(hook) - if hook then - exports['screenshot-basic']:requestScreenshotUpload(hook, "files[]", function(data) - local image = json.decode(data) - ESX.ShowNotification(_U("picture_taken"), "success") - SendNUIMessage({link = image.attachments[1].proxy_url}) - ESX.ShowNotification(_U("clipboard"), "success") - ShowButtons = true - CamTakePic = false - SetTimeout(5000, function() - CamTakePic = true - end) - end) + if IsDisabledControlPressed(1, Config.CCTV.Controls.Exit) then + DoScreenFadeOut(1000) + ESX.TriggerServerCallback("esx_property:ExitCCTV", function(CanExit) + if CanExit then + InCCTV = false + Wait(1000) + ClearFocus() + ClearTimecycleModifier() + ClearExtraTimecycleModifier() + RenderScriptCams(false, false, 0, true, false) + DestroyCam(cctvcam, false) + SetFocusEntity(playerPed) + SetNightvision(false) + SetSeethrough(false) + SetEntityCollision(playerPed, true, true) + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + Wait(1500) + DoScreenFadeIn(1000) + end + end, PropertyID) + break + end end - end) - else - ESX.ShowNotification(_U("please_wait"), "error") end - end - - if IsDisabledControlPressed(1, Config.CCTV.Controls.Exit) then - DoScreenFadeOut(1000) - ESX.TriggerServerCallback("esx_property:ExitCCTV", function(CanExit) - if CanExit then - InCCTV = false - Wait(1000) - ClearFocus() - ClearTimecycleModifier() - ClearExtraTimecycleModifier() - RenderScriptCams(false, false, 0, true, false) - DestroyCam(cctvcam, false) - SetFocusEntity(playerPed) - SetNightvision(false) - SetSeethrough(false) - SetEntityCollision(playerPed, true, true) - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - Wait(1500) - DoScreenFadeIn(1000) - end - end, PropertyID) - break - end - end - end - end, PropertyID) - end + end, PropertyID) + end end diff --git a/server-data/resources/[esx_addons]/esx_property/client/furniture.lua b/server-data/resources/[esx_addons]/esx_property/client/furniture.lua index 1d718e2d1..eebe61ab4 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/furniture.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/furniture.lua @@ -16,392 +16,393 @@ along with this program. If not, see . ]] if Config.Furniture.Enabled then - SpawnedFurniture = {} - RegisterNetEvent("esx_property:syncFurniture", function(PropertyId, Furniture) - if Properties[PropertyId] and Furniture then - Properties[PropertyId].furniture = Furniture - end - end) - - RegisterNetEvent("esx_property:placeFurniture", function(Id, furniture, findex) - if Properties[Id] and InProperty and CurrentId == Id then - ESX.Game.SpawnLocalObject(furniture.Name, vector3(furniture.Pos.x, furniture.Pos.y, furniture.Pos.z - 0.1), function(object) - SetEntityCoordsNoOffset(object, furniture.Pos.x, furniture.Pos.y, furniture.Pos.z) - SetEntityHeading(object, furniture.Heading) - SetEntityAsMissionEntity(object, true, true) - FreezeEntityPosition(object, true) - SpawnedFurniture[findex] = {obj = object, data = furniture} - end) - end - end) - - RegisterNetEvent("esx_property:removeFurniture", function(Id, furniture) - if Properties[Id] and InProperty and CurrentId == Id then - if SpawnedFurniture[furniture] then - DeleteEntity(SpawnedFurniture[furniture].obj) - SpawnedFurniture[furniture] = nil - end - end - end) - - RegisterNetEvent("esx_property:editFurniture", function(Id, furniture, Pos, Heading) - if Properties[Id] and InProperty and CurrentId == Id then - - if SpawnedFurniture[furniture] then - local obj = SpawnedFurniture[furniture].obj - SetEntityCoordsNoOffset(obj, Pos.x, Pos.y, Pos.z) - SetEntityHeading(obj, Heading) - SpawnedFurniture[furniture].data.Pos = Pos - SpawnedFurniture[furniture].data.Heading = Heading - end - end - end) - - ------------------------ Furniture Start ------------------------------- - local inFurniture = false - local CurrentlyEditing = nil - - function TempFurniturePlacement(PropertyId, PropName, PropIndex, PropCatagory, PropPrice, Existing, Pos, Heading) - ESX.CloseContext() - if CurrentlyEditing then - DeleteEntity(CurrentlyEditing) - CurrentlyEditing = nil - end - local function InstructionButtonMessage(text) - BeginTextCommandScaleformString("STRING") - AddTextComponentScaleform(text) - EndTextCommandScaleformString() - end - - local function CreateInstuctionScaleform(scaleform) - local scaleform = RequestScaleformMovie(scaleform) - while not HasScaleformMovieLoaded(scaleform) do - Wait(0) - end - PushScaleformMovieFunction(scaleform, "CLEAR_ALL") - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_CLEAR_SPACE") - PushScaleformMovieFunctionParameterInt(200) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(1) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.MinusX, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.PlusX, true)) - InstructionButtonMessage(_U("rot_left_right")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(3) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.MinusY, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.PlusY, true)) - InstructionButtonMessage(_U("rot_up_down")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(5) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Up, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Down, true)) - InstructionButtonMessage(_U("Height")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(7) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.RotateLeft, true)) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.RotateRight, true)) - InstructionButtonMessage(_U("Rotation")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(9) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Confirm, true)) - InstructionButtonMessage(_U("place")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") - PushScaleformMovieFunctionParameterInt(0) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Exit, true)) - InstructionButtonMessage(_U("delete_furni")) - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "DRAW_INSTRUCTIONAL_BUTTONS") - PopScaleformMovieFunctionVoid() - - PushScaleformMovieFunction(scaleform, "SET_BACKGROUND_COLOUR") - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(0) - PushScaleformMovieFunctionParameterInt(80) - PopScaleformMovieFunctionVoid() - - return scaleform - end - function GetCameraDirection() - local rotation = GetGameplayCamRot() * (math.pi / 180) - - return vector3(-math.sin(rotation.z), math.cos(rotation.z), math.sin(rotation.x)) - end - local Position = GetEntityCoords(ESX.PlayerData.ped) - local PropSpawn = Position - vector3(0.5, 0.5, 1.0) - ESX.Game.SpawnLocalObject(PropName, PropSpawn, function(CurrentlyEditing) - CurrentlyEditing = CurrentlyEditing - NetworkSetObjectForceStaticBlend(CurrentlyEditing, true) - SetEntityAsMissionEntity(CurrentlyEditing, true, true) - SetEntityCollision(CurrentlyEditing, false, true) - if Existing then - SetEntityCoordsNoOffset(CurrentlyEditing, vector3(Pos.x, Pos.y, Pos.z)) - SetEntityHeading(CurrentlyEditing, Heading) - else - PlaceObjectOnGroundProperly(CurrentlyEditing) - end - FreezeEntityPosition(CurrentlyEditing, true) - while true do - HudForceWeaponWheel(false) - HideHudComponentThisFrame(19) - HideHudComponentThisFrame(20) - local CurrentPos = GetEntityCoords(CurrentlyEditing) - local CurrentHeading = GetEntityHeading(CurrentlyEditing) - local Rotation = GetEntityRotation(CurrentlyEditing, 2) - SetEntityDrawOutline(CurrentlyEditing, true) - SetEntityDrawOutlineColor(55, 140, 191, 200) - SetEntityDrawOutlineShader(1) - local instructions = CreateInstuctionScaleform("instructional_buttons") - DrawScaleformMovieFullscreen(instructions, 255, 255, 255, 255, 0) - Wait(0) - if IsControlJustPressed(0, 202) then - DeleteObject(CurrentlyEditing) + SpawnedFurniture = {} + RegisterNetEvent("esx_property:syncFurniture", function(PropertyId, Furniture) + if Properties[PropertyId] and Furniture then + Properties[PropertyId].furniture = Furniture end + end) - if IsControlPressed(0, Config.Furniture.Controls.MinusY) then - local direction = GetCameraDirection() - CurrentPos = CurrentPos - vector3(direction.x * Config.Furniture.MovementSpeed, direction.y * Config.Furniture.MovementSpeed, 0) - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z) + RegisterNetEvent("esx_property:placeFurniture", function(Id, furniture, findex) + if Properties[Id] and InProperty and CurrentId == Id then + ESX.Game.SpawnLocalObject(furniture.Name, vector3(furniture.Pos.x, furniture.Pos.y, furniture.Pos.z - 0.1), function(object) + SetEntityCoordsNoOffset(object, furniture.Pos.x, furniture.Pos.y, furniture.Pos.z) + SetEntityHeading(object, furniture.Heading) + SetEntityAsMissionEntity(object, true, true) + FreezeEntityPosition(object, true) + SpawnedFurniture[findex] = { obj = object, data = furniture } + end) end + end) - if IsControlPressed(0, Config.Furniture.Controls.PlusY) then - local direction = GetCameraDirection() - CurrentPos = CurrentPos + vector3(direction.x * Config.Furniture.MovementSpeed, direction.y * Config.Furniture.MovementSpeed, 0) - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) + RegisterNetEvent("esx_property:removeFurniture", function(Id, furniture) + if Properties[Id] and InProperty and CurrentId == Id then + if SpawnedFurniture[furniture] then + DeleteEntity(SpawnedFurniture[furniture].obj) + SpawnedFurniture[furniture] = nil + end end + end) - if IsControlPressed(0, Config.Furniture.Controls.Up) then - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z + Config.Furniture.MovementZspeed) + RegisterNetEvent("esx_property:editFurniture", function(Id, furniture, Pos, Heading) + if Properties[Id] and InProperty and CurrentId == Id then + if SpawnedFurniture[furniture] then + local obj = SpawnedFurniture[furniture].obj + SetEntityCoordsNoOffset(obj, Pos.x, Pos.y, Pos.z) + SetEntityHeading(obj, Heading) + SpawnedFurniture[furniture].data.Pos = Pos + SpawnedFurniture[furniture].data.Heading = Heading + end end + end) - if IsControlPressed(0, Config.Furniture.Controls.Down) then - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z - Config.Furniture.MovementZspeed) + ------------------------ Furniture Start ------------------------------- + local inFurniture = false + local CurrentlyEditing = nil + + function TempFurniturePlacement(PropertyId, PropName, PropIndex, PropCatagory, PropPrice, Existing, Pos, Heading) + ESX.CloseContext() + if CurrentlyEditing then + DeleteEntity(CurrentlyEditing) + CurrentlyEditing = nil end - if IsControlPressed(0, Config.Furniture.Controls.RotateLeft) then - CurrentHeading = CurrentHeading + Config.Furniture.RotationSpeed - SetEntityRotation(CurrentlyEditing, 0, 0, CurrentHeading, 1, true) - -- SetEntityRotation(CurrentlyEditing, Rotation.x, Rotation.y, Rotation.z + Config.Furniture.RotationSpeed, 2, false) - -- SetEntityHeading(CurrentlyEditing, CurrentHeading + Config.Furniture.RotationSpeed) + local function InstructionButtonMessage(text) + BeginTextCommandScaleformString("STRING") + AddTextComponentScaleform(text) + EndTextCommandScaleformString() end - if IsControlPressed(0, Config.Furniture.Controls.RotateRight) then - CurrentHeading = CurrentHeading - Config.Furniture.RotationSpeed - SetEntityRotation(CurrentlyEditing, 0, 0, CurrentHeading, 1, true) - -- SetEntityRotation(CurrentlyEditing, Rotation.x, Rotation.y, Rotation.z - Config.Furniture.RotationSpeed, 2, false) - -- SetEntityHeading(CurrentlyEditing, CurrentHeading - Config.Furniture.RotationSpeed) + local function CreateInstuctionScaleform(scaleform) + local scaleform = RequestScaleformMovie(scaleform) + while not HasScaleformMovieLoaded(scaleform) do + Wait(0) + end + PushScaleformMovieFunction(scaleform, "CLEAR_ALL") + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_CLEAR_SPACE") + PushScaleformMovieFunctionParameterInt(200) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(1) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.MinusX, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.PlusX, true)) + InstructionButtonMessage(_U("rot_left_right")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(3) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.MinusY, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.PlusY, true)) + InstructionButtonMessage(_U("rot_up_down")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(5) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Up, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Down, true)) + InstructionButtonMessage(_U("Height")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(7) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.RotateLeft, true)) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.RotateRight, true)) + InstructionButtonMessage(_U("Rotation")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(9) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Confirm, true)) + InstructionButtonMessage(_U("place")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT") + PushScaleformMovieFunctionParameterInt(0) + N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Exit, true)) + InstructionButtonMessage(_U("delete_furni")) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "DRAW_INSTRUCTIONAL_BUTTONS") + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, "SET_BACKGROUND_COLOUR") + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(0) + PushScaleformMovieFunctionParameterInt(80) + PopScaleformMovieFunctionVoid() + + return scaleform end + function GetCameraDirection() + local rotation = GetGameplayCamRot() * (math.pi / 180) - if IsControlPressed(0, Config.Furniture.Controls.PlusX) then - local direction = GetCameraDirection() - CurrentPos = CurrentPos + vector3(-direction.y * Config.Furniture.MovementSpeed, direction.x * Config.Furniture.MovementSpeed, 0) - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) + return vector3(-math.sin(rotation.z), math.cos(rotation.z), math.sin(rotation.x)) end + local Position = GetEntityCoords(ESX.PlayerData.ped) + local PropSpawn = Position - vector3(0.5, 0.5, 1.0) + ESX.Game.SpawnLocalObject(PropName, PropSpawn, function(CurrentlyEditing) + CurrentlyEditing = CurrentlyEditing + NetworkSetObjectForceStaticBlend(CurrentlyEditing, true) + SetEntityAsMissionEntity(CurrentlyEditing, true, true) + SetEntityCollision(CurrentlyEditing, false, true) + if Existing then + SetEntityCoordsNoOffset(CurrentlyEditing, vector3(Pos.x, Pos.y, Pos.z)) + SetEntityHeading(CurrentlyEditing, Heading) + else + PlaceObjectOnGroundProperly(CurrentlyEditing) + end + FreezeEntityPosition(CurrentlyEditing, true) + while true do + HudForceWeaponWheel(false) + HideHudComponentThisFrame(19) + HideHudComponentThisFrame(20) + local CurrentPos = GetEntityCoords(CurrentlyEditing) + local CurrentHeading = GetEntityHeading(CurrentlyEditing) + local Rotation = GetEntityRotation(CurrentlyEditing, 2) + SetEntityDrawOutline(CurrentlyEditing, true) + SetEntityDrawOutlineColor(55, 140, 191, 200) + SetEntityDrawOutlineShader(1) + local instructions = CreateInstuctionScaleform("instructional_buttons") + DrawScaleformMovieFullscreen(instructions, 255, 255, 255, 255, 0) + Wait(0) + if IsControlJustPressed(0, 202) then + DeleteObject(CurrentlyEditing) + end - if IsControlPressed(0, Config.Furniture.Controls.MinusX) then - local direction = GetCameraDirection() - CurrentPos = CurrentPos - vector3(-direction.y * Config.Furniture.MovementSpeed, direction.x * Config.Furniture.MovementSpeed, 0) - SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) - end + if IsControlPressed(0, Config.Furniture.Controls.MinusY) then + local direction = GetCameraDirection() + CurrentPos = CurrentPos - vector3(direction.x * Config.Furniture.MovementSpeed, direction.y * Config.Furniture.MovementSpeed, 0) + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z) + end - if IsControlJustPressed(0, Config.Furniture.Controls.Confirm) then - if not Existing then - ESX.OpenContext("right", - {{unslectable = true, title = _U("confirm_buy",Config.FurnitureCatagories[PropCatagory][PropIndex].title), - description = _U("price",Config.FurnitureCatagories[PropCatagory][PropIndex].price), icon = "fas fa-shopping-cart"}, - {title = _U("yes"), value = "buy", icon = "fas fa-check"}, {title = _U("no"), icon = "fas fa-minus"}}, function(menu, element) - if element.value and element.value == "buy" then - ESX.TriggerServerCallback("esx_property:buyFurniture", function(response) - if response then - DeleteEntity(CurrentlyEditing) - ESX.ShowNotification(_U("bought_furni", Config.FurnitureCatagories[PropCatagory][PropIndex].title), "success") - ESX.CloseContext() - else - ESX.ShowNotification(_U("cannot_buy"), "error") - end - end, CurrentId, PropName, PropIndex, PropCatagory, vector3(CurrentPos.x, CurrentPos.y, CurrentPos.z), CurrentHeading) + if IsControlPressed(0, Config.Furniture.Controls.PlusY) then + local direction = GetCameraDirection() + CurrentPos = CurrentPos + vector3(direction.x * Config.Furniture.MovementSpeed, direction.y * Config.Furniture.MovementSpeed, 0) + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) end - end) - else - ESX.TriggerServerCallback("esx_property:editFurniture", function(response) - if response then - DeleteEntity(CurrentlyEditing) - ESX.ShowNotification(_U("edited_furni"), "success") - ESX.CloseContext() - else - ESX.ShowNotification(_U("cannot_edit"), "error") - end - end, CurrentId, PropIndex, vector3(CurrentPos.x, CurrentPos.y, CurrentPos.z), CurrentHeading) - end - end - if DoesEntityExist(CurrentlyEditing) then - inFurniture = true - else - inFurniture = false - for _, Control in pairs(Config.Furniture.Controls) do - EnableControlAction(0, Control, true) - end - break - end - end - end) - end + if IsControlPressed(0, Config.Furniture.Controls.Up) then + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z + Config.Furniture.MovementZspeed) + end - function FurnitureItems(house, Store, StoreIndex, Catagory) - local Items = {{unselectable = true, title = _U("store_title", Catagory), icon = "fas fa-store"}, - {title = _U("back"), value = "go-back", icon = "fas fa-arrow-left"}} + if IsControlPressed(0, Config.Furniture.Controls.Down) then + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z - Config.Furniture.MovementZspeed) + end + if IsControlPressed(0, Config.Furniture.Controls.RotateLeft) then + CurrentHeading = CurrentHeading + Config.Furniture.RotationSpeed + SetEntityRotation(CurrentlyEditing, 0, 0, CurrentHeading, 1, true) + -- SetEntityRotation(CurrentlyEditing, Rotation.x, Rotation.y, Rotation.z + Config.Furniture.RotationSpeed, 2, false) + -- SetEntityHeading(CurrentlyEditing, CurrentHeading + Config.Furniture.RotationSpeed) + end - for k, v in pairs(Config.FurnitureCatagories[Catagory]) do - table.insert(Items, {title = v.title, value = v.name, index = k, description = "Price: " .. v.price, icon = "fas fa-shopping-cart"}) - end + if IsControlPressed(0, Config.Furniture.Controls.RotateRight) then + CurrentHeading = CurrentHeading - Config.Furniture.RotationSpeed + SetEntityRotation(CurrentlyEditing, 0, 0, CurrentHeading, 1, true) + -- SetEntityRotation(CurrentlyEditing, Rotation.x, Rotation.y, Rotation.z - Config.Furniture.RotationSpeed, 2, false) + -- SetEntityHeading(CurrentlyEditing, CurrentHeading - Config.Furniture.RotationSpeed) + end - ESX.OpenContext("right", Items, function(data, element) - if element.value == "go-back" then - FurnitureCatagories(house, Store, StoreIndex) - else - TempFurniturePlacement(house, element.value, element.index, Catagory) - end - end) - end + if IsControlPressed(0, Config.Furniture.Controls.PlusX) then + local direction = GetCameraDirection() + CurrentPos = CurrentPos + vector3(-direction.y * Config.Furniture.MovementSpeed, direction.x * Config.Furniture.MovementSpeed, 0) + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) + end - function FurnitureCatagories(house, Store, StoreIndex) - local Catagories = {{unselectable = true, title = _U("store_title", Store), icon = "fas fa-store"}, - {title = _U("back"), value = "go-back", icon = "fas fa-arrow-left"}} + if IsControlPressed(0, Config.Furniture.Controls.MinusX) then + local direction = GetCameraDirection() + CurrentPos = CurrentPos - vector3(-direction.y * Config.Furniture.MovementSpeed, direction.x * Config.Furniture.MovementSpeed, 0) + SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos) + end - for k, v in pairs(Config.FurnitureStores[StoreIndex].Catagories) do - table.insert(Catagories, {title = v}) + if IsControlJustPressed(0, Config.Furniture.Controls.Confirm) then + if not Existing then + ESX.OpenContext( + "right", + { + { unslectable = true, title = _U("confirm_buy", Config.FurnitureCatagories[PropCatagory][PropIndex].title), description = _U("price", Config.FurnitureCatagories[PropCatagory][PropIndex].price), icon = "fas fa-shopping-cart" }, + { title = _U("yes"), value = "buy", icon = "fas fa-check" }, + { title = _U("no"), icon = "fas fa-minus" }, + }, + function(menu, element) + if element.value and element.value == "buy" then + ESX.TriggerServerCallback("esx_property:buyFurniture", function(response) + if response then + DeleteEntity(CurrentlyEditing) + ESX.ShowNotification(_U("bought_furni", Config.FurnitureCatagories[PropCatagory][PropIndex].title), "success") + ESX.CloseContext() + else + ESX.ShowNotification(_U("cannot_buy"), "error") + end + end, CurrentId, PropName, PropIndex, PropCatagory, vector3(CurrentPos.x, CurrentPos.y, CurrentPos.z), CurrentHeading) + end + end + ) + else + ESX.TriggerServerCallback("esx_property:editFurniture", function(response) + if response then + DeleteEntity(CurrentlyEditing) + ESX.ShowNotification(_U("edited_furni"), "success") + ESX.CloseContext() + else + ESX.ShowNotification(_U("cannot_edit"), "error") + end + end, CurrentId, PropIndex, vector3(CurrentPos.x, CurrentPos.y, CurrentPos.z), CurrentHeading) + end + end + + if DoesEntityExist(CurrentlyEditing) then + inFurniture = true + else + inFurniture = false + for _, Control in pairs(Config.Furniture.Controls) do + EnableControlAction(0, Control, true) + end + break + end + end + end) end - ESX.OpenContext("right", Catagories, function(data, element) - if element.value == "go-back" then - FurnitureStores(house) - else - FurnitureItems(house, Store, StoreIndex, element.title) - end - end) - end - - function FurnitureEdit(propertyId, furniture) - local furni = SpawnedFurniture[furniture] - local Funiture = Config.FurnitureCatagories[furni.data.Catagory][furni.data.Index] - local Catagories = {{unselectable = true, title = _U("edit_title",Funiture.title), icon = "fas fa-store"}, - {title = _U("back"), value = "go-back", icon = "fas fa-arrow-left"}, - {title = _U("move_title"), value = "rotate", icon = "fas fa-sync-alt"}, {title = _U("delete_furni"), value = "delete", icon = "fas fa-trash-alt"}} - - ESX.OpenContext("right", Catagories, function(data, element) - if element.value == "go-back" then - FurnitureEditSelect(propertyId) - end - if element.value == "delete" then - ESX.TriggerServerCallback("esx_property:deleteFurniture", function(response) - if response then - ESX.ShowNotification(_U("delete_confirm", Funiture.title), "success") - FurnitureEditSelect(propertyId) - else - ESX.ShowNotification(_U("delete_error", Funiture.title), "error") - end - end, propertyId, furniture) - end - if element.value == "rotate" then - ESX.CloseContext() - TempFurniturePlacement(propertyId, furni.data.Name, furniture, furni.data.Catagory, furni.data.Index, true, furni.data.Pos, furni.data.Heading) - end - end) - end + function FurnitureItems(house, Store, StoreIndex, Catagory) + local Items = { { unselectable = true, title = _U("store_title", Catagory), icon = "fas fa-store" }, { title = _U("back"), value = "go-back", icon = "fas fa-arrow-left" } } - function FurnitureEditSelect(propertyId) - local Furni = {{unselectable = true, title = _U("owned_furni"), icon = "far fa-edit"}, - {title = _U("back"), value = "go-back", icon = "fas fa-arrow-left"}} + for k, v in pairs(Config.FurnitureCatagories[Catagory]) do + table.insert(Items, { title = v.title, value = v.name, index = k, description = "Price: " .. v.price, icon = "fas fa-shopping-cart" }) + end - for k, v in pairs(SpawnedFurniture) do - local Funiture = Config.FurnitureCatagories[v.data.Catagory][v.data.Index] - table.insert(Furni, {title = Funiture.title, value = k}) + ESX.OpenContext("right", Items, function(data, element) + if element.value == "go-back" then + FurnitureCatagories(house, Store, StoreIndex) + else + TempFurniturePlacement(house, element.value, element.index, Catagory) + end + end) end - ESX.OpenContext("right", Furni, function(data, element) - if element.value == "go-back" then - FurnitureMenu(propertyId) - else - FurnitureEdit(propertyId, element.value) - end - end) - end + function FurnitureCatagories(house, Store, StoreIndex) + local Catagories = { { unselectable = true, title = _U("store_title", Store), icon = "fas fa-store" }, { title = _U("back"), value = "go-back", icon = "fas fa-arrow-left" } } - function FurnitureStores(house) - local Options = {{unselectable = true, title = _U("menu_stores"), icon = "fas fa-store"}, - {title = _U("back"), value = "go-back", icon = "fas fa-arrow-left"}} + for k, v in pairs(Config.FurnitureStores[StoreIndex].Catagories) do + table.insert(Catagories, { title = v }) + end - for k, v in pairs(Config.FurnitureStores) do - table.insert(Options, {title = v.title, Store = k}) + ESX.OpenContext("right", Catagories, function(data, element) + if element.value == "go-back" then + FurnitureStores(house) + else + FurnitureItems(house, Store, StoreIndex, element.title) + end + end) end - ESX.OpenContext("right", Options, function(data, element) - if element.Store then - FurnitureCatagories(house, element.title, element.Store) - elseif element.value == "go-back" then - FurnitureMenu(house) - end - end) - end + function FurnitureEdit(propertyId, furniture) + local furni = SpawnedFurniture[furniture] + local Funiture = Config.FurnitureCatagories[furni.data.Catagory][furni.data.Index] + local Catagories = { + { unselectable = true, title = _U("edit_title", Funiture.title), icon = "fas fa-store" }, + { title = _U("back"), value = "go-back", icon = "fas fa-arrow-left" }, + { title = _U("move_title"), value = "rotate", icon = "fas fa-sync-alt" }, + { title = _U("delete_furni"), value = "delete", icon = "fas fa-trash-alt" }, + } + + ESX.OpenContext("right", Catagories, function(data, element) + if element.value == "go-back" then + FurnitureEditSelect(propertyId) + end + if element.value == "delete" then + ESX.TriggerServerCallback("esx_property:deleteFurniture", function(response) + if response then + ESX.ShowNotification(_U("delete_confirm", Funiture.title), "success") + FurnitureEditSelect(propertyId) + else + ESX.ShowNotification(_U("delete_error", Funiture.title), "error") + end + end, propertyId, furniture) + end + if element.value == "rotate" then + ESX.CloseContext() + TempFurniturePlacement(propertyId, furni.data.Name, furniture, furni.data.Catagory, furni.data.Index, true, furni.data.Pos, furni.data.Heading) + end + end) + end - function FurnitureMenu(PropertyId) - local Options = {{unselectable = true, title = _U("furni_management"), icon = "fas fa-lamp"}, - {title = _U("menu_stores"), description = _U("menu_stores_desc"), icon = "fas fa-dollar-sign", value = "store"}} + function FurnitureEditSelect(propertyId) + local Furni = { { unselectable = true, title = _U("owned_furni"), icon = "far fa-edit" }, { title = _U("back"), value = "go-back", icon = "fas fa-arrow-left" } } - if #SpawnedFurniture > 0 then - Options[#Options + 1] = {title = _U("menu_reset"), description = _U("menu_reset_desc"), icon = "fas fa-trash", value = "reset"} - Options[#Options + 1] = {title = _U("menu_edit"), description = _U("menu_edit_desc"), icon = "fas fa-archive", value = "edit"} + for k, v in pairs(SpawnedFurniture) do + local Funiture = Config.FurnitureCatagories[v.data.Catagory][v.data.Index] + table.insert(Furni, { title = Funiture.title, value = k }) + end - end - ESX.OpenContext("right", Options, function(data, element) - if element.value then - if element.value == "store" then - FurnitureStores(PropertyId) - elseif element.value == "edit" then - FurnitureEditSelect(PropertyId) - elseif element.value == "reset" then - ESX.TriggerServerCallback("esx_property:RemoveAllfurniture", function(Removed) - if Removed then - ESX.ShowNotification(_U("furni_reset_success"), "success") + ESX.OpenContext("right", Furni, function(data, element) + if element.value == "go-back" then + FurnitureMenu(propertyId) else - ESX.ShowNotification(_U("furni_reset_error"), "error") + FurnitureEdit(propertyId, element.value) end - end, PropertyId) + end) + end + + function FurnitureStores(house) + local Options = { { unselectable = true, title = _U("menu_stores"), icon = "fas fa-store" }, { title = _U("back"), value = "go-back", icon = "fas fa-arrow-left" } } + + for k, v in pairs(Config.FurnitureStores) do + table.insert(Options, { title = v.title, Store = k }) end - end - end) - end - - ESX.RegisterInput(_U("furni_command"), _U("furni_command_desc"), "keyboard", "M", function() - if InProperty then - ESX.TriggerServerCallback('esx_property:CanOpenFurniture', function(Access) - if Access then - if not inFurniture then - FurnitureMenu(CurrentId) - else - FurnitureStores(CurrentId) - end - else - ESX.ShowNotification(_U("furni_command_permission"), 5000, "error") + + ESX.OpenContext("right", Options, function(data, element) + if element.Store then + FurnitureCatagories(house, element.title, element.Store) + elseif element.value == "go-back" then + FurnitureMenu(house) + end + end) + end + + function FurnitureMenu(PropertyId) + local Options = { { unselectable = true, title = _U("furni_management"), icon = "fas fa-lamp" }, { title = _U("menu_stores"), description = _U("menu_stores_desc"), icon = "fas fa-dollar-sign", value = "store" } } + + if #SpawnedFurniture > 0 then + Options[#Options + 1] = { title = _U("menu_reset"), description = _U("menu_reset_desc"), icon = "fas fa-trash", value = "reset" } + Options[#Options + 1] = { title = _U("menu_edit"), description = _U("menu_edit_desc"), icon = "fas fa-archive", value = "edit" } end - end, CurrentId) - else - return + ESX.OpenContext("right", Options, function(data, element) + if element.value then + if element.value == "store" then + FurnitureStores(PropertyId) + elseif element.value == "edit" then + FurnitureEditSelect(PropertyId) + elseif element.value == "reset" then + ESX.TriggerServerCallback("esx_property:RemoveAllfurniture", function(Removed) + if Removed then + ESX.ShowNotification(_U("furni_reset_success"), "success") + else + ESX.ShowNotification(_U("furni_reset_error"), "error") + end + end, PropertyId) + end + end + end) end - end) + + ESX.RegisterInput(_U("furni_command"), _U("furni_command_desc"), "keyboard", "M", function() + if InProperty then + ESX.TriggerServerCallback("esx_property:CanOpenFurniture", function(Access) + if Access then + if not inFurniture then + FurnitureMenu(CurrentId) + else + FurnitureStores(CurrentId) + end + else + ESX.ShowNotification(_U("furni_command_permission"), 5000, "error") + end + end, CurrentId) + else + return + end + end) end diff --git a/server-data/resources/[esx_addons]/esx_property/client/html/copy.html b/server-data/resources/[esx_addons]/esx_property/client/html/copy.html index a3284bb27..f6ca8ea6e 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/html/copy.html +++ b/server-data/resources/[esx_addons]/esx_property/client/html/copy.html @@ -1,28 +1,30 @@ - + }); + + \ No newline at end of file diff --git a/server-data/resources/[esx_addons]/esx_property/client/main.lua b/server-data/resources/[esx_addons]/esx_property/client/main.lua index 5ea33e46b..c35918473 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/main.lua @@ -10,7 +10,7 @@ local Shell = nil local PM = Config.PlayerManagement local CreateThread = CreateThread local Wait = Wait -local ShowingUIs = {Exit = false, Wardrobe = false, Storage = false, ExitShell = false} +local ShowingUIs = { Exit = false, Wardrobe = false, Storage = false, ExitShell = false } local ox_inventory = exports.ox_inventory local DoScreenFadeIn = DoScreenFadeIn local PlayerPedId = PlayerPedId @@ -20,1485 +20,1463 @@ local IsControlJustPressed = IsControlJustPressed local IsControlPressed = IsControlPressed local DoScreenFadeOut = DoScreenFadeOut function RefreshBlips() - for i = 1, #Blips, 1 do - RemoveBlip(Blips[i]) - Blips[i] = nil - end + for i = 1, #Blips, 1 do + RemoveBlip(Blips[i]) + Blips[i] = nil + end - for k, v in pairs(Properties) do - if v.Owned and Config.OwnedBlips then - if v.Owner == ESX.PlayerData.identifier then - local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) - SetBlipSprite(Blip, 40) - SetBlipAsShortRange(Blip, true) - SetBlipScale(Blip, 0.8) - SetBlipColour(Blip, 0) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(v.Name) - EndTextCommandSetBlipName(Blip) - SetBlipCategory(Blip, 11) - Blips[#Blips + 1] = Blip - elseif PlayerKeys[k] then - local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) - SetBlipSprite(Blip, GameBuild >= 2699 and 811 or 134) + for k, v in pairs(Properties) do + if v.Owned and Config.OwnedBlips then + if v.Owner == ESX.PlayerData.identifier then + local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) + SetBlipSprite(Blip, 40) + SetBlipAsShortRange(Blip, true) + SetBlipScale(Blip, 0.8) + SetBlipColour(Blip, 0) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(v.Name) + EndTextCommandSetBlipName(Blip) + SetBlipCategory(Blip, 11) + Blips[#Blips + 1] = Blip + elseif PlayerKeys[k] then + local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) + SetBlipSprite(Blip, GameBuild >= 2699 and 811 or 134) + SetBlipAsShortRange(Blip, true) + SetBlipScale(Blip, 0.9) + SetBlipColour(Blip, 26) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(v.Name) + EndTextCommandSetBlipName(Blip) + SetBlipCategory(Blip, 11) + Blips[#Blips + 1] = Blip + end + elseif not v.Owned and Config.ForSaleBlips then + local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) + SetBlipSprite(Blip, 350) + SetBlipAsShortRange(Blip, true) + SetBlipScale(Blip, 0.7) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(v.Name) + EndTextCommandSetBlipName(Blip) + SetBlipCategory(Blip, 10) + Blips[#Blips + 1] = Blip + end + end + + if PM.Enabled then + local Blip = AddBlipForCoord(PM.Locations.Entrance) + SetBlipSprite(Blip, 374) + SetBlipColour(Blip, 45) SetBlipAsShortRange(Blip, true) - SetBlipScale(Blip, 0.9) - SetBlipColour(Blip, 26) + SetBlipScale(Blip, 0.7) BeginTextCommandSetBlipName("STRING") - AddTextComponentString(v.Name) + AddTextComponentString(_U("office_blip", PM.joblabel)) EndTextCommandSetBlipName(Blip) - SetBlipCategory(Blip, 11) Blips[#Blips + 1] = Blip - end - elseif not v.Owned and Config.ForSaleBlips then - local Blip = AddBlipForCoord(v.Entrance.x, v.Entrance.y, v.Entrance.z) - SetBlipSprite(Blip, 350) - SetBlipAsShortRange(Blip, true) - SetBlipScale(Blip, 0.7) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(v.Name) - EndTextCommandSetBlipName(Blip) - SetBlipCategory(Blip, 10) - Blips[#Blips + 1] = Blip end - end - - if PM.Enabled then - local Blip = AddBlipForCoord(PM.Locations.Entrance) - SetBlipSprite(Blip, 374) - SetBlipColour(Blip, 45) - SetBlipAsShortRange(Blip, true) - SetBlipScale(Blip, 0.7) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U("office_blip",PM.joblabel)) - EndTextCommandSetBlipName(Blip) - Blips[#Blips + 1] = Blip - end end RegisterNetEvent("esx_property:syncProperties", function(properties, lastProperty) - while not ESX.PlayerLoaded and not ESX.PlayerData.identifier do - Wait(0) - end - Properties = properties - for house, data in pairs(Properties) do - if data.Keys then - for ident, vaues in pairs(data.Keys) do - if vaues and ident == ESX.PlayerData.identifier then - PlayerKeys[house] = true + while not ESX.PlayerLoaded and not ESX.PlayerData.identifier do + Wait(0) + end + Properties = properties + for house, data in pairs(Properties) do + if data.Keys then + for ident, vaues in pairs(data.Keys) do + if vaues and ident == ESX.PlayerData.identifier then + PlayerKeys[house] = true + end + end end - end end - end - if lastProperty then - if Properties[lastProperty.id] and (Properties[lastProperty.id].Owner == ESX.PlayerData.identifier or PlayerKeys[lastProperty.id]) then - AttemptHouseEntry(lastProperty.id) - else - ESX.TriggerServerCallback('esx_property:RemoveLastProperty', function() - SetEntityCoords(ESX.PlayerData.ped, vector3(lastProperty.coords.x, lastProperty.coords.y, lastProperty.coords.z)) - end) + if lastProperty then + if Properties[lastProperty.id] and (Properties[lastProperty.id].Owner == ESX.PlayerData.identifier or PlayerKeys[lastProperty.id]) then + AttemptHouseEntry(lastProperty.id) + else + ESX.TriggerServerCallback("esx_property:RemoveLastProperty", function() + SetEntityCoords(ESX.PlayerData.ped, vector3(lastProperty.coords.x, lastProperty.coords.y, lastProperty.coords.z)) + end) + end end - end - RefreshBlips() + RefreshBlips() end) RegisterNetEvent("esx_property:giveKeyAccess", function(Property) - ESX.TriggerServerCallback("esx_property:ShouldHaveKey", function(Should) - if Should then - PlayerKeys[Property] = true - end - end, Property) + ESX.TriggerServerCallback("esx_property:ShouldHaveKey", function(Should) + if Should then + PlayerKeys[Property] = true + end + end, Property) end) RegisterNetEvent("esx_property:RemoveKey", function(Property) - PlayerKeys[Property] = false + PlayerKeys[Property] = false end) -RegisterNetEvent('esx:setJob') -AddEventHandler('esx:setJob', function(job) - RefreshBlips() +RegisterNetEvent("esx:setJob") +AddEventHandler("esx:setJob", function(job) + RefreshBlips() end) exports("GetProperties", function() - return Properties + return Properties end) function OpenInteractionMenu(PropertyId, Interaction) - local Property = Properties[PropertyId] - if Property.Owned then - if Interaction == "Wardrobe" then - Config.WardrobeInteraction(PropertyId, Interaction) - elseif Interaction == "Storage" then - if Config.OxInventory then - exports.ox_inventory:openInventory('stash', {id = 'property-' .. PropertyId, owner = Property.Owner}) - end + local Property = Properties[PropertyId] + if Property.Owned then + if Interaction == "Wardrobe" then + Config.WardrobeInteraction(PropertyId, Interaction) + elseif Interaction == "Storage" then + if Config.OxInventory then + exports.ox_inventory:openInventory("stash", { id = "property-" .. PropertyId, owner = Property.Owner }) + end + end end - end end function GiveKeysMenu(Property) - ESX.TriggerServerCallback("esx_property:GetInsidePlayers", function(Players) - local Elements = {{unselectable = true, title = _U("nearby"), icon = "fas fa-user-plus"}, - {title = _U("back"), icon = "fas fa-arrow-left", value = "go_back"}} - for i = 1, #Players, 1 do - Elements[#Elements + 1] = {title = Players[i].Name, icon = "far fa-user", index = Players[i].Id, value = "user"} - end - ESX.OpenContext("right", Elements, function(menu, element) - if element.value == "go_back" then - ManageKeys(Property) - elseif element.value == "user" then - ESX.TriggerServerCallback("esx_property:GiveKey", function(KeyGiven) - if KeyGiven then - ESX.ShowNotification(_U("gave_key",element.title), "success") - ESX.CloseContext() - else - ESX.ShowNotification(_U("key_cannot_give"), "error") - end - end, Property, element.index) - end - end) - end, Property) + ESX.TriggerServerCallback("esx_property:GetInsidePlayers", function(Players) + local Elements = { { unselectable = true, title = _U("nearby"), icon = "fas fa-user-plus" }, { title = _U("back"), icon = "fas fa-arrow-left", value = "go_back" } } + for i = 1, #Players, 1 do + Elements[#Elements + 1] = { title = Players[i].Name, icon = "far fa-user", index = Players[i].Id, value = "user" } + end + ESX.OpenContext("right", Elements, function(menu, element) + if element.value == "go_back" then + ManageKeys(Property) + elseif element.value == "user" then + ESX.TriggerServerCallback("esx_property:GiveKey", function(KeyGiven) + if KeyGiven then + ESX.ShowNotification(_U("gave_key", element.title), "success") + ESX.CloseContext() + else + ESX.ShowNotification(_U("key_cannot_give"), "error") + end + end, Property, element.index) + end + end) + end, Property) end function RemoveKeysMenu(Property) - ESX.TriggerServerCallback("esx_property:GetPlayersWithKeys", function(Players) - local Elements = {{unselectable = true, title = _U("remove_title"), icon = "fas fa-user-plus"}, - {title = _U("back"), icon = "fas fa-arrow-left", value = "go_back"}} - for k, v in pairs(Players) do - local name = v.name - local Id = k - Elements[#Elements + 1] = {title = name, icon = "far fa-user", value = "user", id = Id} - end - ESX.OpenContext("right", Elements, function(menu, element) - if element.value == "go_back" then - ManageKeys(Property) - elseif element.value == "user" then - ESX.TriggerServerCallback("esx_property:RemoveKey", function(KeyGiven) - if KeyGiven then - ESX.ShowNotification(_U("key_revoke_success", element.title), "success") - ESX.CloseContext() - else - ESX.ShowNotification(_U("key_revoke_error"), "error") - end - end, Property, element.id) - end - end) - end, Property) + ESX.TriggerServerCallback("esx_property:GetPlayersWithKeys", function(Players) + local Elements = { { unselectable = true, title = _U("remove_title"), icon = "fas fa-user-plus" }, { title = _U("back"), icon = "fas fa-arrow-left", value = "go_back" } } + for k, v in pairs(Players) do + local name = v.name + local Id = k + Elements[#Elements + 1] = { title = name, icon = "far fa-user", value = "user", id = Id } + end + ESX.OpenContext("right", Elements, function(menu, element) + if element.value == "go_back" then + ManageKeys(Property) + elseif element.value == "user" then + ESX.TriggerServerCallback("esx_property:RemoveKey", function(KeyGiven) + if KeyGiven then + ESX.ShowNotification(_U("key_revoke_success", element.title), "success") + ESX.CloseContext() + else + ESX.ShowNotification(_U("key_revoke_error"), "error") + end + end, Property, element.id) + end + end) + end, Property) end function ManageKeys(Property) - ESX.HideUI() - local Elements = {{unselectable = true, title = _U("key_management"), icon = "fas fa-key"}, - {title = _U("back"), icon = "fas fa-arrow-left", value = "go_back"}, - {title = _U("give_keys"), icon = "fas fa-plus", value = "give_keys"}, - {title = _U("remove_keys"), icon = "fas fa-minus", value = "remove_keys"} - } + ESX.HideUI() + local Elements = { + { unselectable = true, title = _U("key_management"), icon = "fas fa-key" }, + { title = _U("back"), icon = "fas fa-arrow-left", value = "go_back" }, + { title = _U("give_keys"), icon = "fas fa-plus", value = "give_keys" }, + { title = _U("remove_keys"), icon = "fas fa-minus", value = "remove_keys" }, + } - ESX.OpenContext("right", Elements, function(menu, element) - if element.value == "go_back" then - OpenPropertyMenu(Property) - end - if element.value == "give_keys" then - GiveKeysMenu(Property) - end - if element.value == "remove_keys" then - RemoveKeysMenu(Property) - end - end) + ESX.OpenContext("right", Elements, function(menu, element) + if element.value == "go_back" then + OpenPropertyMenu(Property) + end + if element.value == "give_keys" then + GiveKeysMenu(Property) + end + if element.value == "remove_keys" then + RemoveKeysMenu(Property) + end + end) end function SetPropertyName(Property) - local Name = Properties[Property].setName ~= "" and Properties[Property].setName or Properties[Property].Name - local Elements = {{unselectable = true, title = _U("name_edit"), icon = "fa-solid fa-signature"}, - {icon = "", title = _U("name"), input = true, inputType = "text", inputValue = Name, inputPlaceholder = Properties[Property].Name, - name = "setName"}, {icon = "fa-solid fa-check", title = _U("confirm"), name = "confirm"} - } + local Name = Properties[Property].setName ~= "" and Properties[Property].setName or Properties[Property].Name + local Elements = { + { unselectable = true, title = _U("name_edit"), icon = "fa-solid fa-signature" }, + { icon = "", title = _U("name"), input = true, inputType = "text", inputValue = Name, inputPlaceholder = Properties[Property].Name, name = "setName" }, + { icon = "fa-solid fa-check", title = _U("confirm"), name = "confirm" }, + } - ESX.OpenContext("right", Elements, function(menu, element) - if element.name == "confirm" then - ESX.TriggerServerCallback("esx_property:SetPropertyName", function(Set) - if Set then - ESX.ShowNotification(_U("name_edit_success",menu.eles[2].inputValue), "success") - ESX.CloseContext() - else - ESX.ShowNotification(_U("name_edit_error",menu.eles[2].inputValue), "error") + ESX.OpenContext("right", Elements, function(menu, element) + if element.name == "confirm" then + ESX.TriggerServerCallback("esx_property:SetPropertyName", function(Set) + if Set then + ESX.ShowNotification(_U("name_edit_success", menu.eles[2].inputValue), "success") + ESX.CloseContext() + else + ESX.ShowNotification(_U("name_edit_error", menu.eles[2].inputValue), "error") + end + end, Property, menu.eles[2].inputValue) end - end, Property, menu.eles[2].inputValue) - end - end) + end) end local SettingValue = "" function PropertyMenuElements(PropertyId) - local Property = Properties[PropertyId] - local elements = {{unselectable = true, title = Property.setName ~= "" and Property.setName or Property.Name, icon = "fas fa-home"}} - if Property.Owned then - if Property.Locked then - table.insert(elements, {title = _U("door_locked"), icon = "fas fa-lock", value = 'property_unlock'}) - else - table.insert(elements, {title = _U("door_unlocked"), icon = "fas fa-unlock", value = 'property_lock'}) - end - if ESX.PlayerData.identifier == Property.Owner then - table.insert(elements, - {title = _U("name_manage"), description = _U("name_manage_desc"), icon = "fa-solid fa-signature", value = 'property_name'}) - end - if not InProperty then - if ESX.PlayerData.identifier == Property.Owner then - table.insert(elements, {title = _U("key_management"), description = _U("key_management_desc"), icon = "fas fa-key", value = 'property_keys'}) - table.insert(elements, - {title = _U("sell_title"), description = _U("sell_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price * 0.6))), - icon = "fas fa-dollar-sign", value = 'property_sell'}) - end - if Config.Raiding.Enabled and Property.Locked and ESX.PlayerData.job and ESX.GetPlayerData().job.name == "police" then - table.insert(elements, {title = _U("raid_title"), description = _U("raid_desc"), icon = "fas fa-bomb", value = 'property_raid'}) - end - else - if (Config.CCTV.Enabled and Properties[PropertyId].cctv.enabled) and (ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId]) then - table.insert(elements, {title = _U("cctv_title"), description = _U("cctv_desc"), icon = "fas fa-video", value = 'property_cctv'}) - end - if (ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId]) then - if Config.CanCustomiseInventoryAndWardrobePositions then - if Config.OxInventory then - table.insert(elements, {title = _U("inventory_title"), description = _U("inventory_desc"), - icon = "fa-solid fa-up-down-left-right", value = 'property_inventory'}) - end - table.insert(elements, {title = _U("wardrobe_title"), description = _U("wardrobe_desc"), icon = "fa-solid fa-up-down-left-right", - value = 'property_wardrobe'}) + local Property = Properties[PropertyId] + local elements = { { unselectable = true, title = Property.setName ~= "" and Property.setName or Property.Name, icon = "fas fa-home" } } + if Property.Owned then + if Property.Locked then + table.insert(elements, { title = _U("door_locked"), icon = "fas fa-lock", value = "property_unlock" }) + else + table.insert(elements, { title = _U("door_unlocked"), icon = "fas fa-unlock", value = "property_lock" }) + end + if ESX.PlayerData.identifier == Property.Owner then + table.insert(elements, { title = _U("name_manage"), description = _U("name_manage_desc"), icon = "fa-solid fa-signature", value = "property_name" }) + end + if not InProperty then + if ESX.PlayerData.identifier == Property.Owner then + table.insert(elements, { title = _U("key_management"), description = _U("key_management_desc"), icon = "fas fa-key", value = "property_keys" }) + table.insert(elements, { title = _U("sell_title"), description = _U("sell_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price * 0.6))), icon = "fas fa-dollar-sign", value = "property_sell" }) + end + if Config.Raiding.Enabled and Property.Locked and ESX.PlayerData.job and ESX.GetPlayerData().job.name == "police" then + table.insert(elements, { title = _U("raid_title"), description = _U("raid_desc"), icon = "fas fa-bomb", value = "property_raid" }) + end + else + if (Config.CCTV.Enabled and Properties[PropertyId].cctv.enabled) and (ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId]) then + table.insert(elements, { title = _U("cctv_title"), description = _U("cctv_desc"), icon = "fas fa-video", value = "property_cctv" }) + end + if ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId] then + if Config.CanCustomiseInventoryAndWardrobePositions then + if Config.OxInventory then + table.insert(elements, { title = _U("inventory_title"), description = _U("inventory_desc"), icon = "fa-solid fa-up-down-left-right", value = "property_inventory" }) + end + table.insert(elements, { title = _U("wardrobe_title"), description = _U("wardrobe_desc"), icon = "fa-solid fa-up-down-left-right", value = "property_wardrobe" }) + end + table.insert(elements, { title = _U("furniture_title"), description = _U("furniture_desc"), icon = "fas fa-boxes-stacked", value = "property_furniture" }) + end + end + if (not Property.Locked or Config.OwnerCanAlwaysEnter and ESX.PlayerData.identifier == Property.Owner) and not InProperty then + table.insert(elements, { title = _U("enter_title"), icon = "fas fa-door-open", value = "property_enter" }) + end + if Property.Locked and not InProperty and not (Config.OwnerCanAlwaysEnter and ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId]) then + table.insert(elements, { title = _U("knock_title"), icon = "fa-solid fa-hand-sparkles", value = "property_knock" }) end - table.insert(elements, - {title = _U("furniture_title"), description = _U("furniture_desc"), icon = "fas fa-boxes-stacked", value = 'property_furniture'}) - end - end - if (not Property.Locked or Config.OwnerCanAlwaysEnter and ESX.PlayerData.identifier == Property.Owner) and not InProperty then - table.insert(elements, {title = _U("enter_title"), icon = "fas fa-door-open", value = 'property_enter'}) - end - if Property.Locked and not InProperty and - not (Config.OwnerCanAlwaysEnter and ESX.PlayerData.identifier == Property.Owner or PlayerKeys[PropertyId]) then - table.insert(elements, {title = _U("knock_title"), icon = "fa-solid fa-hand-sparkles", value = 'property_knock'}) - end - else - if not PM.Enabled then - table.insert(elements, - {title = _U("buy_title"), description = _U("buy_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price))), icon = "fas fa-shopping-cart", - value = 'property_buy'}) else - if ESX.PlayerData.job.name == PM.job and ESX.PlayerData.job.grade >= PM.Permissions.SellProperty then - table.insert(elements, {title = _U("sellplayer_title"), description = _U("sellplayer_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price))), - icon = "fas fa-shopping-cart", value = 'property_sell_re'}) - end - end - if not Property.Locked and not InProperty then - table.insert(elements, {title = _U("view_title"), icon = "fas fa-door-open", value = 'property_enter'}) + if not PM.Enabled then + table.insert(elements, { title = _U("buy_title"), description = _U("buy_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price))), icon = "fas fa-shopping-cart", value = "property_buy" }) + else + if ESX.PlayerData.job.name == PM.job and ESX.PlayerData.job.grade >= PM.Permissions.SellProperty then + table.insert(elements, { title = _U("sellplayer_title"), description = _U("sellplayer_desc", ESX.Math.GroupDigits(ESX.Round(Property.Price))), icon = "fas fa-shopping-cart", value = "property_sell_re" }) + end + end + if not Property.Locked and not InProperty then + table.insert(elements, { title = _U("view_title"), icon = "fas fa-door-open", value = "property_enter" }) + end end - end - if InProperty and (not Property.Locked or Config.CanAlwaysExit) then - table.insert(elements, {title = _U("exit_title"), icon = "fas fa-sign-out-alt", value = 'property_exit'}) - end + if InProperty and (not Property.Locked or Config.CanAlwaysExit) then + table.insert(elements, { title = _U("exit_title"), icon = "fas fa-sign-out-alt", value = "property_exit" }) + end - return elements + return elements end function OpenPropertyMenu(PropertyId) - if SettingValue ~= "" then - ESX.ShowNotification(_U("property_editing_error")) - return - end - ESX.HideUI() - local Property = Properties[PropertyId] - local elements = PropertyMenuElements(PropertyId) + if SettingValue ~= "" then + ESX.ShowNotification(_U("property_editing_error")) + return + end + ESX.HideUI() + local Property = Properties[PropertyId] + local elements = PropertyMenuElements(PropertyId) - ESX.OpenContext("right", elements, function(menu, element) - if element.value == "property_unlock" then - ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) - if IsUnlocked then - local eles = PropertyMenuElements(PropertyId) - exports["esx_context"]:Refresh(eles) - else - ESX.ShowNotification(_U("unlock_error"), "error") + ESX.OpenContext("right", elements, function(menu, element) + if element.value == "property_unlock" then + ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) + if IsUnlocked then + local eles = PropertyMenuElements(PropertyId) + exports["esx_context"]:Refresh(eles) + else + ESX.ShowNotification(_U("unlock_error"), "error") + end + end, PropertyId) end - end, PropertyId) - end - if element.value == "property_lock" then - ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) - if IsUnlocked then - local eles = PropertyMenuElements(PropertyId) - exports["esx_context"]:Refresh(eles) - else - ESX.ShowNotification(_U("lock_error"), "error") + if element.value == "property_lock" then + ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) + if IsUnlocked then + local eles = PropertyMenuElements(PropertyId) + exports["esx_context"]:Refresh(eles) + else + ESX.ShowNotification(_U("lock_error"), "error") + end + end, PropertyId) end - end, PropertyId) - end - if element.value == "property_cctv" then - CCTV(PropertyId) - end - if element.value == "property_raid" then - ESX.TriggerServerCallback("esx_property:CanRaid", function(CanRaid) - if CanRaid then - ESX.Progressbar(_U("prep_raid"), 15000, {FreezePlayer = true, animation = Config.Raiding.Animation, onFinish = function() - ESX.ShowNotification(_U("raiding"), "success") + if element.value == "property_cctv" then + CCTV(PropertyId) + end + if element.value == "property_raid" then + ESX.TriggerServerCallback("esx_property:CanRaid", function(CanRaid) + if CanRaid then + ESX.Progressbar(_U("prep_raid"), 15000, { + FreezePlayer = true, + animation = Config.Raiding.Animation, + onFinish = function() + ESX.ShowNotification(_U("raiding"), "success") + AttemptHouseEntry(PropertyId) + end, + onCancel = function() + ESX.ShowNotification(_U("cancel_raiding"), "error") + end, + }) + else + ESX.ShowNotification(_U("cannot_raid"), "error") + end + end, PropertyId) + end + if element.value == "property_enter" then + ESX.CloseContext() AttemptHouseEntry(PropertyId) - end, onCancel = function() - ESX.ShowNotification(_U("cancel_raiding"), "error") - end}) - else - ESX.ShowNotification(_U("cannot_raid"), "error") end - end, PropertyId) - end - if element.value == "property_enter" then - ESX.CloseContext() - AttemptHouseEntry(PropertyId) - end - if element.value == "property_keys" then - ESX.CloseContext() - ManageKeys(PropertyId) - end - if element.value == "property_name" then - ESX.CloseContext() - SetPropertyName(PropertyId) - end - if element.value == "property_furniture" then - ESX.CloseContext() - FurnitureMenu(PropertyId) - end - if element.value == "property_inventory" then - ESX.CloseContext() - ShowingUIs.Exit = false - SettingValue = "Storage" - Wait(20) - ESX.TextUI(_U("storage_pos_textui")) - while SettingValue ~= "" do - Wait(1) - if IsControlJustPressed(0, 47) then - SettingValue = "" - ESX.HideUI() - ESX.TriggerServerCallback("esx_property:SetInventoryPosition", function(Success) - if Success then - ESX.ShowNotification(_U("storage_pos_success"), "success") - else - ESX.ShowNotification(_U("storage_pos_error"), "error") + if element.value == "property_keys" then + ESX.CloseContext() + ManageKeys(PropertyId) + end + if element.value == "property_name" then + ESX.CloseContext() + SetPropertyName(PropertyId) + end + if element.value == "property_furniture" then + ESX.CloseContext() + FurnitureMenu(PropertyId) + end + if element.value == "property_inventory" then + ESX.CloseContext() + ShowingUIs.Exit = false + SettingValue = "Storage" + Wait(20) + ESX.TextUI(_U("storage_pos_textui")) + while SettingValue ~= "" do + Wait(1) + if IsControlJustPressed(0, 47) then + SettingValue = "" + ESX.HideUI() + ESX.TriggerServerCallback("esx_property:SetInventoryPosition", function(Success) + if Success then + ESX.ShowNotification(_U("storage_pos_success"), "success") + else + ESX.ShowNotification(_U("storage_pos_error"), "error") + end + end, PropertyId, GetEntityCoords(ESX.PlayerData.ped)) + break + end end - end, PropertyId, GetEntityCoords(ESX.PlayerData.ped)) - break end - end - end - if element.value == "property_wardrobe" then - ESX.CloseContext() - ShowingUIs.Exit = false - SettingValue = "Wardrobe" - Wait(20) - ESX.TextUI(_U("wardrobe_pos_textui")) - while SettingValue ~= "" do - Wait(1) - if IsControlJustPressed(0, 47) then - SettingValue = "" - ESX.HideUI() - ESX.TriggerServerCallback("esx_property:SetWardrobePosition", function(Success) - if Success then - ESX.ShowNotification(_U("wardrobe_pos_success"), "success") - else - ESX.ShowNotification(_U("wardrobe_pos_error"), "error") + if element.value == "property_wardrobe" then + ESX.CloseContext() + ShowingUIs.Exit = false + SettingValue = "Wardrobe" + Wait(20) + ESX.TextUI(_U("wardrobe_pos_textui")) + while SettingValue ~= "" do + Wait(1) + if IsControlJustPressed(0, 47) then + SettingValue = "" + ESX.HideUI() + ESX.TriggerServerCallback("esx_property:SetWardrobePosition", function(Success) + if Success then + ESX.ShowNotification(_U("wardrobe_pos_success"), "success") + else + ESX.ShowNotification(_U("wardrobe_pos_error"), "error") + end + end, PropertyId, GetEntityCoords(ESX.PlayerData.ped)) + break + end end - end, PropertyId, GetEntityCoords(ESX.PlayerData.ped)) - break end - end - end - if element.value == "property_exit" then - ESX.CloseContext() - if SettingValue == "" then - AttemptHouseExit(PropertyId) - else - ESX.ShowNotification(_U("please_finish", SettingValue)) - end - end - if element.value == "property_buy" then - ESX.TriggerServerCallback("esx_property:buyProperty", function(IsBought) - if IsBought then - local eles = PropertyMenuElements(PropertyId) - exports["esx_context"]:Refresh(eles) - else - ESX.ShowNotification(_U("cannot_afford"), "error") + if element.value == "property_exit" then + ESX.CloseContext() + if SettingValue == "" then + AttemptHouseExit(PropertyId) + else + ESX.ShowNotification(_U("please_finish", SettingValue)) + end end - end, PropertyId) - end - if element.value == "property_sell_re" then - local Elements = {{unselectable = true, title = _U("select_player")}} - ESX.TriggerServerCallback("esx_property:GetNearbyPlayers", function(Players) - if Players then - for i = 1, #Players do - Elements[#Elements + 1] = {title = Players[i].name, value = Players[i].source} - end - - ESX.OpenContext("right", Elements, function(menu, element) - if element.value then - ESX.TriggerServerCallback("esx_property:attemptSellToPlayer", function(IsBought) + if element.value == "property_buy" then + ESX.TriggerServerCallback("esx_property:buyProperty", function(IsBought) if IsBought then - local eles = PropertyMenuElements(PropertyId) - exports["esx_context"]:Refresh(eles) + local eles = PropertyMenuElements(PropertyId) + exports["esx_context"]:Refresh(eles) else - ESX.ShowNotification(_U("cannot_sell"), "error") + ESX.ShowNotification(_U("cannot_afford"), "error") end - end, PropertyId, element.value) - end - end) + end, PropertyId) end - end, PropertyId) - end - if element.value == "property_knock" then - ESX.ShowNotification(_U("knock_on_door"), "success") - ESX.TriggerServerCallback("esx_property:KnockOnDoor", function(HasKnocked) - if not HasKnocked then - ESX.ShowNotification(_U("nobody_home"), "error") + if element.value == "property_sell_re" then + local Elements = { { unselectable = true, title = _U("select_player") } } + ESX.TriggerServerCallback("esx_property:GetNearbyPlayers", function(Players) + if Players then + for i = 1, #Players do + Elements[#Elements + 1] = { title = Players[i].name, value = Players[i].source } + end + + ESX.OpenContext("right", Elements, function(menu, element) + if element.value then + ESX.TriggerServerCallback("esx_property:attemptSellToPlayer", function(IsBought) + if IsBought then + local eles = PropertyMenuElements(PropertyId) + exports["esx_context"]:Refresh(eles) + else + ESX.ShowNotification(_U("cannot_sell"), "error") + end + end, PropertyId, element.value) + end + end) + end + end, PropertyId) end - end, PropertyId) - end - if element.value == "property_sell" then - ESX.TriggerServerCallback("esx_property:sellProperty", function(IsSold) - if IsSold then - local eles = PropertyMenuElements(PropertyId) - exports["esx_context"]:Refresh(eles) - else - ESX.ShowNotification(_U("cannot_sell"), "error") + if element.value == "property_knock" then + ESX.ShowNotification(_U("knock_on_door"), "success") + ESX.TriggerServerCallback("esx_property:KnockOnDoor", function(HasKnocked) + if not HasKnocked then + ESX.ShowNotification(_U("nobody_home"), "error") + end + end, PropertyId) end - end, PropertyId) - end - end, function(menu) - CurrentDrawing.Showing = false - end) + if element.value == "property_sell" then + ESX.TriggerServerCallback("esx_property:sellProperty", function(IsSold) + if IsSold then + local eles = PropertyMenuElements(PropertyId) + exports["esx_context"]:Refresh(eles) + else + ESX.ShowNotification(_U("cannot_sell"), "error") + end + end, PropertyId) + end + end, function(menu) + CurrentDrawing.Showing = false + end) end function AttemptHouseExit(PropertyId) - local Property = Properties[PropertyId] + local Property = Properties[PropertyId] - ESX.ShowNotification(_U("exiting"), "success") - FreezeEntityPosition(ESX.PlayerData.ped, true) - InProperty = false - CurrentId = 0 - SettingValue = "" - ESX.HideUI() - ESX.UI.Menu.CloseAll() - SetRainLevel(-1) - DoScreenFadeOut(1500) - Wait(1500) - TriggerServerEvent("esx_property:leave", PropertyId) - if Shell then - DeleteObject(Shell) - Shell = nil - end - if Config.Furniture.Enabled then - for k, v in pairs(SpawnedFurniture) do - DeleteObject(v.obj) + ESX.ShowNotification(_U("exiting"), "success") + FreezeEntityPosition(ESX.PlayerData.ped, true) + InProperty = false + CurrentId = 0 + SettingValue = "" + ESX.HideUI() + ESX.UI.Menu.CloseAll() + SetRainLevel(-1) + DoScreenFadeOut(1500) + Wait(1500) + TriggerServerEvent("esx_property:leave", PropertyId) + if Shell then + DeleteObject(Shell) + Shell = nil end - SpawnedFurniture = {} - end - Wait(1500) - FreezeEntityPosition(ESX.PlayerData.ped, false) - DoScreenFadeIn(1500) + if Config.Furniture.Enabled then + for k, v in pairs(SpawnedFurniture) do + DeleteObject(v.obj) + end + SpawnedFurniture = {} + end + Wait(1500) + FreezeEntityPosition(ESX.PlayerData.ped, false) + DoScreenFadeIn(1500) end RegisterCommand("getoffset", function(source) - if InProperty then - local PlayerPed = ESX.PlayerData.ped - local Pcoords = GetEntityCoords(PlayerPed) - local Property = Properties[CurrentId] - local Interior = GetInteriorValues(Property.Interior) - print(vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Pcoords) - SendNUIMessage({ - link = tostring(vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Pcoords) - }) - end + if InProperty then + local PlayerPed = ESX.PlayerData.ped + local Pcoords = GetEntityCoords(PlayerPed) + local Property = Properties[CurrentId] + local Interior = GetInteriorValues(Property.Interior) + print(vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Pcoords) + SendNUIMessage({ + link = tostring(vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Pcoords), + }) + end end) function AttemptHouseEntry(PropertyId) - local Property = Properties[PropertyId] - local Interior = GetInteriorValues(Property.Interior) - if Interior.type == "shell" and not Config.Shells then - ESX.ShowNotification(_U("shell_disabled"), "error") - return - end - ESX.ShowNotification(_U("entering"), "success") - CurrentId = PropertyId - ESX.UI.Menu.CloseAll() - local Property = Properties[CurrentId] - FreezeEntityPosition(ESX.PlayerData.ped, true) - DoScreenFadeOut(1500) - Wait(1500) - if Interior.type == "shell" then - ESX.Streaming.RequestModel(joaat(Property.Interior), function() - if Shell then - DeleteObject(Shell) - Shell = nil - end - local Pos = vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Shell = CreateObjectNoOffset(joaat(Property.Interior), Pos + Interior.pos, false, false, false) - SetEntityHeading(Shell, 0.0) - while not DoesEntityExist(Shell) do - Wait(1) - end - FreezeEntityPosition(Shell, true) - end) - end - if Properties[PropertyId].furniture then - for k, v in pairs(Properties[PropertyId].furniture) do - ESX.Game.SpawnLocalObject(v.Name, v.Pos, function(object) - SetEntityCoordsNoOffset(object, v.Pos.x, v.Pos.y, v.Pos.z) - SetEntityHeading(object, v.Heading) - SetEntityAsMissionEntity(object, true, true) - FreezeEntityPosition(object, true) - SpawnedFurniture[k] = {obj = object, data = v} - end) + local Property = Properties[PropertyId] + local Interior = GetInteriorValues(Property.Interior) + if Interior.type == "shell" and not Config.Shells then + ESX.ShowNotification(_U("shell_disabled"), "error") + return end - end - local ShowingTextUI2 = false - FreezeEntityPosition(ESX.PlayerData.ped, false) - TriggerServerEvent("esx_property:enter", PropertyId) - Wait(1500) - DoScreenFadeIn(1800) - InProperty = true - if not Config.OxInventory then - Interior.positions.Storage = nil - Properties[CurrentId].positions.Storage = nil - end - - CreateThread(function() - while InProperty do - local Property = Properties[CurrentId] - local Sleep = 1000 - local Near = false - SetRainLevel(0.0) - local PlayerPed = ESX.PlayerData.ped - local PlayerCoords = GetEntityCoords(PlayerPed) - if Interior.type == "shell" then - if #(PlayerCoords - vector3(Property.Entrance.x, Property.Entrance.y, 1999)) < 5.0 then - Sleep = 0 - DrawMarker(27, vector3(Property.Entrance.x, Property.Entrance.y, 2000.2), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 50, 200, 200, - false, false, 2, true, nil, nil, false) - if #(PlayerCoords.xy - vector2(Property.Entrance.x, Property.Entrance.y)) <= 2.5 then - Near = true - if not ShowingUIs.Exit then - - local Pname = Properties[CurrentId].setName ~= "" and Properties[CurrentId].setName or Properties[CurrentId].Name - ESX.TextUI(_U("access_textui", Pname)) - ShowingUIs.Exit = true - end - if IsControlJustPressed(0, 38) then - OpenPropertyMenu(CurrentId) + ESX.ShowNotification(_U("entering"), "success") + CurrentId = PropertyId + ESX.UI.Menu.CloseAll() + local Property = Properties[CurrentId] + FreezeEntityPosition(ESX.PlayerData.ped, true) + DoScreenFadeOut(1500) + Wait(1500) + if Interior.type == "shell" then + ESX.Streaming.RequestModel(joaat(Property.Interior), function() + if Shell then + DeleteObject(Shell) + Shell = nil end - else - if not Near and ShowingUIs.Exit and SettingValue == "" then - ShowingUIs.Exit = false - ESX.HideUI() - ESX.CloseContext() + local Pos = vector3(Property.Entrance.x, Property.Entrance.y, 2000) + Shell = CreateObjectNoOffset(joaat(Property.Interior), Pos + Interior.pos, false, false, false) + SetEntityHeading(Shell, 0.0) + while not DoesEntityExist(Shell) do + Wait(1) end - end + FreezeEntityPosition(Shell, true) + end) + end + if Properties[PropertyId].furniture then + for k, v in pairs(Properties[PropertyId].furniture) do + ESX.Game.SpawnLocalObject(v.Name, v.Pos, function(object) + SetEntityCoordsNoOffset(object, v.Pos.x, v.Pos.y, v.Pos.z) + SetEntityHeading(object, v.Heading) + SetEntityAsMissionEntity(object, true, true) + FreezeEntityPosition(object, true) + SpawnedFurniture[k] = { obj = object, data = v } + end) end + end + local ShowingTextUI2 = false + FreezeEntityPosition(ESX.PlayerData.ped, false) + TriggerServerEvent("esx_property:enter", PropertyId) + Wait(1500) + DoScreenFadeIn(1800) + InProperty = true + if not Config.OxInventory then + Interior.positions.Storage = nil + Properties[CurrentId].positions.Storage = nil + end + + CreateThread(function() + while InProperty do + local Property = Properties[CurrentId] + local Sleep = 1000 + local Near = false + SetRainLevel(0.0) + local PlayerPed = ESX.PlayerData.ped + local PlayerCoords = GetEntityCoords(PlayerPed) + if Interior.type == "shell" then + if #(PlayerCoords - vector3(Property.Entrance.x, Property.Entrance.y, 1999)) < 5.0 then + Sleep = 0 + DrawMarker(27, vector3(Property.Entrance.x, Property.Entrance.y, 2000.2), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 50, 200, 200, false, false, 2, true, nil, nil, false) + if #(PlayerCoords.xy - vector2(Property.Entrance.x, Property.Entrance.y)) <= 2.5 then + Near = true + if not ShowingUIs.Exit then + local Pname = Properties[CurrentId].setName ~= "" and Properties[CurrentId].setName or Properties[CurrentId].Name + ESX.TextUI(_U("access_textui", Pname)) + ShowingUIs.Exit = true + end + if IsControlJustPressed(0, 38) then + OpenPropertyMenu(CurrentId) + end + else + if not Near and ShowingUIs.Exit and SettingValue == "" then + ShowingUIs.Exit = false + ESX.HideUI() + ESX.CloseContext() + end + end + end - if Property.Owned then - for k, v in pairs(Properties[CurrentId].positions) do - local v = vector3(v.x, v.y, v.z) - local CanDo = true - if CanDo then - local Poss = vector3(Property.Entrance.x, Property.Entrance.y, 1999) - v - if #(PlayerCoords - Poss) < 5.0 then - Sleep = 0 - DrawMarker(27, Poss, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 200, 50, 50, 200, false, false, 2, true, nil, nil, false) - if #(PlayerCoords - Poss) < 2.0 and SettingValue == "" then - Near = true - if not ShowingUIs[k] then - ShowingUIs[k] = true + if Property.Owned then + for k, v in pairs(Properties[CurrentId].positions) do + local v = vector3(v.x, v.y, v.z) + local CanDo = true + if CanDo then + local Poss = vector3(Property.Entrance.x, Property.Entrance.y, 1999) - v + if #(PlayerCoords - Poss) < 5.0 then + Sleep = 0 + DrawMarker(27, Poss, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 200, 50, 50, 200, false, false, 2, true, nil, nil, false) + if #(PlayerCoords - Poss) < 2.0 and SettingValue == "" then + Near = true + if not ShowingUIs[k] then + ShowingUIs[k] = true - ESX.TextUI(_U("access_textui", k)) - end - if IsControlJustPressed(0, 38) then - OpenInteractionMenu(CurrentId, k) - end - else - if not Near and ShowingUIs[k] and SettingValue == "" then - ShowingUIs[k] = false - ESX.HideUI() - end + ESX.TextUI(_U("access_textui", k)) + end + if IsControlJustPressed(0, 38) then + OpenInteractionMenu(CurrentId, k) + end + else + if not Near and ShowingUIs[k] and SettingValue == "" then + ShowingUIs[k] = false + ESX.HideUI() + end + end + end + end + end + if not Near and ShowingUIs and SettingValue == "" then + ShowingTextUI2 = false + ESX.HideUI() + end + end + else + if #(PlayerCoords - Interior.pos) < 5.0 then + Sleep = 0 + DrawMarker(27, vector3(Interior.pos.xy, Interior.pos.z - 0.98), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 50, 200, 200, false, false, 2, true, nil, nil, false) + if #(PlayerCoords - Interior.pos) < 2.0 then + if not ShowingUIs.Exit then + ShowingUIs.Exit = true + local Pname = Properties[CurrentId].setName ~= "" and Properties[CurrentId].setName or Properties[CurrentId].Name + ESX.TextUI(_U("access_textui", Pname)) + end + if IsControlJustPressed(0, 38) then + OpenPropertyMenu(CurrentId) + end + else + if ShowingUIs.Exit and SettingValue == "" then + ShowingUIs.Exit = false + ESX.HideUI() + ESX.CloseContext() + end + end end - end - end - end - if not Near and ShowingUIs and SettingValue == "" then - ShowingTextUI2 = false - ESX.HideUI() - end - end - else - if #(PlayerCoords - Interior.pos) < 5.0 then - Sleep = 0 - DrawMarker(27, vector3(Interior.pos.xy, Interior.pos.z - 0.98), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 50, 200, 200, false, false, - 2, true, nil, nil, false) - if #(PlayerCoords - Interior.pos) < 2.0 then - if not ShowingUIs.Exit then - ShowingUIs.Exit = true - local Pname = Properties[CurrentId].setName ~= "" and Properties[CurrentId].setName or Properties[CurrentId].Name - ESX.TextUI(_U("access_textui", Pname)) - end - if IsControlJustPressed(0, 38) then - OpenPropertyMenu(CurrentId) - end - else - if ShowingUIs.Exit and SettingValue == "" then - ShowingUIs.Exit = false - ESX.HideUI() - ESX.CloseContext() - end - end - end - if Property.Owned then - for k, v in pairs(Properties[CurrentId].positions) do - v = vector3(v.x, v.y, v.z) - local CanDo = true + if Property.Owned then + for k, v in pairs(Properties[CurrentId].positions) do + v = vector3(v.x, v.y, v.z) + local CanDo = true - if CanDo then - if #(PlayerCoords - v) < 5.0 then - Sleep = 0 - DrawMarker(27, vector3(v.xy, v.z - 0.98), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 200, 50, 50, 200, false, false, 2, true, nil, - nil, false) - if #(PlayerCoords - v) < 2.0 then - if not ShowingUIs[k] then - ShowingUIs[k] = true - ESX.TextUI(_U("access_textui", k)) - end - if IsControlJustPressed(0, 38) then - OpenInteractionMenu(CurrentId, k) - end - else - if ShowingUIs[k] and SettingValue == "" then - ShowingUIs[k] = false - ESX.HideUI() - end + if CanDo then + if #(PlayerCoords - v) < 5.0 then + Sleep = 0 + DrawMarker(27, vector3(v.xy, v.z - 0.98), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 200, 50, 50, 200, false, false, 2, true, nil, nil, false) + if #(PlayerCoords - v) < 2.0 then + if not ShowingUIs[k] then + ShowingUIs[k] = true + ESX.TextUI(_U("access_textui", k)) + end + if IsControlJustPressed(0, 38) then + OpenInteractionMenu(CurrentId, k) + end + else + if ShowingUIs[k] and SettingValue == "" then + ShowingUIs[k] = false + ESX.HideUI() + end + end + end + end + end end - end end - end + Wait(Sleep) end - end - Wait(Sleep) - end - end) + end) end function StoreVehicle(PropertyId) - local Vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped, false) - if Vehicle then - local VehProperties = ESX.Game.GetVehicleProperties(Vehicle) - VehProperties.DisplayName = GetLabelText(GetDisplayNameFromVehicleModel(VehProperties.model)) - ESX.TriggerServerCallback("esx_property:StoreVehicle", function(result) - if result then - SetEntityAsMissionEntity(Vehicle, true, true) - DeleteVehicle(Vehicle) - ESX.ShowNotification(_U("store_success"), "success") - return - else - ESX.ShowNotification(_U("store_error"), "error") - return - end - end, PropertyId, VehProperties) - end + local Vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped, false) + if Vehicle then + local VehProperties = ESX.Game.GetVehicleProperties(Vehicle) + VehProperties.DisplayName = GetLabelText(GetDisplayNameFromVehicleModel(VehProperties.model)) + ESX.TriggerServerCallback("esx_property:StoreVehicle", function(result) + if result then + SetEntityAsMissionEntity(Vehicle, true, true) + DeleteVehicle(Vehicle) + ESX.ShowNotification(_U("store_success"), "success") + return + else + ESX.ShowNotification(_U("store_error"), "error") + return + end + end, PropertyId, VehProperties) + end end function AccessGarage(PropertyId) - ESX.TriggerServerCallback("esx_property:AccessGarage", function(Vehicles) - if Vehicles then - local elements = {{unselectable = true, icon = "fas fa-warehouse", title = _U("property_garage")}} - for k, v in pairs(Vehicles) do - elements[#elements + 1] = {title = v.vehicle.DisplayName .. " | " .. v.vehicle.plate, Properties = v.vehicle, index = k} - end - ESX.OpenContext("right", elements, function(menu, element) - if element.Properties then - ESX.CloseContext() - ESX.ShowNotification(_U("retriving_notify",element.Properties.DisplayName)) - if ESX.Game.IsSpawnPointClear(vector3(Properties[PropertyId].garage.pos.x, Properties[PropertyId].garage.pos.y, - Properties[PropertyId].garage.pos.z), 3.0) then - ESX.Game.SpawnVehicle(element.Properties.model, Properties[PropertyId].garage.pos, Properties[PropertyId].garage.Heading, - function(vehicle) - SetEntityAsMissionEntity(vehicle, true, true) - ESX.Game.SetVehicleProperties(vehicle, element.Properties) - TaskWarpPedIntoVehicle(ESX.PlayerData.ped, vehicle, -1) - SetModelAsNoLongerNeeded(element.Properties.model) - TriggerServerEvent("esx_property:SetVehicleOut", PropertyId, element.index) - end) - end + ESX.TriggerServerCallback("esx_property:AccessGarage", function(Vehicles) + if Vehicles then + local elements = { { unselectable = true, icon = "fas fa-warehouse", title = _U("property_garage") } } + for k, v in pairs(Vehicles) do + elements[#elements + 1] = { title = v.vehicle.DisplayName .. " | " .. v.vehicle.plate, Properties = v.vehicle, index = k } + end + ESX.OpenContext("right", elements, function(menu, element) + if element.Properties then + ESX.CloseContext() + ESX.ShowNotification(_U("retriving_notify", element.Properties.DisplayName)) + if ESX.Game.IsSpawnPointClear(vector3(Properties[PropertyId].garage.pos.x, Properties[PropertyId].garage.pos.y, Properties[PropertyId].garage.pos.z), 3.0) then + ESX.Game.SpawnVehicle(element.Properties.model, Properties[PropertyId].garage.pos, Properties[PropertyId].garage.Heading, function(vehicle) + SetEntityAsMissionEntity(vehicle, true, true) + ESX.Game.SetVehicleProperties(vehicle, element.Properties) + TaskWarpPedIntoVehicle(ESX.PlayerData.ped, vehicle, -1) + SetModelAsNoLongerNeeded(element.Properties.model) + TriggerServerEvent("esx_property:SetVehicleOut", PropertyId, element.index) + end) + end + end + end) + else + ESX.ShowNotification(_U("cannot_access"), "error") + return end - end) - else - ESX.ShowNotification(_U("cannot_access"), "error") - return - end - end, PropertyId) + end, PropertyId) end CreateThread(function() - local ShowingTextUI = false - while true do - local Sleep = 2000 + local ShowingTextUI = false + while true do + local Sleep = 2000 - if #(Properties) > 0 then - Sleep = 800 - local nearby = false - for i = 1, #(Properties) do - if Properties[i].Entrance then - local GetEntityCoords = GetEntityCoords - local IsControlJustPressed = IsControlJustPressed - local DrawMarker = DrawMarker - local Coords = GetEntityCoords(ESX.PlayerData.ped) - local Entrance = vector3(Properties[i].Entrance.x, Properties[i].Entrance.y, Properties[i].Entrance.z) - if not InCCTV then - if #(Coords - Entrance) < 10.0 then - Sleep = 0 - DrawMarker(27, Entrance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) - if #(Coords - Entrance) < 1.5 then - nearby = true - local PropertyName = Properties[i].setName ~= "" and Properties[i].setName or Properties[i].Name - if not CurrentDrawing.Showing or CurrentDrawing.Name ~= PropertyName then - CurrentDrawing.Name = PropertyName - CurrentDrawing.Showing = true - ESX.TextUI(_U("access_textui", PropertyName)) - end - if IsControlJustPressed(0, 38) then - OpenPropertyMenu(i) + if #Properties > 0 then + Sleep = 800 + local nearby = false + for i = 1, #Properties do + if Properties[i].Entrance then + local GetEntityCoords = GetEntityCoords + local IsControlJustPressed = IsControlJustPressed + local DrawMarker = DrawMarker + local Coords = GetEntityCoords(ESX.PlayerData.ped) + local Entrance = vector3(Properties[i].Entrance.x, Properties[i].Entrance.y, Properties[i].Entrance.z) + if not InCCTV then + if #(Coords - Entrance) < 10.0 then + Sleep = 0 + DrawMarker(27, Entrance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) + if #(Coords - Entrance) < 1.5 then + nearby = true + local PropertyName = Properties[i].setName ~= "" and Properties[i].setName or Properties[i].Name + if not CurrentDrawing.Showing or CurrentDrawing.Name ~= PropertyName then + CurrentDrawing.Name = PropertyName + CurrentDrawing.Showing = true + ESX.TextUI(_U("access_textui", PropertyName)) + end + if IsControlJustPressed(0, 38) then + OpenPropertyMenu(i) + end + end + end + end + if Properties[i].garage.enabled and Properties[i].garage.pos and (ESX.PlayerData.identifier == Properties[i].Owner or PlayerKeys[i]) then + local Garage = vector3(Properties[i].garage.pos.x, Properties[i].garage.pos.y, Properties[i].garage.pos.z) + if #(Coords - Garage) < 10.0 then + Sleep = 0 + DrawMarker(36, Garage, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 1.5, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) + if #(Coords - Garage) < 3.0 then + nearby = true + if GetVehiclePedIsUsing(ESX.PlayerData.ped) ~= 0 then + local veh = GetVehiclePedIsIn(ESX.PlayerData.ped, false) + local vehmodel = GetEntityModel(veh) + local DisplayName = GetLabelText(GetDisplayNameFromVehicleModel(vehmodel)) + if not CurrentDrawing.Showing or CurrentDrawing.Name ~= DisplayName then + CurrentDrawing.Name = DisplayName + CurrentDrawing.Showing = true + ESX.TextUI(_U("store_textui", DisplayName)) + end + else + if not CurrentDrawing.Showing or CurrentDrawing.Name ~= "Garage" then + CurrentDrawing.Name = "Garage" + CurrentDrawing.Showing = true + ESX.TextUI(_U("access_textui", "garage")) + end + end + if IsControlJustPressed(0, 38) then + if GetVehiclePedIsUsing(ESX.PlayerData.ped) ~= 0 then + StoreVehicle(i) + else + AccessGarage(i) + end + end + end + end + end end - end end - end - if Properties[i].garage.enabled and Properties[i].garage.pos and (ESX.PlayerData.identifier == Properties[i].Owner or PlayerKeys[i]) then - local Garage = vector3(Properties[i].garage.pos.x, Properties[i].garage.pos.y, Properties[i].garage.pos.z) - if #(Coords - Garage) < 10.0 then - Sleep = 0 - DrawMarker(36, Garage, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 1.5, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) - if #(Coords - Garage) < 3.0 then - nearby = true - if GetVehiclePedIsUsing(ESX.PlayerData.ped) ~= 0 then - local veh = GetVehiclePedIsIn(ESX.PlayerData.ped, false) - local vehmodel = GetEntityModel(veh) - local DisplayName = GetLabelText(GetDisplayNameFromVehicleModel(vehmodel)) - if not CurrentDrawing.Showing or CurrentDrawing.Name ~= DisplayName then - CurrentDrawing.Name = DisplayName - CurrentDrawing.Showing = true - ESX.TextUI(_U("store_textui", DisplayName)) - end - else - if not CurrentDrawing.Showing or CurrentDrawing.Name ~= "Garage" then - CurrentDrawing.Name = "Garage" - CurrentDrawing.Showing = true - ESX.TextUI(_U("access_textui", "garage")) - end - end - if IsControlJustPressed(0, 38) then - if GetVehiclePedIsUsing(ESX.PlayerData.ped) ~= 0 then - StoreVehicle(i) - else - AccessGarage(i) - end - end - end + if not nearby and CurrentDrawing.Showing and SettingValue == "" then + ESX.HideUI() + CurrentDrawing.Showing = false + ESX.CloseContext() end - end end - end - if not nearby and CurrentDrawing.Showing and SettingValue == "" then - ESX.HideUI() - CurrentDrawing.Showing = false - ESX.CloseContext() - end + Wait(Sleep) end - Wait(Sleep) - end end) function OpenPMQuickMenu(Action) - if Action == "Entrance" then - DoScreenFadeOut(1500) - Wait(1500) - ESX.TriggerServerCallback("esx_property:PMenterOffice", function(HasEntered) - if HasEntered then - ESX.ShowNotification(_U("enter_office"), "success") - else - ESX.ShowNotification(_U("enter_office_error"), "error") - end - Wait(1500) - DoScreenFadeIn(1500) - end) - elseif Action == "Exit" then - DoScreenFadeOut(1500) - Wait(1500) - ESX.TriggerServerCallback("esx_property:PMexitOffice", function(HasExited) - if HasExited then - ESX.ShowNotification(_U("exit_office"), "success") - else - ESX.ShowNotification(_U("exit_office_error"), "error") - end - Wait(1500) - DoScreenFadeIn(1500) - end) - elseif Action == "Properties" then - TriggerEvent("esx_property:AdminMenu") - - elseif Action == "ActionsMenu" then - local elements = {{unselectable = true, title = _U("actions"), value = "RealEstateActions"}} + if Action == "Entrance" then + DoScreenFadeOut(1500) + Wait(1500) + ESX.TriggerServerCallback("esx_property:PMenterOffice", function(HasEntered) + if HasEntered then + ESX.ShowNotification(_U("enter_office"), "success") + else + ESX.ShowNotification(_U("enter_office_error"), "error") + end + Wait(1500) + DoScreenFadeIn(1500) + end) + elseif Action == "Exit" then + DoScreenFadeOut(1500) + Wait(1500) + ESX.TriggerServerCallback("esx_property:PMexitOffice", function(HasExited) + if HasExited then + ESX.ShowNotification(_U("exit_office"), "success") + else + ESX.ShowNotification(_U("exit_office_error"), "error") + end + Wait(1500) + DoScreenFadeIn(1500) + end) + elseif Action == "Properties" then + TriggerEvent("esx_property:AdminMenu") + elseif Action == "ActionsMenu" then + local elements = { { unselectable = true, title = _U("actions"), value = "RealEstateActions" } } - if ESX.PlayerData.job.name == PM.job then - if ESX.PlayerData.job.grade >= PM.Permissions.CreateProperty then - elements[#elements + 1] = {title = _U("property_create"), value = "CreateProperty"} - end - if ESX.PlayerData.job.grade >= PM.Permissions.ManagePropertiesFromQuickActions then - elements[#elements + 1] = {title = _U("property_manage"), value = "manage"} - end + if ESX.PlayerData.job.name == PM.job then + if ESX.PlayerData.job.grade >= PM.Permissions.CreateProperty then + elements[#elements + 1] = { title = _U("property_create"), value = "CreateProperty" } + end + if ESX.PlayerData.job.grade >= PM.Permissions.ManagePropertiesFromQuickActions then + elements[#elements + 1] = { title = _U("property_manage"), value = "manage" } + end + end + ESX.OpenContext("right", elements, function(menu, element) + if element.value == "CreateProperty" then + TriggerEvent("esx_property:CreateProperty") + end + if element.value == "manage" then + TriggerEvent("esx_property:AdminMenu") + end + end) end - ESX.OpenContext("right", elements, function(menu, element) - if element.value == "CreateProperty" then - TriggerEvent("esx_property:CreateProperty") - end - if element.value == "manage" then - TriggerEvent("esx_property:AdminMenu") - end - end) - end end ESX.RegisterInput(_U("realestate_command"), _U("realestate_command_desc"), "keyboard", "F5", function() - ESX.TriggerServerCallback('esx_property:CanAccessRealEstateMenu', function(Access) - if Access then - OpenPMQuickMenu("ActionsMenu") - end - end) + ESX.TriggerServerCallback("esx_property:CanAccessRealEstateMenu", function(Access) + if Access then + OpenPMQuickMenu("ActionsMenu") + end + end) end) -local PMdrawing = {Entrance = false, Exit = false} +local PMdrawing = { Entrance = false, Exit = false } CreateThread(function() - while PM.Enabled do - local Sleep = 2500 - local DrawMarker = DrawMarker - if ESX.IsPlayerLoaded() then - if ESX.PlayerData.job and ESX.PlayerData.job.name == PM.job then - Sleep = 1500 + while PM.Enabled do + local Sleep = 2500 + local DrawMarker = DrawMarker + if ESX.IsPlayerLoaded() then + if ESX.PlayerData.job and ESX.PlayerData.job.name == PM.job then + Sleep = 1500 - local Coords = GetEntityCoords(ESX.PlayerData.ped) - local nearby = false + local Coords = GetEntityCoords(ESX.PlayerData.ped) + local nearby = false - for k, v in pairs(PM.Locations) do - local Dist = #(Coords - v) - if Dist <= 10.0 then - nearby = true - Sleep = 0 - DrawMarker(27, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) - if Dist <= 1.5 then - if not PMdrawing[k] then - PMdrawing[k] = true - ESX.TextUI(_U("realestate_textui", k)) - end - if IsControlJustPressed(0, 38) then - OpenPMQuickMenu(k) - end - end - else - if not nearby and PMdrawing[k] then - ESX.HideUI() - PMdrawing[k] = false - ESX.CloseContext() + for k, v in pairs(PM.Locations) do + local Dist = #(Coords - v) + if Dist <= 10.0 then + nearby = true + Sleep = 0 + DrawMarker(27, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 50, 200, 50, 200, false, false, 2, true, nil, nil, false) + if Dist <= 1.5 then + if not PMdrawing[k] then + PMdrawing[k] = true + ESX.TextUI(_U("realestate_textui", k)) + end + if IsControlJustPressed(0, 38) then + OpenPMQuickMenu(k) + end + end + else + if not nearby and PMdrawing[k] then + ESX.HideUI() + PMdrawing[k] = false + ESX.CloseContext() + end + end + end end - end end - end + Wait(Sleep) end - Wait(Sleep) - end end) local HouseData = {} RegisterNetEvent("esx_property:CreateProperty", function() - ESX.TriggerServerCallback('esx_property:CanCreateProperty', function(data) - if data then - local GetEntityCoords = GetEntityCoords - local GetStreetNameAtCoord = GetStreetNameAtCoord - local GetStreetNameFromHashKey = GetStreetNameFromHashKey - local Pcoords = GetEntityCoords(ESX.PlayerData.ped) - local StreetHash = GetStreetNameAtCoord(Pcoords.x, Pcoords.y, Pcoords.z) - local StreetName = GetStreetNameFromHashKey(StreetHash) - local Zone = GetZoneAtCoords(Pcoords.x, Pcoords.y, Pcoords.z) - local ZoneScum = GetZoneScumminess(Zone) - local SuggestedPrice = Config.ZonePriceOptions.Enabled and Config.ZonePriceOptions.Default * Config.ZonePrices[ZoneScum] or nil - HouseData = {} - local Property = {{unselectable = true, icon = "fas fa-plus", title = _U("menu_title")}, - {value = 0, title = _U("element_title1"), icon = "fas fa-list-ol", description = _U("element_description1"), input = true, - inputType = "number", inputPlaceholder = "Number...", inputValue = nil, inputMin = 1, inputMax = 90000, index = "hnumber"}, - {title = _U("element_title2"), icon = "fas fa-dollar-sign", input = true, inputType = "number",description = _U("element_description2"), - inputPlaceholder = "Price...", inputValue = SuggestedPrice, inputMin = 1, inputMax = 900000000, index = "price"}, - {title = _U("element_title3"), description = _U("element_description3"), icon = "fas fa-home", index = "interior"}, - {title = _U("element_title4"), description = _U("element_description4"), icon = "fas fa-warehouse", value = {enabled = false}, - index = "garage", disabled = not (Config.Garage.Enabled)}, - {title = _U("element_title5"), description = _U("element_description5"), icon = "fas fa-video", - value = {enabled = false, rot = GetGameplayCamRot(2), maxleft = 80, maxright = -20}, index = "cctv", - disabled = not (Config.CCTV.Enabled)}, - {title = _U("element_title6"),description = _U("element_description6"), icon = "fas fa-map-marker-alt", index = "entrance"}, - {title = _U("element_create_title"), icon = "fas fa-check", description = _U("element_create_desc_1"), index = "creation"}} - local function OpenCreate() - local opos = {} - ESX.OpenContext("right", Property, function(menu, element) - if menu.eles[2] and menu.eles[2].inputValue and menu.eles[1].title == _U("menu_title") then - Property[2].inputValue = menu.eles[2].inputValue - HouseData.name = menu.eles[2].inputValue .. " " .. StreetName - end - if menu.eles[3] and menu.eles[3].inputValue and menu.eles[1].title == _U("menu_title") then - Property[3].inputValue = menu.eles[3].inputValue - HouseData.price = menu.eles[3].inputValue - end - if element.index then - if element.index == "entrance" then - local PlayerPos = GetEntityCoords(ESX.PlayerData.ped) - HouseData.entrance = {x = ESX.Math.Round(PlayerPos.x, 2), y = ESX.Math.Round(PlayerPos.y, 2), z = ESX.Math.Round(PlayerPos.z, 2) - 0.98} - Property[7].title = _U("entrance_set_title") - Property[7].description = _U("entrance_set_description",HouseData.entrance.x, HouseData.entrance.y, HouseData.entrance.z) - OpenCreate() - end - if element.index == "selectedinterior" then - HouseData.interior = element.value - Property[4].title = _U("interior_set_title") - Property[4].description = _U("interior_set_description",element.title) - OpenCreate() - end - if element.index == "IPL" then - local ints = {{unselectable = true, icon = "fas fa-warehouse", title = _U("ipl_title")}} - for i = 1, #(Config.Interiors.IPL) do - ints[#ints + 1] = {title = Config.Interiors.IPL[i].label, index = "selectedinterior", value = Config.Interiors.IPL[i].value} - exports["esx_context"]:Refresh(ints, "right") - end - end - if element.index == "Shells" then - local ints = {{unselectable = true, icon = "fas fa-warehouse", title = _U("shell_title")}} - for i = 1, #(Config.Interiors.Shells) do - ints[#ints + 1] = {title = Config.Interiors.Shells[i].label, index = "selectedinterior", value = Config.Interiors.Shells[i].value} - exports["esx_context"]:Refresh(ints, "right") - end - end - if element.index == "interior" then - local catsa = {{unselectable = true, icon = "fas fa-warehouse", title = _U("types_title")}, - {title = _U("ipl_title"), description = _U("ipl_description"), index = "IPL"}} - if Config.Shells then - catsa[3] = {title = _U("shell_title"), description = _U("shell_description"), index = "Shells"} - end - exports["esx_context"]:Refresh(catsa, "right") - end - if element.index == "return" then - OpenCreate() - end - if element.index == "cctv" then - local status = Property[6].value.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-video", title = _U("cctv_settings")}, - {title = _U("toggle_title"), icon = status == _U("enabled") and "fas fa-eye" or "fas fa-eye-slash", - description = _U("toggle_description",status), index = "ToggleCCTV"}, - {title = _U("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, - description = _U("cctv_set_description"), index = "SetCCTVangle"}, - {title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return"}} - exports["esx_context"]:Refresh(opos, "right") - end - if element.index == "ToggleCCTV" then - Property[6].value.enabled = not Property[6].value.enabled - local status = Property[6].value.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-video", title = _U("cctv_settings")}, - {title = _U("toggle_title"), icon = status == _U("enabled") and "fas fa-eye" or "fas fa-eye-slash", - description = _U("toggle_description",status), index = "ToggleCCTV"}, - {title = _U("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, - description = _U("cctv_set_description"), index = "SetCCTVangle"}, - {title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return"}} - exports["esx_context"]:Refresh(opos, "right") - end - if Config.Garage.Enabled and element.index == "garage" then - local status = Property[5].value.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings")}, - {title = _U("toggle_title"), icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = _U("toggle_description",status), index = "ToggleGarage"}} - if Property[5].value.enabled then - opos[#opos + 1] = {title = _U("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, - description = _U("garage_set_description"), index = "SetGaragePos"} - if Property[5].value.pos then - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return"} - end - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - end - if element.index == "ToggleGarage" then - Property[5].value.enabled = not Property[5].value.enabled - local status = Property[5].value.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings")}, - {title = _U("toggle_title"), icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = _U("toggle_description",status), index = "ToggleGarage"}} - if Property[5].value.enabled then - opos[#opos + 1] = {title = _U("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, - description = _U("garage_set_description"), index = "SetGaragePos"} - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - end - if element.index == "SetGaragePos" then - ESX.CloseContext() - ESX.TextUI(_U("garage_textui")) - while true do - Wait(0) - if IsControlJustPressed(0, 38) then - local PlayerPos = GetEntityCoords(ESX.PlayerData.ped) - Property[5].value.pos = GetEntityCoords(ESX.PlayerData.ped) - Property[5].value.heading = GetEntityHeading(ESX.PlayerData.ped) - ESX.HideUI() - OpenCreate() - break - end - end - end - if element.index == "SetCCTVangle" then - ESX.CloseContext() - ESX.TextUI(_U("cctv_textui_1")) - local stage = "angle" - while true do - Wait(0) - if IsControlJustPressed(0, 38) then - if stage == "angle" then - Property[6].value.rot = GetGameplayCamRot(2) - ESX.TextUI(_U("cctv_textui_2")) - stage = "maxright" - elseif stage == "maxright" then - Property[6].value.maxright = GetGameplayCamRot(2).z - ESX.TextUI(_U("cctv_textui_3")) - stage = "maxleft" - elseif stage == "maxleft" then - Property[6].value.maxleft = GetGameplayCamRot(2).z - ESX.HideUI() - OpenCreate() - break - end - end - end - end - if element.index == "creation" then - if HouseData.price and HouseData.name and HouseData.entrance and HouseData.interior then - local newProperty = {name = HouseData.name, price = HouseData.price, interior = HouseData.interior, entrance = HouseData.entrance, - cctv = Property[6].value, garage = Property[5].value} - TriggerServerEvent("esx_property:server:createProperty", newProperty) - ESX.ShowNotification(_U("create_success"), "success") - ESX.CloseContext() - HouseData = {} - else - ESX.ShowNotification(_U("missing_data"), "error") - end - end - end - end) - end - OpenCreate() - end - end) -end) - -RegisterNetEvent("esx_property:AdminMenu", function() - ESX.TriggerServerCallback('esx_property:IsAdmin', function(data) - if data then - - function ManageProperty(currentProperty) - local Interior = GetInteriorValues(Properties[currentProperty].Interior) - ESX.TriggerServerCallback('esx_property:IsAdmin', function(data) - if data then - local opos = {} - local function GetData() - local elements = {{unselectable = true, icon = "fas fa-cogs", title = "Property Management"}, - {title = _U("back"), icon = "fas fa-arrow-left", value = "back"}, - {title = "Toggle Lock", icon = (Properties[currentProperty].Locked and "fas fa-lock") or "fas fa-unlock", - description = "Lock/Unlock The Property.", value = "lock"}, - {title = "Enter", description = "Force Entry Into The Property.", icon = "fas fa-door-open", value = "enter"}, - {title = "Price", icon = "fas fa-dollar-sign", description = "Alter The Price Of The Property.", value = "price"}, - {title = "Set Interior", description = "Renovate The Property`s Interior.", icon = "fas fa-home", value = "interior"}, - {title = "Entrance", description = "Set The Entrance As Your Position.", icon = "fas fa-map-marker-alt", - value = "entrance"}} - if Properties[currentProperty].setName ~= "" then - elements[#elements + 1] = {title = "Clear Custom Name", icon = "fa-solid fa-ban", - description = "Current Name: " .. Properties[currentProperty].setName, value = "remove_custom_name"} - end - if Config.Furniture.Enabled and #(Properties[currentProperty].furniture) > 0 then - elements[#elements + 1] = {title = "Reset Furniture", description = "Delete All Property Furniture", icon = "fas fa-eraser", - value = "refurni"} - end - if Config.Garage.Enabled then - elements[#elements + 1] = {title = "Garage", description = "Change Garage Settings", icon = "fa-solid fa-warehouse", value = "garage"} - end - if Config.CCTV.Enabled then - elements[#elements + 1] = {title = "CCTV", description = "Change CCTV Settings", icon = "fa-solid fa-camera", value = "cctv"} - end - if (Config.OxInventory) and Properties[currentProperty].positions.Storage and - (ESX.Round(Interior.positions.Storage.x, 2) ~= Properties[currentProperty].positions.Storage.x or - ESX.Round(Interior.positions.Storage.y, 2) ~= Properties[currentProperty].positions.Storage.y) then - elements[#elements + 1] = {title = "Reset Storage Position", description = "Set Storage Position To Interior Default.", - icon = "fas fa-eraser", value = "restorage"} - end - if Interior.positions.Wardrobe then - if ESX.Round(Interior.positions.Wardrobe.x, 2) ~= ESX.Round(Properties[currentProperty].positions.Wardrobe.x, 2) or - ESX.Round(Interior.positions.Wardrobe.y, 2) ~= ESX.Round(Properties[currentProperty].positions.Wardrobe.y, 2) then - elements[#elements + 1] = {title = "Reset Wardrobe Position", description = "Set Wardrobe Position To Interior Default.", - icon = "fas fa-eraser", value = "rewardrobe"} - end - end - if Properties[currentProperty].Owned then - elements[#elements + 1] = {title = "Remove Owner", icon = "fas fa-user-times", description = "Evict The Owner Of The Property.", - value = "removeowner"} - end - return elements - end - ESX.OpenContext("right", GetData(), function(menu, element) - if element.value then - if element.value == "lock" then - ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) - if IsUnlocked then - ESX.ShowNotification("Lock Toggled!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Lock This Property", "error") - end - end, currentProperty) - end - if element.value == "enter" then - AttemptHouseEntry(currentProperty) - end - if element.value == "removeowner" then - ESX.TriggerServerCallback("esx_property:evictOwner", function(Evicted) - if Evicted then - ESX.ShowNotification("Owner Evicted!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Evict This Owner!", "error") + ESX.TriggerServerCallback("esx_property:CanCreateProperty", function(data) + if data then + local GetEntityCoords = GetEntityCoords + local GetStreetNameAtCoord = GetStreetNameAtCoord + local GetStreetNameFromHashKey = GetStreetNameFromHashKey + local Pcoords = GetEntityCoords(ESX.PlayerData.ped) + local StreetHash = GetStreetNameAtCoord(Pcoords.x, Pcoords.y, Pcoords.z) + local StreetName = GetStreetNameFromHashKey(StreetHash) + local Zone = GetZoneAtCoords(Pcoords.x, Pcoords.y, Pcoords.z) + local ZoneScum = GetZoneScumminess(Zone) + local SuggestedPrice = Config.ZonePriceOptions.Enabled and Config.ZonePriceOptions.Default * Config.ZonePrices[ZoneScum] or nil + HouseData = {} + local Property = { + { unselectable = true, icon = "fas fa-plus", title = _U("menu_title") }, + { value = 0, title = _U("element_title1"), icon = "fas fa-list-ol", description = _U("element_description1"), input = true, inputType = "number", inputPlaceholder = "Number...", inputValue = nil, inputMin = 1, inputMax = 90000, index = "hnumber" }, + { title = _U("element_title2"), icon = "fas fa-dollar-sign", input = true, inputType = "number", description = _U("element_description2"), inputPlaceholder = "Price...", inputValue = SuggestedPrice, inputMin = 1, inputMax = 900000000, index = "price" }, + { title = _U("element_title3"), description = _U("element_description3"), icon = "fas fa-home", index = "interior" }, + { title = _U("element_title4"), description = _U("element_description4"), icon = "fas fa-warehouse", value = { enabled = false }, index = "garage", disabled = not Config.Garage.Enabled }, + { + title = _U("element_title5"), + description = _U("element_description5"), + icon = "fas fa-video", + value = { enabled = false, rot = GetGameplayCamRot(2), maxleft = 80, maxright = -20 }, + index = "cctv", + disabled = not Config.CCTV.Enabled, + }, + { title = _U("element_title6"), description = _U("element_description6"), icon = "fas fa-map-marker-alt", index = "entrance" }, + { title = _U("element_create_title"), icon = "fas fa-check", description = _U("element_create_desc_1"), index = "creation" }, + } + local function OpenCreate() + local opos = {} + ESX.OpenContext("right", Property, function(menu, element) + if menu.eles[2] and menu.eles[2].inputValue and menu.eles[1].title == _U("menu_title") then + Property[2].inputValue = menu.eles[2].inputValue + HouseData.name = menu.eles[2].inputValue .. " " .. StreetName end - end, currentProperty) - end - if element.value == "garage" then - local status = Properties[currentProperty].garage.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings")}, - {title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = "Current Status: " .. status, value = "ToggleGarage"}} - if Properties[currentProperty].garage.enabled then - opos[#opos + 1] = {title = "Set Position", icon = "fas fa-map-marker-alt", - disabled = not Properties[currentProperty].garage.enabled, - description = "Sets the Garage Position to your Players Position", value = "SetGaragePos"} - if Properties[currentProperty].garage.pos then - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", - value = "return"} - end - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - end - if element.value == "cctv" then - local status = Properties[currentProperty].cctv.enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("cctv_settings")}, - {title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = "Current Status: " .. status, value = "ToggleCCTV"}} - if Properties[currentProperty].cctv.enabled then - opos[#opos + 1] = {title = "Set Angle", icon = "fas fa-map-marker-alt", disabled = not Properties[currentProperty].cctv.enabled, - description = "Sets the Angle of the Camera.", value = "SetCCTVangle"} - if Properties[currentProperty].cctv.rot then - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", - value = "return"} + if menu.eles[3] and menu.eles[3].inputValue and menu.eles[1].title == _U("menu_title") then + Property[3].inputValue = menu.eles[3].inputValue + HouseData.price = menu.eles[3].inputValue end - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - end - if element.value == "ToggleGarage" then - ESX.TriggerServerCallback("esx_property:toggleGarage", function(IsUnlocked, enabled) - if IsUnlocked then - ESX.ShowNotification("Garage Toggled!", "success") - local status = enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings")}, - {title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = "Current Status: " .. status, value = "ToggleGarage"}} - if enabled then - opos[#opos + 1] = {title = "Set Position", icon = "fas fa-map-marker-alt", disabled = not enabled, - description = "Sets the Garage Position to your Players Position", value = "SetGaragePos"} - if Properties[currentProperty].garage.pos then - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", - value = "return"} + if element.index then + if element.index == "entrance" then + local PlayerPos = GetEntityCoords(ESX.PlayerData.ped) + HouseData.entrance = { x = ESX.Math.Round(PlayerPos.x, 2), y = ESX.Math.Round(PlayerPos.y, 2), z = ESX.Math.Round(PlayerPos.z, 2) - 0.98 } + Property[7].title = _U("entrance_set_title") + Property[7].description = _U("entrance_set_description", HouseData.entrance.x, HouseData.entrance.y, HouseData.entrance.z) + OpenCreate() end - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", - value = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - else - ESX.ShowNotification("You ~r~Cannot~s~ Toggle This Option!", "error") - end - end, currentProperty) - end - if element.value == "ToggleCCTV" then - ESX.TriggerServerCallback("esx_property:toggleCCTV", function(IsUnlocked, enabled) - if IsUnlocked then - ESX.ShowNotification("CCTV Toggled!", "success") - local status = enabled and _U("enabled") or _U("disabled") - opos = {{unselectable = true, icon = "fas fa-warehouse", title = _U("cctv_settings")}, - {title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", - description = "Current Status: " .. status, value = "ToggleCCTV"}} - if enabled then - opos[#opos + 1] = {title = "Set Angle", icon = "fas fa-map-marker-alt", disabled = not enabled, - description = "Sets the Angle of the Camera.", value = "SetCCTVangle"} - if Properties[currentProperty].cctv.rot then - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", - value = "return"} + if element.index == "selectedinterior" then + HouseData.interior = element.value + Property[4].title = _U("interior_set_title") + Property[4].description = _U("interior_set_description", element.title) + OpenCreate() end - else - opos[#opos + 1] = {title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", - value = "return"} - end - exports["esx_context"]:Refresh(opos, "right") - else - ESX.ShowNotification("You ~r~Cannot~s~ Toggle This Option!", "error") - end - end, currentProperty) - end - if element.value == "SetGaragePos" then - ESX.CloseContext() - ESX.TextUI("Press ~b~[E]~s~ to Set Position") - SettingValue = "Garage" - while SettingValue ~= "" do - Wait(0) - if IsControlJustPressed(0, 38) then - ESX.TriggerServerCallback("esx_property:SetGaragePos", function(IsChanged) - if IsChanged then - ESX.HideUI() - SettingValue = "" - ESX.ShowNotification("Position Changed!", "success") - ManageProperty(currentProperty) - else - ESX.ShowNotification("You ~r~Cannot~s~ Change This Option!", "error") + if element.index == "IPL" then + local ints = { { unselectable = true, icon = "fas fa-warehouse", title = _U("ipl_title") } } + for i = 1, #Config.Interiors.IPL do + ints[#ints + 1] = { title = Config.Interiors.IPL[i].label, index = "selectedinterior", value = Config.Interiors.IPL[i].value } + exports["esx_context"]:Refresh(ints, "right") + end end - end, currentProperty, GetEntityHeading(ESX.PlayerData.ped)) - break - end - end - end - if element.value == "SetCCTVangle" then - ESX.CloseContext() - ESX.TextUI("Press ~b~[E]~s~ to Set Angle") - local stage = "angle" - SettingValue = "cctv" - local Angles = {} - while stage do - Wait(0) - if IsControlJustPressed(0, 38) then - if stage == "angle" then - Angles.rot = GetGameplayCamRot(2) - ESX.TextUI("Press ~b~[E]~s~ to Set Max Right Roation") - stage = "maxright" - elseif stage == "maxright" then - Angles.maxright = GetGameplayCamRot(2).z - ESX.TextUI("Press ~b~[E]~s~ to Set Max Left Roation") - stage = "maxleft" - elseif stage == "maxleft" then - Angles.maxleft = GetGameplayCamRot(2).z - ESX.TriggerServerCallback("esx_property:SetCCTVangle", function(IsChanged) - if IsChanged then - SettingValue = "" - stage = nil - ESX.HideUI() - ESX.ShowNotification("Angle Changed!", "success") - ManageProperty(currentProperty) - else - ESX.ShowNotification("You ~r~Cannot~s~ Change This Option!", "error") - end - end, currentProperty, Angles) - break - end - end - end - end - if element.value == "remove_custom_name" then - ESX.TriggerServerCallback("esx_property:RemoveCustomName", function(Cleared) - if Cleared then - ESX.ShowNotification("Property Name Reset!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Reset This Property`s Name!", "error") - end - end, currentProperty) - end - if element.value == "refurni" then - ESX.TriggerServerCallback("esx_property:RemoveAllfurniture", function(Removed) - if Removed then - ESX.ShowNotification("Furniture Reset!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Reset This Property!", "error") - end - end, currentProperty) - end - if element.value == "restorage" then - ESX.TriggerServerCallback("esx_property:SetInventoryPosition", function(Reset) - if Reset then - ESX.ShowNotification("~b~Storage~s~ Position Reset!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Reset This Property!", "error") - end - end, currentProperty, Interior.positions.Storage, true) - end - if element.value == "rewardrobe" then - ESX.TriggerServerCallback("esx_property:SetWardrobePosition", function(Reset) - if Reset then - ESX.ShowNotification("~b~Wardrobe~s~ Position Reset!", "success") - exports["esx_context"]:Refresh(GetData()) - else - ESX.ShowNotification("You Cannot Reset This Property!", "error") - end - end, currentProperty, Interior.positions.Wardrobe, true) - end - if element.value == "back" then - AdminOptions(currentProperty) - end - if element.value == "return" then - exports["esx_context"]:Refresh(GetData()) - end - if element.value == "price" then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'PropertyPrice', {title = "Property Price"}, function(data4, menu4) - if data4.value then - ESX.TriggerServerCallback("esx_property:ChangePrice", function(IsChanged) - if IsChanged then - ESX.ShowNotification("Price Changed!", "success") - menu4.close() - else - ESX.ShowNotification("You Cannot Change this property!", "error") + if element.index == "Shells" then + local ints = { { unselectable = true, icon = "fas fa-warehouse", title = _U("shell_title") } } + for i = 1, #Config.Interiors.Shells do + ints[#ints + 1] = { title = Config.Interiors.Shells[i].label, index = "selectedinterior", value = Config.Interiors.Shells[i].value } + exports["esx_context"]:Refresh(ints, "right") + end end - end, currentProperty, tonumber(data4.value)) - end - end, function(data4, menu4) - menu4.close() - end) - end - if element.value == "interior" then - local elements = {{unselectable = true, icon = "fas fa-warehouse", title = "Interior Types"}, - {title = "IPL Interiors", description = "Native GTA Interiors, Made by R*", value = "IPL"}} - if Config.Shells then - elements[3] = {title = "Custom Interiors", description = "Custom Interiors, Made by You", value = "Shells"} - end - ESX.OpenContext("right", elements, function(menu, element) - if element.value then - local elements = {{unselectable = true, icon = "fas fa-warehouse", title = "Interiors"}} - for i = 1, #(Config.Interiors[element.value]) do - elements[#elements + 1] = {title = Config.Interiors[element.value][i].label, value = Config.Interiors[element.value][i].value} - end - ESX.OpenContext("right", elements, function(menu, element) - if element.value then - ESX.TriggerServerCallback("esx_property:ChangeInterior", function(IsChanged) - if IsChanged then - ESX.ShowNotification("Interior Changed!", "success") - ESX.CloseContext() + if element.index == "interior" then + local catsa = { { unselectable = true, icon = "fas fa-warehouse", title = _U("types_title") }, { title = _U("ipl_title"), description = _U("ipl_description"), index = "IPL" } } + if Config.Shells then + catsa[3] = { title = _U("shell_title"), description = _U("shell_description"), index = "Shells" } + end + exports["esx_context"]:Refresh(catsa, "right") + end + if element.index == "return" then + OpenCreate() + end + if element.index == "cctv" then + local status = Property[6].value.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-video", title = _U("cctv_settings") }, + { title = _U("toggle_title"), icon = status == _U("enabled") and "fas fa-eye" or "fas fa-eye-slash", description = _U("toggle_description", status), index = "ToggleCCTV" }, + { title = _U("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, description = _U("cctv_set_description"), index = "SetCCTVangle" }, + { title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return" }, + } + exports["esx_context"]:Refresh(opos, "right") + end + if element.index == "ToggleCCTV" then + Property[6].value.enabled = not Property[6].value.enabled + local status = Property[6].value.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-video", title = _U("cctv_settings") }, + { title = _U("toggle_title"), icon = status == _U("enabled") and "fas fa-eye" or "fas fa-eye-slash", description = _U("toggle_description", status), index = "ToggleCCTV" }, + { title = _U("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, description = _U("cctv_set_description"), index = "SetCCTVangle" }, + { title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return" }, + } + exports["esx_context"]:Refresh(opos, "right") + end + if Config.Garage.Enabled and element.index == "garage" then + local status = Property[5].value.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings") }, + { title = _U("toggle_title"), icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = _U("toggle_description", status), index = "ToggleGarage" }, + } + if Property[5].value.enabled then + opos[#opos + 1] = { title = _U("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, description = _U("garage_set_description"), index = "SetGaragePos" } + if Property[5].value.pos then + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return" } + end + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + end + if element.index == "ToggleGarage" then + Property[5].value.enabled = not Property[5].value.enabled + local status = Property[5].value.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings") }, + { title = _U("toggle_title"), icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = _U("toggle_description", status), index = "ToggleGarage" }, + } + if Property[5].value.enabled then + opos[#opos + 1] = { title = _U("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, description = _U("garage_set_description"), index = "SetGaragePos" } + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = _U("back_description"), index = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + end + if element.index == "SetGaragePos" then + ESX.CloseContext() + ESX.TextUI(_U("garage_textui")) + while true do + Wait(0) + if IsControlJustPressed(0, 38) then + local PlayerPos = GetEntityCoords(ESX.PlayerData.ped) + Property[5].value.pos = GetEntityCoords(ESX.PlayerData.ped) + Property[5].value.heading = GetEntityHeading(ESX.PlayerData.ped) + ESX.HideUI() + OpenCreate() + break + end + end + end + if element.index == "SetCCTVangle" then + ESX.CloseContext() + ESX.TextUI(_U("cctv_textui_1")) + local stage = "angle" + while true do + Wait(0) + if IsControlJustPressed(0, 38) then + if stage == "angle" then + Property[6].value.rot = GetGameplayCamRot(2) + ESX.TextUI(_U("cctv_textui_2")) + stage = "maxright" + elseif stage == "maxright" then + Property[6].value.maxright = GetGameplayCamRot(2).z + ESX.TextUI(_U("cctv_textui_3")) + stage = "maxleft" + elseif stage == "maxleft" then + Property[6].value.maxleft = GetGameplayCamRot(2).z + ESX.HideUI() + OpenCreate() + break + end + end + end + end + if element.index == "creation" then + if HouseData.price and HouseData.name and HouseData.entrance and HouseData.interior then + local newProperty = { name = HouseData.name, price = HouseData.price, interior = HouseData.interior, entrance = HouseData.entrance, cctv = Property[6].value, garage = Property[5].value } + TriggerServerEvent("esx_property:server:createProperty", newProperty) + ESX.ShowNotification(_U("create_success"), "success") + ESX.CloseContext() + HouseData = {} else - ESX.ShowNotification("You Cannot Change this property!", "error") + ESX.ShowNotification(_U("missing_data"), "error") end - end, currentProperty, element.value) end - end) end - end, function() - ManageProperty(currentProperty) - end) - end - if element.value == "entrance" then - ESX.TriggerServerCallback("esx_property:ChangeEntrance", function(IsChanged) - if IsChanged then - ESX.ShowNotification("Entrance Changed!", "success") - else - ESX.ShowNotification("You Cannot Change this property!", "error") + end) + end + OpenCreate() + end + end) +end) + +RegisterNetEvent("esx_property:AdminMenu", function() + ESX.TriggerServerCallback("esx_property:IsAdmin", function(data) + if data then + function ManageProperty(currentProperty) + local Interior = GetInteriorValues(Properties[currentProperty].Interior) + ESX.TriggerServerCallback("esx_property:IsAdmin", function(data) + if data then + local opos = {} + local function GetData() + local elements = { + { unselectable = true, icon = "fas fa-cogs", title = "Property Management" }, + { title = _U("back"), icon = "fas fa-arrow-left", value = "back" }, + { title = "Toggle Lock", icon = (Properties[currentProperty].Locked and "fas fa-lock") or "fas fa-unlock", description = "Lock/Unlock The Property.", value = "lock" }, + { title = "Enter", description = "Force Entry Into The Property.", icon = "fas fa-door-open", value = "enter" }, + { title = "Price", icon = "fas fa-dollar-sign", description = "Alter The Price Of The Property.", value = "price" }, + { title = "Set Interior", description = "Renovate The Property`s Interior.", icon = "fas fa-home", value = "interior" }, + { title = "Entrance", description = "Set The Entrance As Your Position.", icon = "fas fa-map-marker-alt", value = "entrance" }, + } + if Properties[currentProperty].setName ~= "" then + elements[#elements + 1] = { title = "Clear Custom Name", icon = "fa-solid fa-ban", description = "Current Name: " .. Properties[currentProperty].setName, value = "remove_custom_name" } + end + if Config.Furniture.Enabled and #Properties[currentProperty].furniture > 0 then + elements[#elements + 1] = { title = "Reset Furniture", description = "Delete All Property Furniture", icon = "fas fa-eraser", value = "refurni" } + end + if Config.Garage.Enabled then + elements[#elements + 1] = { title = "Garage", description = "Change Garage Settings", icon = "fa-solid fa-warehouse", value = "garage" } + end + if Config.CCTV.Enabled then + elements[#elements + 1] = { title = "CCTV", description = "Change CCTV Settings", icon = "fa-solid fa-camera", value = "cctv" } + end + if + Config.OxInventory + and Properties[currentProperty].positions.Storage + and (ESX.Round(Interior.positions.Storage.x, 2) ~= Properties[currentProperty].positions.Storage.x or ESX.Round(Interior.positions.Storage.y, 2) ~= Properties[currentProperty].positions.Storage.y) + then + elements[#elements + 1] = { title = "Reset Storage Position", description = "Set Storage Position To Interior Default.", icon = "fas fa-eraser", value = "restorage" } + end + if Interior.positions.Wardrobe then + if ESX.Round(Interior.positions.Wardrobe.x, 2) ~= ESX.Round(Properties[currentProperty].positions.Wardrobe.x, 2) or ESX.Round(Interior.positions.Wardrobe.y, 2) ~= ESX.Round(Properties[currentProperty].positions.Wardrobe.y, 2) then + elements[#elements + 1] = { title = "Reset Wardrobe Position", description = "Set Wardrobe Position To Interior Default.", icon = "fas fa-eraser", value = "rewardrobe" } + end + end + if Properties[currentProperty].Owned then + elements[#elements + 1] = { title = "Remove Owner", icon = "fas fa-user-times", description = "Evict The Owner Of The Property.", value = "removeowner" } + end + return elements + end + ESX.OpenContext("right", GetData(), function(menu, element) + if element.value then + if element.value == "lock" then + ESX.TriggerServerCallback("esx_property:toggleLock", function(IsUnlocked) + if IsUnlocked then + ESX.ShowNotification("Lock Toggled!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Lock This Property", "error") + end + end, currentProperty) + end + if element.value == "enter" then + AttemptHouseEntry(currentProperty) + end + if element.value == "removeowner" then + ESX.TriggerServerCallback("esx_property:evictOwner", function(Evicted) + if Evicted then + ESX.ShowNotification("Owner Evicted!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Evict This Owner!", "error") + end + end, currentProperty) + end + if element.value == "garage" then + local status = Properties[currentProperty].garage.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings") }, + { title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = "Current Status: " .. status, value = "ToggleGarage" }, + } + if Properties[currentProperty].garage.enabled then + opos[#opos + 1] = { title = "Set Position", icon = "fas fa-map-marker-alt", disabled = not Properties[currentProperty].garage.enabled, description = "Sets the Garage Position to your Players Position", value = "SetGaragePos" } + if Properties[currentProperty].garage.pos then + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + end + if element.value == "cctv" then + local status = Properties[currentProperty].cctv.enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("cctv_settings") }, + { title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = "Current Status: " .. status, value = "ToggleCCTV" }, + } + if Properties[currentProperty].cctv.enabled then + opos[#opos + 1] = { title = "Set Angle", icon = "fas fa-map-marker-alt", disabled = not Properties[currentProperty].cctv.enabled, description = "Sets the Angle of the Camera.", value = "SetCCTVangle" } + if Properties[currentProperty].cctv.rot then + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + end + if element.value == "ToggleGarage" then + ESX.TriggerServerCallback("esx_property:toggleGarage", function(IsUnlocked, enabled) + if IsUnlocked then + ESX.ShowNotification("Garage Toggled!", "success") + local status = enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("garage_settings") }, + { title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = "Current Status: " .. status, value = "ToggleGarage" }, + } + if enabled then + opos[#opos + 1] = { title = "Set Position", icon = "fas fa-map-marker-alt", disabled = not enabled, description = "Sets the Garage Position to your Players Position", value = "SetGaragePos" } + if Properties[currentProperty].garage.pos then + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + else + ESX.ShowNotification("You ~r~Cannot~s~ Toggle This Option!", "error") + end + end, currentProperty) + end + if element.value == "ToggleCCTV" then + ESX.TriggerServerCallback("esx_property:toggleCCTV", function(IsUnlocked, enabled) + if IsUnlocked then + ESX.ShowNotification("CCTV Toggled!", "success") + local status = enabled and _U("enabled") or _U("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = _U("cctv_settings") }, + { title = "Toggle Usage", icon = status == _U("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = "Current Status: " .. status, value = "ToggleCCTV" }, + } + if enabled then + opos[#opos + 1] = { title = "Set Angle", icon = "fas fa-map-marker-alt", disabled = not enabled, description = "Sets the Angle of the Camera.", value = "SetCCTVangle" } + if Properties[currentProperty].cctv.rot then + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = _U("back"), icon = "fas fa-arrow-left", description = "return to Property Management", value = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + else + ESX.ShowNotification("You ~r~Cannot~s~ Toggle This Option!", "error") + end + end, currentProperty) + end + if element.value == "SetGaragePos" then + ESX.CloseContext() + ESX.TextUI("Press ~b~[E]~s~ to Set Position") + SettingValue = "Garage" + while SettingValue ~= "" do + Wait(0) + if IsControlJustPressed(0, 38) then + ESX.TriggerServerCallback("esx_property:SetGaragePos", function(IsChanged) + if IsChanged then + ESX.HideUI() + SettingValue = "" + ESX.ShowNotification("Position Changed!", "success") + ManageProperty(currentProperty) + else + ESX.ShowNotification("You ~r~Cannot~s~ Change This Option!", "error") + end + end, currentProperty, GetEntityHeading(ESX.PlayerData.ped)) + break + end + end + end + if element.value == "SetCCTVangle" then + ESX.CloseContext() + ESX.TextUI("Press ~b~[E]~s~ to Set Angle") + local stage = "angle" + SettingValue = "cctv" + local Angles = {} + while stage do + Wait(0) + if IsControlJustPressed(0, 38) then + if stage == "angle" then + Angles.rot = GetGameplayCamRot(2) + ESX.TextUI("Press ~b~[E]~s~ to Set Max Right Roation") + stage = "maxright" + elseif stage == "maxright" then + Angles.maxright = GetGameplayCamRot(2).z + ESX.TextUI("Press ~b~[E]~s~ to Set Max Left Roation") + stage = "maxleft" + elseif stage == "maxleft" then + Angles.maxleft = GetGameplayCamRot(2).z + ESX.TriggerServerCallback("esx_property:SetCCTVangle", function(IsChanged) + if IsChanged then + SettingValue = "" + stage = nil + ESX.HideUI() + ESX.ShowNotification("Angle Changed!", "success") + ManageProperty(currentProperty) + else + ESX.ShowNotification("You ~r~Cannot~s~ Change This Option!", "error") + end + end, currentProperty, Angles) + break + end + end + end + end + if element.value == "remove_custom_name" then + ESX.TriggerServerCallback("esx_property:RemoveCustomName", function(Cleared) + if Cleared then + ESX.ShowNotification("Property Name Reset!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Reset This Property`s Name!", "error") + end + end, currentProperty) + end + if element.value == "refurni" then + ESX.TriggerServerCallback("esx_property:RemoveAllfurniture", function(Removed) + if Removed then + ESX.ShowNotification("Furniture Reset!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Reset This Property!", "error") + end + end, currentProperty) + end + if element.value == "restorage" then + ESX.TriggerServerCallback("esx_property:SetInventoryPosition", function(Reset) + if Reset then + ESX.ShowNotification("~b~Storage~s~ Position Reset!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Reset This Property!", "error") + end + end, currentProperty, Interior.positions.Storage, true) + end + if element.value == "rewardrobe" then + ESX.TriggerServerCallback("esx_property:SetWardrobePosition", function(Reset) + if Reset then + ESX.ShowNotification("~b~Wardrobe~s~ Position Reset!", "success") + exports["esx_context"]:Refresh(GetData()) + else + ESX.ShowNotification("You Cannot Reset This Property!", "error") + end + end, currentProperty, Interior.positions.Wardrobe, true) + end + if element.value == "back" then + AdminOptions(currentProperty) + end + if element.value == "return" then + exports["esx_context"]:Refresh(GetData()) + end + if element.value == "price" then + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "PropertyPrice", { title = "Property Price" }, function(data4, menu4) + if data4.value then + ESX.TriggerServerCallback("esx_property:ChangePrice", function(IsChanged) + if IsChanged then + ESX.ShowNotification("Price Changed!", "success") + menu4.close() + else + ESX.ShowNotification("You Cannot Change this property!", "error") + end + end, currentProperty, tonumber(data4.value)) + end + end, function(data4, menu4) + menu4.close() + end) + end + if element.value == "interior" then + local elements = { { unselectable = true, icon = "fas fa-warehouse", title = "Interior Types" }, { title = "IPL Interiors", description = "Native GTA Interiors, Made by R*", value = "IPL" } } + if Config.Shells then + elements[3] = { title = "Custom Interiors", description = "Custom Interiors, Made by You", value = "Shells" } + end + ESX.OpenContext("right", elements, function(menu, element) + if element.value then + local elements = { { unselectable = true, icon = "fas fa-warehouse", title = "Interiors" } } + for i = 1, #Config.Interiors[element.value] do + elements[#elements + 1] = { title = Config.Interiors[element.value][i].label, value = Config.Interiors[element.value][i].value } + end + ESX.OpenContext("right", elements, function(menu, element) + if element.value then + ESX.TriggerServerCallback("esx_property:ChangeInterior", function(IsChanged) + if IsChanged then + ESX.ShowNotification("Interior Changed!", "success") + ESX.CloseContext() + else + ESX.ShowNotification("You Cannot Change this property!", "error") + end + end, currentProperty, element.value) + end + end) + end + end, function() + ManageProperty(currentProperty) + end) + end + if element.value == "entrance" then + ESX.TriggerServerCallback("esx_property:ChangeEntrance", function(IsChanged) + if IsChanged then + ESX.ShowNotification("Entrance Changed!", "success") + else + ESX.ShowNotification("You Cannot Change this property!", "error") + end + end, currentProperty, GetEntityCoords(ESX.PlayerData.ped)) + end + end + end) end - end, currentProperty, GetEntityCoords(ESX.PlayerData.ped)) - end - end - end) - end - end) - end + end) + end - function AdminOptions(currentProperty) - ESX.TriggerServerCallback('esx_property:IsAdmin', function(data) - if data then - local elements = {{unselectable = true, icon = "fas fa-home", title = "Property Options"}, - {title = _U("back"), icon = "fas fa-arrow-left", value = "back"}, - {title = "Manage", icon = "fas fa-cogs", description = "Alter This Property's Settings.", value = "manage"}, - {title = "Teleport", description = "Teleport To This Property.", icon = "fas fa-map-marker-alt", value = "goto"}, - {title = "Set GPS", description = "Set GPS position To Property.", icon = "fa-solid fa-location-dot", value = "gps"}, - {title = "Delete", icon = "fas fa-trash-alt", description = "Remove Current Property.", value = "delete"}} + function AdminOptions(currentProperty) + ESX.TriggerServerCallback("esx_property:IsAdmin", function(data) + if data then + local elements = { + { unselectable = true, icon = "fas fa-home", title = "Property Options" }, + { title = _U("back"), icon = "fas fa-arrow-left", value = "back" }, + { title = "Manage", icon = "fas fa-cogs", description = "Alter This Property's Settings.", value = "manage" }, + { title = "Teleport", description = "Teleport To This Property.", icon = "fas fa-map-marker-alt", value = "goto" }, + { title = "Set GPS", description = "Set GPS position To Property.", icon = "fa-solid fa-location-dot", value = "gps" }, + { title = "Delete", icon = "fas fa-trash-alt", description = "Remove Current Property.", value = "delete" }, + } - ESX.OpenContext("right", elements, function(menu, element) - if element.value then - if element.value == "goto" then - SetEntityCoords(ESX.PlayerData.ped, Properties[currentProperty].Entrance.x, Properties[currentProperty].Entrance.y, - Properties[currentProperty].Entrance.z) - ESX.ShowNotification("Teleported to Property!") - end - if element.value == "gps" then - SetNewWaypoint(Properties[currentProperty].Entrance.x, Properties[currentProperty].Entrance.y) - ESX.ShowNotification("GPS Set!") - end - if element.value == "back" then - AdminMenu() - end - if element.value == "delete" then - ESX.TriggerServerCallback("esx_property:deleteProperty", function(response) - if response then - ESX.ShowNotification("Property Deleted!", "success") - ESX.CloseContext() - else - ESX.ShowNotification("You Cannot Delete This Property", "error") - end - end, currentProperty) - end + ESX.OpenContext("right", elements, function(menu, element) + if element.value then + if element.value == "goto" then + SetEntityCoords(ESX.PlayerData.ped, Properties[currentProperty].Entrance.x, Properties[currentProperty].Entrance.y, Properties[currentProperty].Entrance.z) + ESX.ShowNotification("Teleported to Property!") + end + if element.value == "gps" then + SetNewWaypoint(Properties[currentProperty].Entrance.x, Properties[currentProperty].Entrance.y) + ESX.ShowNotification("GPS Set!") + end + if element.value == "back" then + AdminMenu() + end + if element.value == "delete" then + ESX.TriggerServerCallback("esx_property:deleteProperty", function(response) + if response then + ESX.ShowNotification("Property Deleted!", "success") + ESX.CloseContext() + else + ESX.ShowNotification("You Cannot Delete This Property", "error") + end + end, currentProperty) + end - if element.value == "manage" then - ManageProperty(currentProperty) - end - end - end) - end - end) - end + if element.value == "manage" then + ManageProperty(currentProperty) + end + end + end) + end + end) + end - function AdminMenu() - ESX.TriggerServerCallback('esx_property:IsAdmin', function(data) - if data then - local elements = {{unselectable = true, icon = "fas fa-home", title = "Properties Management"}} - for i = 1, #(Properties) do - if Properties[i].Entrance then - local description = "" - if Properties[i].setName ~= "" then - description = description .. "\nName: " .. Properties[i].setName - end - if Properties[i].Owned then - description = description .. "\nOwner: " .. Properties[i].OwnerName - end - table.insert(elements, {title = Properties[i].Name, value = i, description = description, icon = "fas fa-home"}) - end + function AdminMenu() + ESX.TriggerServerCallback("esx_property:IsAdmin", function(data) + if data then + local elements = { { unselectable = true, icon = "fas fa-home", title = "Properties Management" } } + for i = 1, #Properties do + if Properties[i].Entrance then + local description = "" + if Properties[i].setName ~= "" then + description = description .. "\nName: " .. Properties[i].setName + end + if Properties[i].Owned then + description = description .. "\nOwner: " .. Properties[i].OwnerName + end + table.insert(elements, { title = Properties[i].Name, value = i, description = description, icon = "fas fa-home" }) + end + end + ESX.OpenContext("right", elements, function(menu, element) + if element.value then + ESX.CloseContext() + AdminOptions(element.value) + end + end) + end + end) end - ESX.OpenContext("right", elements, function(menu, element) - if element.value then - ESX.CloseContext() - AdminOptions(element.value) - end - end) - end - end) - end - AdminMenu() - else - ESX.ShowNotification("You ~r~Cannot~s~ Access This Menu!", 5000, "error") - end - end) + AdminMenu() + else + ESX.ShowNotification("You ~r~Cannot~s~ Access This Menu!", 5000, "error") + end + end) end) diff --git a/server-data/resources/[esx_addons]/esx_property/config.lua b/server-data/resources/[esx_addons]/esx_property/config.lua index ae74fe449..ae1bc90fd 100644 --- a/server-data/resources/[esx_addons]/esx_property/config.lua +++ b/server-data/resources/[esx_addons]/esx_property/config.lua @@ -6,7 +6,7 @@ Config.OwnedBlips = true -- Add blips for Owned Properties --------------------------------------------------------------- --------------------- General Settings --------------------------------- -Config.Locale = 'it' +Config.Locale = "en" Config.Shells = false -- Enable/Disable Shell Interiors Default: false Config.SaveInterval = 5 -- Interval in Minutes to Save Properties Config.CanAlwaysExit = true -- Disabling this allows players to be locked in @@ -16,646 +16,644 @@ Config.CanCustomiseInventoryAndWardrobePositions = true -- Allow users to custom Config.WipeCustomNameOnSell = true -- Wipe custom name on sell Default: true Config.WipeFurnitureOnSell = true -- Wipe custom name on sell Default: true - --------------------- Zone Suggested Prices --------------------------------- Config.ZonePriceOptions = { - Enabled = true, -- Enable/Disable Zone Prices Modifiers Default: true - Default = 250000, -- Default Price of a property Default: 250000 + Enabled = true, -- Enable/Disable Zone Prices Modifiers Default: true + Default = 250000, -- Default Price of a property Default: 250000 } -- The Amount to Multiply the Default Price by (if the above is enabled): Config.ZonePrices = { -[0] = 10, -- Posh -[1] = 7, -- Nice -[2] = 5, -- Above Average -[3] = 3, -- Bellow Average -[4] = 2, -- Crap -[5] = 1, -- Scum + [0] = 10, -- Posh + [1] = 7, -- Nice + [2] = 5, -- Above Average + [3] = 3, -- Bellow Average + [4] = 2, -- Crap + [5] = 1, -- Scum } --------------------- Raid Settings --------------------------------- Config.Raiding = { - Enabled = true, -- Enable/Disable Raiding Default: true - CanAdminsRaid = true, -- Can Admins Raid Houses Default: true - ItemRequired = { -- Item Required to Raid -- Remove To Disable - RemoveItem = true, -- Remove Item from Inventory Default: true - name = "bread", -- Item Name Default: "bread" - label = "Bread", -- Item label Default: "Bread" - ItemCount = 1, -- Item Count Default: 1 - }, - Animation = { - type = "Scenario", - Scenario = "WORLD_HUMAN_HAMMERING", - }, + Enabled = true, -- Enable/Disable Raiding Default: true + CanAdminsRaid = true, -- Can Admins Raid Houses Default: true + ItemRequired = { -- Item Required to Raid -- Remove To Disable + RemoveItem = true, -- Remove Item from Inventory Default: true + name = "bread", -- Item Name Default: "bread" + label = "Bread", -- Item label Default: "Bread" + ItemCount = 1, -- Item Count Default: 1 + }, + Animation = { + type = "Scenario", + Scenario = "WORLD_HUMAN_HAMMERING", + }, } --------------------- Garage Settings --------------------------------- Config.Garage = { - Enabled = true, -- Enable/Disable Garage Default: true - OwnedVehiclesOnly = true, -- Only allow owned vehicles to be stored Default: true - MySQLquery = "UPDATE `owned_vehicles` SET `stored` = ? WHERE `plate` = ?" -- MySQL Query to store vehicles `?` = True/false, Vehicle Plate + Enabled = true, -- Enable/Disable Garage Default: true + OwnedVehiclesOnly = true, -- Only allow owned vehicles to be stored Default: true + MySQLquery = "UPDATE `owned_vehicles` SET `stored` = ? WHERE `plate` = ?", -- MySQL Query to store vehicles `?` = True/false, Vehicle Plate } --------------------- Log Settings --------------------------------- if IsDuplicityVersion() then - Config.Logs = { - Webhook = "", - LogLevel = 1 + Config.Logs = { + Webhook = "", + LogLevel = 1, - ----------- Log Levels ------------ - -- 0 = No Logs - -- 1 = Logs Major Actions - -- 2 = Logs Major + Minor Actions - -- 3 = Logs All Actions - ------------------------------------- - } + ----------- Log Levels ------------ + -- 0 = No Logs + -- 1 = Logs Major Actions + -- 2 = Logs Major + Minor Actions + -- 3 = Logs All Actions + ------------------------------------- + } end --------------------- Furniture Settings --------------------------------- Config.Furniture = { - Enabled = true, - RotationSpeed = 0.4, -- Object Rotation Speed - MovementSpeed = 0.01, -- Object Movement Speed - MovementZspeed = 0.05, -- Object Z Movement Speed - WipeFurnitureOnSell = true, -- Wipe Furniture On Sell Default: true - Controls = { - PlusX = 174, -- lEFT Arrow - MinusX = 175, -- RIGHT Arrow - RotateRight = 19, -- Alt, - RotateLeft = 21, -- Shift, - Up = 96, -- UP Arrow - Down = 97, -- DOWN Arrow - Confirm = 201, -- ENTER - Exit = 194, -- BACKSPACE - PlusY = 172, -- SHIFT - MinusY = 173, -- SHIFT - } + Enabled = true, + RotationSpeed = 0.4, -- Object Rotation Speed + MovementSpeed = 0.01, -- Object Movement Speed + MovementZspeed = 0.05, -- Object Z Movement Speed + WipeFurnitureOnSell = true, -- Wipe Furniture On Sell Default: true + Controls = { + PlusX = 174, -- lEFT Arrow + MinusX = 175, -- RIGHT Arrow + RotateRight = 19, -- Alt, + RotateLeft = 21, -- Shift, + Up = 96, -- UP Arrow + Down = 97, -- DOWN Arrow + Confirm = 201, -- ENTER + Exit = 194, -- BACKSPACE + PlusY = 172, -- SHIFT + MinusY = 173, -- SHIFT + }, } --------------------- CCTV Settings --------------------------------- Config.CCTV = { - Enabled = true, - PictureWebook = IsDuplicityVersion() and "" or "DO NOT CHANGE THIS STRING", -- Set a discord webhook here to enable taking pictures of the CCTV (link is copied to user`s clipboard) - HeightAboveDoor = 2.5, -- Height above the door to place the cctv camera - FOV = 80.0, -- Camera Field of View - MaxLeftRotation = 80, - MaxZoom = 30, - MinZoom = 100, - MaxRightRotation = -50, - MaxUpRotation = 10, - MaxDownRotation = -45, - RotateSpeed = 0.3, -- Camera Rotation Speed - Controls = { - Left = 34, -- lEFT Arrow - Right = 35, -- RIGHT Arrow - Screenshot = 201, -- ENTER - NightVision = 38, -- E - ZoomIn = 96, -- UP Arrow - ZoomOut = 97, -- DOWN Arrow - Up = 32, -- UP Arrow - Down = 33, -- DOWN Arrow - Exit = 194, -- BACKSPACE - } + Enabled = true, + PictureWebook = IsDuplicityVersion() and "" or "DO NOT CHANGE THIS STRING", -- Set a discord webhook here to enable taking pictures of the CCTV (link is copied to user`s clipboard) + HeightAboveDoor = 2.5, -- Height above the door to place the cctv camera + FOV = 80.0, -- Camera Field of View + MaxLeftRotation = 80, + MaxZoom = 30, + MinZoom = 100, + MaxRightRotation = -50, + MaxUpRotation = 10, + MaxDownRotation = -45, + RotateSpeed = 0.3, -- Camera Rotation Speed + Controls = { + Left = 34, -- lEFT Arrow + Right = 35, -- RIGHT Arrow + Screenshot = 201, -- ENTER + NightVision = 38, -- E + ZoomIn = 96, -- UP Arrow + ZoomOut = 97, -- DOWN Arrow + Up = 32, -- UP Arrow + Down = 33, -- DOWN Arrow + Exit = 194, -- BACKSPACE + }, } - -------- Groups allowed to use Admin Functions ------------------- Config.AllowedGroups = { - -- Note: Superadmin is not a group In ESX - "admin" + -- Note: Superadmin is not a group In ESX + "admin", } ------------------Interacting With Wardrobe Markers ------------------------------ Config.WardrobeInteraction = function() - ESX.TriggerServerCallback('esx_property:getPlayerDressing', function(dressing) - local elements = {{unselectable = true, icon = "fas fa-tshirt", title = "Wardrobe"}} + ESX.TriggerServerCallback("esx_property:getPlayerDressing", function(dressing) + local elements = { { unselectable = true, icon = "fas fa-tshirt", title = "Wardrobe" } } - for i=1, #dressing, 1 do - elements[#elements + 1] = { - title = dressing[i], - value = i - } - end + for i = 1, #dressing, 1 do + elements[#elements + 1] = { + title = dressing[i], + value = i, + } + end - ESX.OpenContext("left", elements, function(_, element) - TriggerEvent('skinchanger:getSkin', function(skin) - ESX.TriggerServerCallback('esx_property:getPlayerOutfit', function(clothes) - TriggerEvent('skinchanger:loadClothes', skin, clothes) - TriggerEvent('esx_skin:setLastSkin', skin) + ESX.OpenContext("left", elements, function(_, element) + TriggerEvent("skinchanger:getSkin", function(skin) + ESX.TriggerServerCallback("esx_property:getPlayerOutfit", function(clothes) + TriggerEvent("skinchanger:loadClothes", skin, clothes) + TriggerEvent("esx_skin:setLastSkin", skin) - TriggerEvent('skinchanger:getSkin', function() - TriggerServerEvent('esx_skin:save', skin) - end) - end, element.value) - end) + TriggerEvent("skinchanger:getSkin", function() + TriggerServerEvent("esx_skin:save", skin) + end) + end, element.value) + end) + end) end) - end) end --------------------- Real Estate Settings ---------- Config.PlayerManagement = { - Enabled = false, -- Enable/Disable Player Management Default: true - job = "realestateagent", -- Job Required to Manage Players Default: "realestateagent" - joblabel = "Estate Agent", -- Job Label Default: "Estate Agent" - society = "society_realestateagent", -- Society Required to Manage Players Default: "society_realestateagent" - SalePercentage = 0.25, -- Sale Percentage Default: 0.25 -- Note: This is a percentage of the price of the house - jobRanks = { - { - grade = 0, - name = "trainee", - label = "Trainee", - salary = 15, + Enabled = false, -- Enable/Disable Player Management Default: true + job = "realestateagent", -- Job Required to Manage Players Default: "realestateagent" + joblabel = "Estate Agent", -- Job Label Default: "Estate Agent" + society = "society_realestateagent", -- Society Required to Manage Players Default: "society_realestateagent" + SalePercentage = 0.25, -- Sale Percentage Default: 0.25 -- Note: This is a percentage of the price of the house + jobRanks = { + { + grade = 0, + name = "trainee", + label = "Trainee", + salary = 15, + }, + { + grade = 1, + name = "agent", + label = "Experienced Agent", + salary = 30, + }, + { + grade = 2, + name = "boss", + label = "Chief Agent", + salary = 45, + }, }, - { - grade = 1, - name = "agent", - label = "Experienced Agent", - salary = 30, + Permissions = { -- Minimum Grade Required for Action + CreateProperty = 0, -- Create Property + DeleteProperty = 2, -- Delete Property + ViewProperties = 0, -- View All Properties + SellProperty = 0, -- Sell Property to players + ToggleCCTV = 1, -- Change CCTV settings + ToggleLock = 0, -- Change Lock Settings + ToggleGarage = 1, -- Change Garage Settings + SetPropertyName = 1, -- Change Property Name + RemovePropertyName = 1, -- Remove Property Name + SetPropertyPrice = 0, -- Change Property Price + ChangeInterior = 1, -- Change Interior + ResetFurniture = 0, -- Reset Furniture + EvictOwner = 0, -- Evict Owners + ChangeEntrance = 0, -- Change Entrance + EditInteriorPositions = 1, -- Edit Interior Positions + ManagePropertiesFromQuickActions = 1, -- Manage Properties From Quick Actions (F6) }, - { - grade = 2, - name = "boss", - label = "Chief Agent", - salary = 45, + Locations = { + Entrance = vector3(-199.151, -575.000, 39.489), -- Entrance Location Default: vector3( -199.151, -575.000, 39.489 ) + Exit = vector3(-141.226, -614.166, 167.820), -- Exit Location (Interior Location) Default: vector3( -141.226, -614.166, 167.820 ) + Properties = vector3(-138.9228, -634.1255, 167.8504), -- Property Management Menu Default: vector3(-138.9228, -634.1255, 167.8504) }, - }, - Permissions = { -- Minimum Grade Required for Action - CreateProperty = 0, -- Create Property - DeleteProperty = 2, -- Delete Property - ViewProperties = 0, -- View All Properties - SellProperty = 0, -- Sell Property to players - ToggleCCTV = 1, -- Change CCTV settings - ToggleLock = 0, -- Change Lock Settings - ToggleGarage = 1, -- Change Garage Settings - SetPropertyName =1, -- Change Property Name - RemovePropertyName = 1, -- Remove Property Name - SetPropertyPrice = 0, -- Change Property Price - ChangeInterior = 1, -- Change Interior - ResetFurniture = 0, -- Reset Furniture - EvictOwner = 0, -- Evict Owners - ChangeEntrance = 0, -- Change Entrance - EditInteriorPositions = 1, -- Edit Interior Positions - ManagePropertiesFromQuickActions = 1, -- Manage Properties From Quick Actions (F6) - }, - Locations = { - Entrance = vector3( -199.151, -575.000, 39.489 ), -- Entrance Location Default: vector3( -199.151, -575.000, 39.489 ) - Exit = vector3( -141.226, -614.166, 167.820 ), -- Exit Location (Interior Location) Default: vector3( -141.226, -614.166, 167.820 ) - Properties = vector3(-138.9228, -634.1255, 167.8504), -- Property Management Menu Default: vector3(-138.9228, -634.1255, 167.8504) - } } ----------------------Long Lists---------------------------------------- Config.FurnitureStores = { - { - title = "Ikea", - Catagories = {"Decorations", "Tables", "Sofas", "Bedroom"} - }, - { - title = "Electronics Store", - Catagories = {"Electronics","Kitchen"} - }, -} - -Config.Interiors = { - IPL = { - { - label = "Modern Apartment", - value = "apa_v_mp_h_01_a", - positions = { - Wardrobe = vec3(-797.72, 328.03, 220.42), - Storage = vec3(-795.67, 326.67, 217.037), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-786.8663, 315.7642, 217.6385) - }, - { - label = "Mody Apartment", - value = "apa_v_mp_h_02_a", - positions = { - Wardrobe = vec3(-797.591187, 327.995605, 220.424194), - Storage = vec3(-795.441772, 326.307678, 217.037354), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-787.0749, 315.8198, 217.6386) - }, - { - label = "Vibrant Apartment", - value = "apa_v_mp_h_03_a", - positions = { - Wardrobe = vec3(-798.131897, 328.417572, 220.424194), - Storage = vec3(-796.786804, 327.164825, 217.037354),-- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-786.6245, 315.6175, 217.6385) - }, - { - label = "Regal Apartment", - value = " apa_v_mp_h_07_c", - positions = { - Wardrobe = vector3(-797.6594, 328.4619, 190.5122), - Storage = vector3(-796.0188, 326.7346, 187.3131), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-787.0574, 315.6567, 187.9135) - }, - { - label = "Tinsel Towers", - value = "tinsel_towers", - positions = { - Wardrobe = vector3(-594.5938, 55.6803, 96.9996), - Storage = vector3(-622.8556, 54.7504, 97.5995), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-603.7109, 59.0251, 98.2002) - }, - { - label = "Dell Perro Heights", - value = "dell_perro_heights", - positions = { - Wardrobe = vector3(-1467.2574, -536.9599, 50.7325), - Storage = vector3(-1457.0121, -531.0082, 56.9373), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-1449.7212, -526.1263, 56.9290) - }, - { - label = "Mid-Tier Apartment", - value = "mid-end", - positions = { - Wardrobe = vector3(350.7425, -994.2987, -99.1472), - Storage = vector3(343.8686, -1001.1404, -99.1962), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(346.5085, -1012.7023, -99.1962) - }, { - label = "Low-End Apartment", - value = "low-end", - positions = { - Wardrobe = vector3(259.9943, -1003.4595, -99.0086), - Storage = vector3(265.9162, -999.3954, -99.0086), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(266.0285, -1007.4129, -101.0086) + title = "Ikea", + Catagories = { "Decorations", "Tables", "Sofas", "Bedroom" }, }, { - label = "High-End House 1", - value = "wild_oats", - positions = { - Wardrobe = vector3(-167.4227, 487.7173, 133.0), - Storage = vector3(-174.4463, 492.5583, 130.0436), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(-174.3548, 497.7895, 137.6538) + title = "Electronics Store", + Catagories = { "Electronics", "Kitchen" }, }, - { - label = "Clubhouse", - value = "bkr_biker_interior_placement_interior_0_biker_dlc_int_01_milo", - positions = { - Wardrobe = vector3(1116.9374, -3162.8467, -36.8705), - Storage = vector3(1112.0820, -3151.4019, -37.5186), -- Only Works with Ox Inventory - }, - type = "ipl", - pos = vector3(1121.1871, -3152.6177, -37.0628) - }, - }, - Shells = { - { - label = "Michael House", - value = "shell_michael", - positions = { - Wardrobe = vector3(-12.71,8.36,-5.8), -- Wardrobe Location - Storage = vector3(-177.77,-2.05,-1.44), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(9.290245, -5.563965, 5.053642) - }, - { - label = "Standard Motel", - value = "standardmotel_shell", - positions = { - Wardrobe = vector3(-1.435, -4.74, -1.0), - Storage = vector3(2.45, -4.37, -1.0), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(0.054924, 2.459473, 1.546776) - }, - { - label = "Mid-Tier apartment", - value = "furnitured_midapart", - positions = { - Wardrobe = vector3(-4.5, -18.99, -1.2), - Storage = vector3(-5.1, -13.68, -1.2), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(-1.434044, 9.802368, 1.511887) - }, - { - label = "Trever`s Trailer", - value = "shell_trevor", - positions = { - Wardrobe = vector3(-0.58, -4.85, -1.0), - Storage = vector3(3.02, -1.467, -1.0), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(-0.156189, 3.585266, 1.398056) - }, - { - label = "Trailer", - value = "shell_trailer", - positions = { - Wardrobe = vector3(3.8, -2.92, -1.0), - Storage = vector3(-5.69, -0.57, -1.12), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(1.282555, 1.713379, 1.469521) - }, - { - label = "Low-End Apartment", - value = "shell_v16low", - positions = { - Wardrobe = vector3(7.31, -6.71, -3.0), - Storage = vector3(0.61, -8.30, -3.0), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(-4.798767, 6.197479, 2.644226) - }, - { - label = "Store", - value = "shell_store1", - positions = { - Storage = vector3(0.03, -8.4, -1.1), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(2.666809, 4.603638, 1.609573) +} + +Config.Interiors = { + IPL = { + { + label = "Modern Apartment", + value = "apa_v_mp_h_01_a", + positions = { + Wardrobe = vec3(-797.72, 328.03, 220.42), + Storage = vec3(-795.67, 326.67, 217.037), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-786.8663, 315.7642, 217.6385), + }, + { + label = "Mody Apartment", + value = "apa_v_mp_h_02_a", + positions = { + Wardrobe = vec3(-797.591187, 327.995605, 220.424194), + Storage = vec3(-795.441772, 326.307678, 217.037354), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-787.0749, 315.8198, 217.6386), + }, + { + label = "Vibrant Apartment", + value = "apa_v_mp_h_03_a", + positions = { + Wardrobe = vec3(-798.131897, 328.417572, 220.424194), + Storage = vec3(-796.786804, 327.164825, 217.037354), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-786.6245, 315.6175, 217.6385), + }, + { + label = "Regal Apartment", + value = " apa_v_mp_h_07_c", + positions = { + Wardrobe = vector3(-797.6594, 328.4619, 190.5122), + Storage = vector3(-796.0188, 326.7346, 187.3131), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-787.0574, 315.6567, 187.9135), + }, + { + label = "Tinsel Towers", + value = "tinsel_towers", + positions = { + Wardrobe = vector3(-594.5938, 55.6803, 96.9996), + Storage = vector3(-622.8556, 54.7504, 97.5995), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-603.7109, 59.0251, 98.2002), + }, + { + label = "Dell Perro Heights", + value = "dell_perro_heights", + positions = { + Wardrobe = vector3(-1467.2574, -536.9599, 50.7325), + Storage = vector3(-1457.0121, -531.0082, 56.9373), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-1449.7212, -526.1263, 56.9290), + }, + { + label = "Mid-Tier Apartment", + value = "mid-end", + positions = { + Wardrobe = vector3(350.7425, -994.2987, -99.1472), + Storage = vector3(343.8686, -1001.1404, -99.1962), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(346.5085, -1012.7023, -99.1962), + }, + { + label = "Low-End Apartment", + value = "low-end", + positions = { + Wardrobe = vector3(259.9943, -1003.4595, -99.0086), + Storage = vector3(265.9162, -999.3954, -99.0086), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(266.0285, -1007.4129, -101.0086), + }, + { + label = "High-End House 1", + value = "wild_oats", + positions = { + Wardrobe = vector3(-167.4227, 487.7173, 133.0), + Storage = vector3(-174.4463, 492.5583, 130.0436), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(-174.3548, 497.7895, 137.6538), + }, + { + label = "Clubhouse", + value = "bkr_biker_interior_placement_interior_0_biker_dlc_int_01_milo", + positions = { + Wardrobe = vector3(1116.9374, -3162.8467, -36.8705), + Storage = vector3(1112.0820, -3151.4019, -37.5186), -- Only Works with Ox Inventory + }, + type = "ipl", + pos = vector3(1121.1871, -3152.6177, -37.0628), + }, }, - { - label = "Ranch", - value = "shell_ranch", - positions = { - Wardrobe = vector3(-2.78, -10.76, -1.0), - Storage = vector3(3.1, 8.04, -1.0), -- Only Works with Ox Inventory - }, - type = "shell", - pos = vector3(0.873413, -5.749237, 2.416748) + Shells = { + { + label = "Michael House", + value = "shell_michael", + positions = { + Wardrobe = vector3(-12.71, 8.36, -5.8), -- Wardrobe Location + Storage = vector3(-177.77, -2.05, -1.44), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(9.290245, -5.563965, 5.053642), + }, + { + label = "Standard Motel", + value = "standardmotel_shell", + positions = { + Wardrobe = vector3(-1.435, -4.74, -1.0), + Storage = vector3(2.45, -4.37, -1.0), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(0.054924, 2.459473, 1.546776), + }, + { + label = "Mid-Tier apartment", + value = "furnitured_midapart", + positions = { + Wardrobe = vector3(-4.5, -18.99, -1.2), + Storage = vector3(-5.1, -13.68, -1.2), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(-1.434044, 9.802368, 1.511887), + }, + { + label = "Trever`s Trailer", + value = "shell_trevor", + positions = { + Wardrobe = vector3(-0.58, -4.85, -1.0), + Storage = vector3(3.02, -1.467, -1.0), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(-0.156189, 3.585266, 1.398056), + }, + { + label = "Trailer", + value = "shell_trailer", + positions = { + Wardrobe = vector3(3.8, -2.92, -1.0), + Storage = vector3(-5.69, -0.57, -1.12), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(1.282555, 1.713379, 1.469521), + }, + { + label = "Low-End Apartment", + value = "shell_v16low", + positions = { + Wardrobe = vector3(7.31, -6.71, -3.0), + Storage = vector3(0.61, -8.30, -3.0), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(-4.798767, 6.197479, 2.644226), + }, + { + label = "Store", + value = "shell_store1", + positions = { + Storage = vector3(0.03, -8.4, -1.1), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(2.666809, 4.603638, 1.609573), + }, + { + label = "Ranch", + value = "shell_ranch", + positions = { + Wardrobe = vector3(-2.78, -10.76, -1.0), + Storage = vector3(3.1, 8.04, -1.0), -- Only Works with Ox Inventory + }, + type = "shell", + pos = vector3(0.873413, -5.749237, 2.416748), + }, }, - } } -Config.FurnitureCatagories ={ - Decorations = { - {name = "apa_mp_h_acc_bottle_01", title = "Bottle", price = 700}, - {name = "apa_mp_h_acc_candles_01", title = "Candles", price = 700}, - {name = "p_int_jewel_mirror", title = "Mirror", price = 700}, - {name = "apa_mp_h_acc_dec_plate_01", title = "Decorative Plate", price = 700}, - {name = "apa_mp_h_acc_vase_01", title = "Vase", price = 700}, - {name = "v_res_desktidy", title = "Desk Supplies", price = 700}, - {name = "ex_prop_ashtray_luxe_02", title = "Ashtray", price = 700}, - {name = "v_res_mp_ashtrayb", title = "Ashtray 2", price = 300}, - {name = "prop_bong_01", title = "Bong", price = 700}, - {name = "prop_mr_rasberryclean", title = "Mr Rasberry Clean", price = 700}, - {name = "prop_acc_guitar_01", title = "Guitar", price = 1000}, - {name = "p_planning_board_04", title = "Planning Board", price = 500}, - {name = "prop_hotel_clock_01", title = "Hotel Clock", price = 500}, - {name = "p_cs_pamphlet_01_s", title = "Pamphlet", price = 700}, - {name = "prop_big_clock_01", title = "Big Clock", price = 500}, - {name = "prop_egg_clock_01", title = "Egg Clock", price = 500}, - {name = "prop_ld_greenscreen_01", title = "Green Screen", price = 100}, - {name = "prop_dart_bd_cab_01", title = "Dart", price = 500}, - {name = "prop_dart_bd_01", title = "Dart 2", price = 500}, - {name = "prop_exercisebike", title = "Exercise Bike", price = 500}, - {name = "p_laz_j02_s", title = "Laz", price = 500}, - {name = "v_res_cherubvase", title = "White Vase", price = 500}, - {name = "v_res_d_paddedwall", title = "Padded Wall", price = 500}, - {name = "prop_dummy_01", title = "Dummy", price = 100}, - {name = "prop_el_guitar_01", title = "E Guitar 1", price = 100}, - {name = "prop_el_guitar_02", title = "E Guitar 2", price = 100}, - {name = "prop_el_guitar_03", title = "E Guitar 2", price = 100}, - {name = "v_res_mbowlornate", title = "Ornate Bowl", price = 300}, - {name = "v_res_mbronzvase", title = "Bronze Vase", price = 300}, - {name = "prop_ceramic_jug_01", title = "Ceramic Jug", price = 100}, - {name = "v_res_m_candle", title = "Candle Large 1", price = 300}, - {name = "v_res_m_candlelrg", title = "Candle Large 2", price = 300}, - {name = "apa_mp_h_acc_candles_06", title = "Candles 1", price = 50}, - {name = "apa_mp_h_acc_candles_05", title = "Candles 2", price = 50}, - {name = "apa_mp_h_acc_candles_04", title = "Candles 3", price = 50}, - {name = "apa_mp_h_acc_rugwools_01", title = "Rug 1", price = 300}, - {name = "apa_mp_h_acc_rugwoolm_01", title = "Rug 2", price = 300}, - {name = "apa_mp_h_acc_rugwooll_04", title = "Rug 3", price = 300}, - {name = "apa_mp_h_acc_rugwooll_03", title = "Rug 4", price = 300}, - {name = "apa_mp_h_acc_rugwoolm_04", title = "Rug 5", price = 300}, - {name = "apa_mp_h_acc_rugwools_03", title = "Rug 6", price = 300}, - {name = "v_res_fh_pouf", title = "Pouf", price = 300}, - {name = "v_res_fh_sculptmod", title = "Sculpture", price = 300}, - {name = "prop_v_5_bclock", title = "Vintage Clock", price = 300}, - {name = "prop_v_15_cars_clock", title = "American Flag Clock", price = 300}, - {name = "prop_sm_19_clock", title = "Modern Clock", price = 300}, - {name = "prop_sports_clock_01", title = "Sports Clock", price = 300}, - {name = "prop_mem_candle_01", title = "Candle 1", price = 300}, - {name = "prop_game_clock_01", title = "Crown Clock", price = 300}, - {name = "prop_game_clock_02", title = "Kronos Clock", price = 300}, - {name = "prop_id2_20_clock", title = "Modern Clock 2", price = 300}, - {name = "ex_office_citymodel_01", title = "CIty name", price = 300}, - {name = "apa_mp_h_acc_dec_head_01", title = "Mask", price = 300}, - {name = "ex_mp_h_acc_vase_06", title = "Vase 1", price = 300}, - {name = "ex_mp_h_acc_vase_02", title = "Red Vase", price = 300}, - {name = "hei_prop_hei_bust_01", title = "Bust", price = 300}, - {name = "prop_arcade_01", title = "Arcade Machine", price = 300}, - {price = 6500, name = 'prop_beer_neon_01', title = 'Neon Sign 1'}, - {price = 6500, name = 'prop_beer_neon_02', title = 'Neon Sign 2'}, - {price = 6500, name = 'prop_beer_neon_03', title = 'Neon Sign 3'}, - {price = 6500, name = 'prop_beer_neon_04', title = 'Neon Sign 3'}, - {price = 6500, name = 'prop_patriotneon', title = 'Neon Sign Patriot'}, - {price = 6500, name = 'prop_barrachneon', title = 'Neon Sign Pussy Beer'} - }, +Config.FurnitureCatagories = { + Decorations = { + { name = "apa_mp_h_acc_bottle_01", title = "Bottle", price = 700 }, + { name = "apa_mp_h_acc_candles_01", title = "Candles", price = 700 }, + { name = "p_int_jewel_mirror", title = "Mirror", price = 700 }, + { name = "apa_mp_h_acc_dec_plate_01", title = "Decorative Plate", price = 700 }, + { name = "apa_mp_h_acc_vase_01", title = "Vase", price = 700 }, + { name = "v_res_desktidy", title = "Desk Supplies", price = 700 }, + { name = "ex_prop_ashtray_luxe_02", title = "Ashtray", price = 700 }, + { name = "v_res_mp_ashtrayb", title = "Ashtray 2", price = 300 }, + { name = "prop_bong_01", title = "Bong", price = 700 }, + { name = "prop_mr_rasberryclean", title = "Mr Rasberry Clean", price = 700 }, + { name = "prop_acc_guitar_01", title = "Guitar", price = 1000 }, + { name = "p_planning_board_04", title = "Planning Board", price = 500 }, + { name = "prop_hotel_clock_01", title = "Hotel Clock", price = 500 }, + { name = "p_cs_pamphlet_01_s", title = "Pamphlet", price = 700 }, + { name = "prop_big_clock_01", title = "Big Clock", price = 500 }, + { name = "prop_egg_clock_01", title = "Egg Clock", price = 500 }, + { name = "prop_ld_greenscreen_01", title = "Green Screen", price = 100 }, + { name = "prop_dart_bd_cab_01", title = "Dart", price = 500 }, + { name = "prop_dart_bd_01", title = "Dart 2", price = 500 }, + { name = "prop_exercisebike", title = "Exercise Bike", price = 500 }, + { name = "p_laz_j02_s", title = "Laz", price = 500 }, + { name = "v_res_cherubvase", title = "White Vase", price = 500 }, + { name = "v_res_d_paddedwall", title = "Padded Wall", price = 500 }, + { name = "prop_dummy_01", title = "Dummy", price = 100 }, + { name = "prop_el_guitar_01", title = "E Guitar 1", price = 100 }, + { name = "prop_el_guitar_02", title = "E Guitar 2", price = 100 }, + { name = "prop_el_guitar_03", title = "E Guitar 2", price = 100 }, + { name = "v_res_mbowlornate", title = "Ornate Bowl", price = 300 }, + { name = "v_res_mbronzvase", title = "Bronze Vase", price = 300 }, + { name = "prop_ceramic_jug_01", title = "Ceramic Jug", price = 100 }, + { name = "v_res_m_candle", title = "Candle Large 1", price = 300 }, + { name = "v_res_m_candlelrg", title = "Candle Large 2", price = 300 }, + { name = "apa_mp_h_acc_candles_06", title = "Candles 1", price = 50 }, + { name = "apa_mp_h_acc_candles_05", title = "Candles 2", price = 50 }, + { name = "apa_mp_h_acc_candles_04", title = "Candles 3", price = 50 }, + { name = "apa_mp_h_acc_rugwools_01", title = "Rug 1", price = 300 }, + { name = "apa_mp_h_acc_rugwoolm_01", title = "Rug 2", price = 300 }, + { name = "apa_mp_h_acc_rugwooll_04", title = "Rug 3", price = 300 }, + { name = "apa_mp_h_acc_rugwooll_03", title = "Rug 4", price = 300 }, + { name = "apa_mp_h_acc_rugwoolm_04", title = "Rug 5", price = 300 }, + { name = "apa_mp_h_acc_rugwools_03", title = "Rug 6", price = 300 }, + { name = "v_res_fh_pouf", title = "Pouf", price = 300 }, + { name = "v_res_fh_sculptmod", title = "Sculpture", price = 300 }, + { name = "prop_v_5_bclock", title = "Vintage Clock", price = 300 }, + { name = "prop_v_15_cars_clock", title = "American Flag Clock", price = 300 }, + { name = "prop_sm_19_clock", title = "Modern Clock", price = 300 }, + { name = "prop_sports_clock_01", title = "Sports Clock", price = 300 }, + { name = "prop_mem_candle_01", title = "Candle 1", price = 300 }, + { name = "prop_game_clock_01", title = "Crown Clock", price = 300 }, + { name = "prop_game_clock_02", title = "Kronos Clock", price = 300 }, + { name = "prop_id2_20_clock", title = "Modern Clock 2", price = 300 }, + { name = "ex_office_citymodel_01", title = "CIty name", price = 300 }, + { name = "apa_mp_h_acc_dec_head_01", title = "Mask", price = 300 }, + { name = "ex_mp_h_acc_vase_06", title = "Vase 1", price = 300 }, + { name = "ex_mp_h_acc_vase_02", title = "Red Vase", price = 300 }, + { name = "hei_prop_hei_bust_01", title = "Bust", price = 300 }, + { name = "prop_arcade_01", title = "Arcade Machine", price = 300 }, + { price = 6500, name = "prop_beer_neon_01", title = "Neon Sign 1" }, + { price = 6500, name = "prop_beer_neon_02", title = "Neon Sign 2" }, + { price = 6500, name = "prop_beer_neon_03", title = "Neon Sign 3" }, + { price = 6500, name = "prop_beer_neon_04", title = "Neon Sign 3" }, + { price = 6500, name = "prop_patriotneon", title = "Neon Sign Patriot" }, + { price = 6500, name = "prop_barrachneon", title = "Neon Sign Pussy Beer" }, + }, - Electronics = { - {price = 0, title = 'Lamp', name = 'prop_cd_lamp'}, - {price = 1800, title = 'Shredder', name = 'v_ret_gc_shred'}, - {price = 800, title = 'Antique telephone', name = 'apa_mp_h_acc_phone_01'}, - {price = 14700, title = 'TV wall white-gray with electronics', name = 'apa_mp_h_str_avunitl_04'}, - {price = 6700, title = 'TV wooden wall with television', name = 'apa_mp_h_str_avunitl_01_b'}, - {price = 14300, title = 'Television with yellow speakers', name = 'apa_mp_h_str_avunitm_01'}, - {price = 12000, title = 'TV with white speakers', name = 'apa_mp_h_str_avunitm_03'}, - {price = 12900, title = 'Television with accessories', name = 'apa_mp_h_str_avunits_01'}, - {price = 6900, title = 'TV on a metal table', name = 'apa_mp_h_str_avunits_01'}, - {price = 5500, title = 'Notebook', name = 'bkr_prop_clubhouse_laptop_01a'}, - {price = 4400, title = 'Notebook', name = 'bkr_prop_clubhouse_laptop_01b'}, - {price = 12400, title = 'Money counter', name = 'bkr_prop_money_counter'}, - {price = 700, title = 'Large upright fan', name = 'bkr_prop_weed_fan_floor_01a'}, - {price = 2400, title = 'Tvsmash', name = 'des_tvsmash_start'}, - {price = 2700, title = 'Wall TV', name = 'ex_prop_ex_tv_flat_01'}, - {price = 3500, title = 'Desktop monitor with keyboard', name = 'ex_prop_monitor_01_ex'}, - {price = 4700, title = 'Desktop monitor with keyboard', name = 'ex_prop_trailer_monitor_01'}, - {price = 200, title = 'TV driver', name = 'ex_prop_tv_settop_remote'}, - {price = 2200, title = 'TV box', name = 'ex_prop_tv_settop_box'}, - {price = 1000, title = 'Table fan', name = 'gr_prop_bunker_deskfan_01a'}, - {price = 8400, title = 'Television with speakers and all equipment', name = 'hei_heist_str_avunitl_03'}, - {price = 1700, title = 'telephone landline', name = 'hei_prop_hei_bank_phone_01'}, - {price = 3800, title = 'Alarm', name = 'hei_prop_hei_bio_panel'}, - {price = 2100, title = 'Keyboard', name = 'hei_prop_hei_cs_keyboard'}, - {price = 8900, title = 'Project board', name = 'hei_prop_hei_muster_01'}, - {price = 1800, title = 'WIFI', name = 'hei_prop_server_piece_01'}, - {price = 3300, title = 'White notebook', name = 'p_laptop_02_s'}, - {price = 10500, title = 'Safe', name = 'p_v_43_safe_s'}, - {price = 7900, title = 'Table Hockey', name = 'prop_airhockey_01'}, - {price = 2400, title = 'Portable Radio', name = 'prop_boombox_01'}, - {price = 2500, title = 'DVD player', name = 'prop_cctv_cont_03'}, - {price = 3300, title = 'CD player', name = 'prop_cctv_cont_04'}, - {price = 900, title = 'PC Mouse', name = 'prop_cs_mouse_01'}, - {price = 900, title = 'Wall clock', name = 'prop_game_clock_01'}, - {price = 600, title = 'Wall clock black', name = 'prop_game_clock_02'}, - {price = 3400, title = 'HiFi system', name = 'prop_hifi_01'}, - {price = 1500, title = 'square clock', name = 'prop_hotel_clock_01'}, - {price = 1500, title = 'Clock', name = 'prop_id2_20_clock'}, - {price = 3400, title = 'Nikon Handheld Camera', name = 'prop_ing_camera_01'}, - {price = 1700, title = 'White keyboard', name = 'prop_keyboard_01a'}, - {price = 1600, title = 'Router', name = 'prop_ld_armour'}, - {price = 1700, title = 'Old monitor', name = 'prop_ld_monitor_01'}, - {price = 2300, title = 'Small old monitor', name = 'prop_monitor_01b'}, - {price = 400, title = 'RETRO monitor', name = 'prop_monitor_03b'}, - {price = 5900, title = 'Monitor', name = 'prop_monitor_w_large'}, - {price = 4800, title = 'Repráček', name = 'prop_mp3_dock'}, - {price = 4000, title = 'White PC', name = 'prop_pc_01a'}, - {price = 4800, title = 'Black PC', name = 'prop_pc_02a'}, - {price = 2500, title = 'Mobile', name = 'prop_phone_ing'}, - {price = 2100, title = 'Mobile', name = 'prop_phone_ing_02'}, - {price = 2000, title = 'Mobile', name = 'prop_phone_ing_02_lod'}, - {price = 2300, title = 'Mobile', name = 'prop_phone_ing_03'}, - {price = 1000, title = 'RETRO radio', name = 'prop_radio_01'}, - {price = 1100, title = 'Small speaker', name = 'prop_speaker_05'}, - {price = 1000, title = 'Speaker', name = 'prop_speaker_06'}, - {price = 1900, title = 'Speaker', name = 'prop_speaker_08'}, - {price = 2000, title = 'Old TV', name = 'prop_trev_tv_01'}, - {price = 500, title = 'Old TV', name = 'prop_tv_03'}, - {price = 300, title = 'Old TV', name = 'prop_tv_01'}, - {price = 400, title = 'RETRO TV', name = 'prop_tv_04'}, - {price = 1700, title = 'Old TV', name = 'prop_tv_06'}, - {price = 6500, title = 'Plasma big screen', name = 'prop_tv_flat_01'}, - {price = 12500, title = 'Plasma thin TV', name = 'prop_tv_flat_01_screen'}, - {price = 1600, title = 'Plasma small television', name = 'prop_tv_flat_02'}, - {price = 2100, title = 'Plasma small television', name = 'prop_tv_flat_02b'}, - {price = 900, title = 'Small TV with stand', name = 'prop_tv_flat_03'}, - {price = 300, title = 'Small TV on the wall', name = 'prop_tv_flat_03b'}, - {price = 9200, title = 'Television Michael 50cm', name = 'prop_tv_flat_michael'}, - {price = 1000, title = 'Little US Clock', name = 'prop_v_15_cars_clock'}, - {price = 4000, title = 'Professional camera', name = 'prop_v_cam_01'}, - {price = 4700, title = 'VET player RETRO', name = 'prop_vcr_01'}, - {price = 9900, title = 'Mixing desk', name = 'v_club_vu_deckcase'}, - {price = 1500, title = 'RETRO Laptop', name = 'v_ind_ss_laptop'}, - {price = 2500, title = 'CD seda', name = 'v_res_cdstorage'}, - {price = 3300, title = 'Ipod', name = 'v_res_ipoddock'}, - {price = 2800, title = 'Silver Monitor', name = 'v_res_monitorwidelarge'}, - {price = 2400, title = 'Mouse and as a gift pad', name = 'v_res_mousemat'}, - {price = 100, title = 'PC Headphones', name = 'v_res_pcheadset'}, - {price = 1200, title = 'PC speaker', name = 'v_res_pcspeaker'}, - {price = 5000, title = 'VHS white RETRO player', name = 'v_res_vhsplayer'}, - {price = 2200, title = 'Vacuum Cleaner', name = 'v_res_vacuum'}, - {price = 5400, title = 'Shredder', name = 'v_ret_gc_shred'}, - {price = 100, title = 'Stapler', name = 'v_ret_gc_staple'}, - {price = 1900, title = 'Hardisk', name = 'xm_prop_x17_harddisk_01a'}, - {price = 5300, title = 'Computer', name = 'xm_prop_x17_res_pctower'}, - {price = 12900, title = 'Plasma TV', name = 'xm_prop_x17_tv_flat_01'}, - {price = 6600, title = 'Plasma TV', name = 'xm_prop_x17_tv_flat_02'}, - {price = 14000, title = 'Jukebox', name = 'bkr_prop_clubhouse_jukebox_01b'}, - {price = 1700, title = 'USB', name = 'hei_prop_hst_usb_drive'}, - {price = 700, title = 'Flashlight', name = 'p_cs_police_torch_s'}, - {price = 1000, title = 'Microphone', name = 'p_ing_microphonel_01'}, - {price = 1600, title = 'Radio', name = 'prop_tapeplayer_01'}, - {price = 4500, title = 'Multifunction Laser Printer', name = 'prop_printer_01'}, - {price = 11200, title = 'Multifunction Laser Printer', name = 'prop_printer_02'}, - {price = 20300, title = 'Jukebox 2', name = 'prop_50s_jukebox'}, - {price = 21200, title = 'Arcade games', name = 'prop_arcade_01'}, - {price = 19400, title = 'Safe', name = 'prop_ld_int_safe_01'}, - {price = 3800, title = 'Astronomical Clock', name = 'prop_v_5_bclock'}, - {price = 22200, title = 'Table with three monitors', name = 'xm_prop_base_staff_desk_01'}, - {price = 17900, title = 'Table with three monitors', name = 'xm_prop_base_staff_desk_02'}, - {price = 1500, title = 'Napkin machine', name = 'prop_handdry_01'}, - {price = 2700, title = 'Washing Machine', name = 'prop_washer_02'}, - {price = 600, title = 'Washing machine with its years', name = 'prop_washer_03'}, - {price = 700, title = 'RETRO washing machine', name = 'v_ret_fh_dryer'} - }, + Electronics = { + { price = 0, title = "Lamp", name = "prop_cd_lamp" }, + { price = 1800, title = "Shredder", name = "v_ret_gc_shred" }, + { price = 800, title = "Antique telephone", name = "apa_mp_h_acc_phone_01" }, + { price = 14700, title = "TV wall white-gray with electronics", name = "apa_mp_h_str_avunitl_04" }, + { price = 6700, title = "TV wooden wall with television", name = "apa_mp_h_str_avunitl_01_b" }, + { price = 14300, title = "Television with yellow speakers", name = "apa_mp_h_str_avunitm_01" }, + { price = 12000, title = "TV with white speakers", name = "apa_mp_h_str_avunitm_03" }, + { price = 12900, title = "Television with accessories", name = "apa_mp_h_str_avunits_01" }, + { price = 6900, title = "TV on a metal table", name = "apa_mp_h_str_avunits_01" }, + { price = 5500, title = "Notebook", name = "bkr_prop_clubhouse_laptop_01a" }, + { price = 4400, title = "Notebook", name = "bkr_prop_clubhouse_laptop_01b" }, + { price = 12400, title = "Money counter", name = "bkr_prop_money_counter" }, + { price = 700, title = "Large upright fan", name = "bkr_prop_weed_fan_floor_01a" }, + { price = 2400, title = "Tvsmash", name = "des_tvsmash_start" }, + { price = 2700, title = "Wall TV", name = "ex_prop_ex_tv_flat_01" }, + { price = 3500, title = "Desktop monitor with keyboard", name = "ex_prop_monitor_01_ex" }, + { price = 4700, title = "Desktop monitor with keyboard", name = "ex_prop_trailer_monitor_01" }, + { price = 200, title = "TV driver", name = "ex_prop_tv_settop_remote" }, + { price = 2200, title = "TV box", name = "ex_prop_tv_settop_box" }, + { price = 1000, title = "Table fan", name = "gr_prop_bunker_deskfan_01a" }, + { price = 8400, title = "Television with speakers and all equipment", name = "hei_heist_str_avunitl_03" }, + { price = 1700, title = "telephone landline", name = "hei_prop_hei_bank_phone_01" }, + { price = 3800, title = "Alarm", name = "hei_prop_hei_bio_panel" }, + { price = 2100, title = "Keyboard", name = "hei_prop_hei_cs_keyboard" }, + { price = 8900, title = "Project board", name = "hei_prop_hei_muster_01" }, + { price = 1800, title = "WIFI", name = "hei_prop_server_piece_01" }, + { price = 3300, title = "White notebook", name = "p_laptop_02_s" }, + { price = 10500, title = "Safe", name = "p_v_43_safe_s" }, + { price = 7900, title = "Table Hockey", name = "prop_airhockey_01" }, + { price = 2400, title = "Portable Radio", name = "prop_boombox_01" }, + { price = 2500, title = "DVD player", name = "prop_cctv_cont_03" }, + { price = 3300, title = "CD player", name = "prop_cctv_cont_04" }, + { price = 900, title = "PC Mouse", name = "prop_cs_mouse_01" }, + { price = 900, title = "Wall clock", name = "prop_game_clock_01" }, + { price = 600, title = "Wall clock black", name = "prop_game_clock_02" }, + { price = 3400, title = "HiFi system", name = "prop_hifi_01" }, + { price = 1500, title = "square clock", name = "prop_hotel_clock_01" }, + { price = 1500, title = "Clock", name = "prop_id2_20_clock" }, + { price = 3400, title = "Nikon Handheld Camera", name = "prop_ing_camera_01" }, + { price = 1700, title = "White keyboard", name = "prop_keyboard_01a" }, + { price = 1600, title = "Router", name = "prop_ld_armour" }, + { price = 1700, title = "Old monitor", name = "prop_ld_monitor_01" }, + { price = 2300, title = "Small old monitor", name = "prop_monitor_01b" }, + { price = 400, title = "RETRO monitor", name = "prop_monitor_03b" }, + { price = 5900, title = "Monitor", name = "prop_monitor_w_large" }, + { price = 4800, title = "Repráček", name = "prop_mp3_dock" }, + { price = 4000, title = "White PC", name = "prop_pc_01a" }, + { price = 4800, title = "Black PC", name = "prop_pc_02a" }, + { price = 2500, title = "Mobile", name = "prop_phone_ing" }, + { price = 2100, title = "Mobile", name = "prop_phone_ing_02" }, + { price = 2000, title = "Mobile", name = "prop_phone_ing_02_lod" }, + { price = 2300, title = "Mobile", name = "prop_phone_ing_03" }, + { price = 1000, title = "RETRO radio", name = "prop_radio_01" }, + { price = 1100, title = "Small speaker", name = "prop_speaker_05" }, + { price = 1000, title = "Speaker", name = "prop_speaker_06" }, + { price = 1900, title = "Speaker", name = "prop_speaker_08" }, + { price = 2000, title = "Old TV", name = "prop_trev_tv_01" }, + { price = 500, title = "Old TV", name = "prop_tv_03" }, + { price = 300, title = "Old TV", name = "prop_tv_01" }, + { price = 400, title = "RETRO TV", name = "prop_tv_04" }, + { price = 1700, title = "Old TV", name = "prop_tv_06" }, + { price = 6500, title = "Plasma big screen", name = "prop_tv_flat_01" }, + { price = 12500, title = "Plasma thin TV", name = "prop_tv_flat_01_screen" }, + { price = 1600, title = "Plasma small television", name = "prop_tv_flat_02" }, + { price = 2100, title = "Plasma small television", name = "prop_tv_flat_02b" }, + { price = 900, title = "Small TV with stand", name = "prop_tv_flat_03" }, + { price = 300, title = "Small TV on the wall", name = "prop_tv_flat_03b" }, + { price = 9200, title = "Television Michael 50cm", name = "prop_tv_flat_michael" }, + { price = 1000, title = "Little US Clock", name = "prop_v_15_cars_clock" }, + { price = 4000, title = "Professional camera", name = "prop_v_cam_01" }, + { price = 4700, title = "VET player RETRO", name = "prop_vcr_01" }, + { price = 9900, title = "Mixing desk", name = "v_club_vu_deckcase" }, + { price = 1500, title = "RETRO Laptop", name = "v_ind_ss_laptop" }, + { price = 2500, title = "CD seda", name = "v_res_cdstorage" }, + { price = 3300, title = "Ipod", name = "v_res_ipoddock" }, + { price = 2800, title = "Silver Monitor", name = "v_res_monitorwidelarge" }, + { price = 2400, title = "Mouse and as a gift pad", name = "v_res_mousemat" }, + { price = 100, title = "PC Headphones", name = "v_res_pcheadset" }, + { price = 1200, title = "PC speaker", name = "v_res_pcspeaker" }, + { price = 5000, title = "VHS white RETRO player", name = "v_res_vhsplayer" }, + { price = 2200, title = "Vacuum Cleaner", name = "v_res_vacuum" }, + { price = 5400, title = "Shredder", name = "v_ret_gc_shred" }, + { price = 100, title = "Stapler", name = "v_ret_gc_staple" }, + { price = 1900, title = "Hardisk", name = "xm_prop_x17_harddisk_01a" }, + { price = 5300, title = "Computer", name = "xm_prop_x17_res_pctower" }, + { price = 12900, title = "Plasma TV", name = "xm_prop_x17_tv_flat_01" }, + { price = 6600, title = "Plasma TV", name = "xm_prop_x17_tv_flat_02" }, + { price = 14000, title = "Jukebox", name = "bkr_prop_clubhouse_jukebox_01b" }, + { price = 1700, title = "USB", name = "hei_prop_hst_usb_drive" }, + { price = 700, title = "Flashlight", name = "p_cs_police_torch_s" }, + { price = 1000, title = "Microphone", name = "p_ing_microphonel_01" }, + { price = 1600, title = "Radio", name = "prop_tapeplayer_01" }, + { price = 4500, title = "Multifunction Laser Printer", name = "prop_printer_01" }, + { price = 11200, title = "Multifunction Laser Printer", name = "prop_printer_02" }, + { price = 20300, title = "Jukebox 2", name = "prop_50s_jukebox" }, + { price = 21200, title = "Arcade games", name = "prop_arcade_01" }, + { price = 19400, title = "Safe", name = "prop_ld_int_safe_01" }, + { price = 3800, title = "Astronomical Clock", name = "prop_v_5_bclock" }, + { price = 22200, title = "Table with three monitors", name = "xm_prop_base_staff_desk_01" }, + { price = 17900, title = "Table with three monitors", name = "xm_prop_base_staff_desk_02" }, + { price = 1500, title = "Napkin machine", name = "prop_handdry_01" }, + { price = 2700, title = "Washing Machine", name = "prop_washer_02" }, + { price = 600, title = "Washing machine with its years", name = "prop_washer_03" }, + { price = 700, title = "RETRO washing machine", name = "v_ret_fh_dryer" }, + }, - Tables = { - {price = 5600, title = 'Glass table', name = 'apa_mp_h_din_table_04'}, - {price = 5000, title = 'Glass table', name = 'apa_mp_h_din_table_11'}, - {price = 5300, title = 'Glass table', name = 'apa_mp_h_tab_sidelrg_07'}, - {price = 1200, title = 'Black Round Table', name = 'apa_mp_h_tab_sidelrg_04'}, - {price = 1600, title = 'Glass table', name = 'apa_mp_h_tab_sidelrg_01'}, - {price = 5700, title = 'Decorative glass table', name = 'apa_mp_h_tab_sidelrg_02'}, - {price = 2600, title = 'Black coffee table', name = 'apa_mp_h_yacht_coffee_table_01'}, - {price = 4200, title = 'Square table', name = 'apa_mp_h_yacht_side_table_01'}, - {price = 3400, title = 'Small table', name = 'gr_dlc_gr_yacht_props_table_01'}, - {price = 4700, title = 'Long table', name = 'gr_dlc_gr_yacht_props_table_02'}, - {price = 1000, title = 'Particleboard table', name = 'prop_rub_table_01'}, - {price = 700, title = 'Particleboard dining table', name = 'prop_rub_table_02'}, - {price = 700, title = 'TV table', name = 'prop_tv_cabinet_03'}, - {price = 300, title = 'TV table', name = 'prop_tv_cabinet_04'}, - {price = 800, title = 'TV table', name = 'prop_tv_cabinet_05'}, - {price = 5300, title = 'Black modern table', name = 'v_ilev_liconftable_sml'}, - {price = 4100, title = 'Bar', name = 'xm_prop_lab_desk_01'} - }, + Tables = { + { price = 5600, title = "Glass table", name = "apa_mp_h_din_table_04" }, + { price = 5000, title = "Glass table", name = "apa_mp_h_din_table_11" }, + { price = 5300, title = "Glass table", name = "apa_mp_h_tab_sidelrg_07" }, + { price = 1200, title = "Black Round Table", name = "apa_mp_h_tab_sidelrg_04" }, + { price = 1600, title = "Glass table", name = "apa_mp_h_tab_sidelrg_01" }, + { price = 5700, title = "Decorative glass table", name = "apa_mp_h_tab_sidelrg_02" }, + { price = 2600, title = "Black coffee table", name = "apa_mp_h_yacht_coffee_table_01" }, + { price = 4200, title = "Square table", name = "apa_mp_h_yacht_side_table_01" }, + { price = 3400, title = "Small table", name = "gr_dlc_gr_yacht_props_table_01" }, + { price = 4700, title = "Long table", name = "gr_dlc_gr_yacht_props_table_02" }, + { price = 1000, title = "Particleboard table", name = "prop_rub_table_01" }, + { price = 700, title = "Particleboard dining table", name = "prop_rub_table_02" }, + { price = 700, title = "TV table", name = "prop_tv_cabinet_03" }, + { price = 300, title = "TV table", name = "prop_tv_cabinet_04" }, + { price = 800, title = "TV table", name = "prop_tv_cabinet_05" }, + { price = 5300, title = "Black modern table", name = "v_ilev_liconftable_sml" }, + { price = 4100, title = "Bar", name = "xm_prop_lab_desk_01" }, + }, - Sofas = { - {price = 11500, title = 'Couch with pillows', name = 'prop_couch_01'}, - {price = 6500, title = 'Padded bench', name = 'prop_wait_bench_01'}, - {price = 4400, title = 'White leather sofa', name = 'xm_lab_sofa_01'} - }, + Sofas = { + { price = 11500, title = "Couch with pillows", name = "prop_couch_01" }, + { price = 6500, title = "Padded bench", name = "prop_wait_bench_01" }, + { price = 4400, title = "White leather sofa", name = "xm_lab_sofa_01" }, + }, - Kitchen = { - {price = 800, title = 'Kitchen scale', name = 'bkr_prop_coke_scale_01'}, - {price = 1000, title = 'Home coffee maker', name = 'prop_coffee_mac_02'}, - {price = 5200, title = 'Automatic juice mixer', name = 'prop_juice_dispenser'}, - {price = 200, title = 'White wall phone', name = 'prop_office_phone_tnt'}, - {price = 2300, title = 'Fruit Blender', name = 'p_kitch_juicer_s'}, - {price = 1500, title = 'Kettle', name = 'prop_kettle_01'}, - {price = 2600, title = 'Crushing machine', name = 'prop_slush_dispenser'}, - {price = 700, title = 'Coffee pot', name = 'xm_prop_x17_coffee_jug'}, - {price = 3700, title = 'Mini bar fridge', name = 'prop_bar_fridge_03'}, - {price = 800, title = 'Plastic red cup', name = 'apa_prop_cs_plastic_cup_01'}, - {price = 1000, title = 'Trash', name = 'prop_bin_10a'}, - {price = 400, title = 'Universal Cleaner', name = 'prop_blox_spray'}, - {price = 200, title = 'Green bucket', name = 'prop_buck_spade_05'}, - {price = 400, title = 'Blue bucket', name = 'prop_buck_spade_06'}, - {price = 200, title = 'Red bucket', name = 'prop_buck_spade_07'}, - {price = 700, title = 'Cups', name = 'prop_food_cups2'}, - {price = 400, title = 'White Cup', name = 'prop_mug_02'}, - {price = 800, title = 'Bowl with donut lid', name = 'v_res_cakedome'}, - {price = 1000, title = 'Loose tea container', name = 'v_res_fa_pottea'}, - {price = 300, title = 'Deep Plate', name = 'v_res_mbowl'}, - {price = 500, title = 'Paper napkins', name = 'v_ret_ta_paproll'}, - {price = 400, title = 'Glasses', name = 'p_w_grass_gls_s'}, - {price = 300, title = 'Glasses', name = 'prop_cocktail'}, - {price = 600, title = 'Knife', name = 'prop_cs_bowie_knife'} - }, + Kitchen = { + { price = 800, title = "Kitchen scale", name = "bkr_prop_coke_scale_01" }, + { price = 1000, title = "Home coffee maker", name = "prop_coffee_mac_02" }, + { price = 5200, title = "Automatic juice mixer", name = "prop_juice_dispenser" }, + { price = 200, title = "White wall phone", name = "prop_office_phone_tnt" }, + { price = 2300, title = "Fruit Blender", name = "p_kitch_juicer_s" }, + { price = 1500, title = "Kettle", name = "prop_kettle_01" }, + { price = 2600, title = "Crushing machine", name = "prop_slush_dispenser" }, + { price = 700, title = "Coffee pot", name = "xm_prop_x17_coffee_jug" }, + { price = 3700, title = "Mini bar fridge", name = "prop_bar_fridge_03" }, + { price = 800, title = "Plastic red cup", name = "apa_prop_cs_plastic_cup_01" }, + { price = 1000, title = "Trash", name = "prop_bin_10a" }, + { price = 400, title = "Universal Cleaner", name = "prop_blox_spray" }, + { price = 200, title = "Green bucket", name = "prop_buck_spade_05" }, + { price = 400, title = "Blue bucket", name = "prop_buck_spade_06" }, + { price = 200, title = "Red bucket", name = "prop_buck_spade_07" }, + { price = 700, title = "Cups", name = "prop_food_cups2" }, + { price = 400, title = "White Cup", name = "prop_mug_02" }, + { price = 800, title = "Bowl with donut lid", name = "v_res_cakedome" }, + { price = 1000, title = "Loose tea container", name = "v_res_fa_pottea" }, + { price = 300, title = "Deep Plate", name = "v_res_mbowl" }, + { price = 500, title = "Paper napkins", name = "v_ret_ta_paproll" }, + { price = 400, title = "Glasses", name = "p_w_grass_gls_s" }, + { price = 300, title = "Glasses", name = "prop_cocktail" }, + { price = 600, title = "Knife", name = "prop_cs_bowie_knife" }, + }, - Bedroom = { - {price = 3300, title = 'Single bed', name = 'v_res_msonbed'}, - {price = 100, title = 'Double bed', name = 'p_lestersbed_s'}, - {price = 600, title = 'Double bed', name = 'p_v_res_tt_bed_s'}, - {price = 400, title = 'Double modern bed', name = 'apa_mp_h_bed_double_08'}, - {price = 1100, title = 'Double modern bed', name = 'apa_mp_h_bed_wide_05'}, - {price = 2200, title = 'Double modern bed', name = 'apa_mp_h_yacht_bed_02'}, - {price = 700, title = 'Single sofa bed', name = 'ex_prop_exec_bed_01'}, - {price = 3100, title = 'Double modern bed', name = 'hei_heist_bed_double_08'}, - {price = 4400, title = 'Chest of drawers', name = 'apa_mp_h_bed_chestdrawer_02'}, - {price = 400, title = 'RETRO wardrobe', name = 'apa_mp_h_str_shelffloorm_02'}, - {price = 100, title = 'RETRO chest of drawers low', name = 'apa_mp_h_str_sideboardl_11'}, - {price = 2500, title = 'Gray-white low cabinet', name = 'apa_mp_h_str_sideboardl_13'}, - {price = 700, title = 'Wooden chest of drawers', name = 'apa_mp_h_str_sideboardl_14'}, - {price = 500, title = 'Wood brindle feather duster', name = 'apa_mp_h_str_sideboardm_02'}, - {price = 900, title = 'Iron open cabinet', name = 'p_cs_locker_01'}, - {price = 300, title = 'Iron used closed cabinet', name = 'p_cs_locker_01_s'} - } + Bedroom = { + { price = 3300, title = "Single bed", name = "v_res_msonbed" }, + { price = 100, title = "Double bed", name = "p_lestersbed_s" }, + { price = 600, title = "Double bed", name = "p_v_res_tt_bed_s" }, + { price = 400, title = "Double modern bed", name = "apa_mp_h_bed_double_08" }, + { price = 1100, title = "Double modern bed", name = "apa_mp_h_bed_wide_05" }, + { price = 2200, title = "Double modern bed", name = "apa_mp_h_yacht_bed_02" }, + { price = 700, title = "Single sofa bed", name = "ex_prop_exec_bed_01" }, + { price = 3100, title = "Double modern bed", name = "hei_heist_bed_double_08" }, + { price = 4400, title = "Chest of drawers", name = "apa_mp_h_bed_chestdrawer_02" }, + { price = 400, title = "RETRO wardrobe", name = "apa_mp_h_str_shelffloorm_02" }, + { price = 100, title = "RETRO chest of drawers low", name = "apa_mp_h_str_sideboardl_11" }, + { price = 2500, title = "Gray-white low cabinet", name = "apa_mp_h_str_sideboardl_13" }, + { price = 700, title = "Wooden chest of drawers", name = "apa_mp_h_str_sideboardl_14" }, + { price = 500, title = "Wood brindle feather duster", name = "apa_mp_h_str_sideboardm_02" }, + { price = 900, title = "Iron open cabinet", name = "p_cs_locker_01" }, + { price = 300, title = "Iron used closed cabinet", name = "p_cs_locker_01_s" }, + }, } -------------------DONT TOUCH ------------------------- Config.OxInventory = ESX.GetConfig().OxInventory function GetInteriorValues(Interior) - for _,type in pairs(Config.Interiors) do - for _, interior in pairs(type) do - if interior.value == Interior then - return interior - end + for _, type in pairs(Config.Interiors) do + for _, interior in pairs(type) do + if interior.value == Interior then + return interior + end + end end - end -end \ No newline at end of file +end diff --git a/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua index 8a269ef5f..01bb6ff7c 100644 --- a/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua @@ -5,7 +5,7 @@ lua54 'yes' author 'ESX-Framework' description 'Official ESX-Legacy Property System' -version '0.0.4' +version '1.0.0' shared_scripts {'@es_extended/imports.lua', '@es_extended/locale.lua', 'locales/*.lua'} file "client/html/copy.html" diff --git a/server-data/resources/[esx_addons]/esx_property/locales/en.lua b/server-data/resources/[esx_addons]/esx_property/locales/en.lua index 3b3d98bf8..b668e4651 100644 --- a/server-data/resources/[esx_addons]/esx_property/locales/en.lua +++ b/server-data/resources/[esx_addons]/esx_property/locales/en.lua @@ -1,218 +1,215 @@ -Locales['en'] = { - --- CCTV Strings ------ - - ["take_picture"] = "Take Picture", - ["rot_left_right"] = "Left/Right", - ["rot_up_down"] = "Up/Down", - ["Zoom"] = "Zoom In/Out", - ["Zoom_level"] = "Zoom Level: %s %", - ["night_vision"] = "Toggle Night Vision", - ["clipboard"] = "Link Copied To ~b~Cipboard", - ["picture_taken"] = "Picture Taken!", - ["please_wait"] = "Please Wait Before taking another ~b~Picture", - ["exit"] = "Exit", - - --- Furniture Strings ------ - - ["Height"] = "Height", - ["rotate"] = "Rotation", - ["place"] = "Place Furniture", - ["delete_furni"] = "Delete", - ["confirm_buy"] = "Do You Want To Buy %s ?", - ["price"] = "Price: $&s", - ["yes"] = "Yes", - ["no"] = "No", - ["action"] = "You %s ~b~%s~s~ !", - ["bought_furni"] = "You Have ~g~Bought~s~ A ~b~%s~s~ !", - ["edited_furni"] = "You Have Edited ~b~%s~s~ !", - ["cannot_buy"] = "You ~r~Cannot~s~ Buy This!", - ["cannot_edit"] = "You ~r~Cannot~s~ Edit This!", - ["store_title"] = "Store - %s", - ["back"] = "Return", - ["edit_title"] = "Editing - %s", - ["move_title"] = "Move", - ["deleted_confirm"] = "Deleting ~b~%s~s~!", - ["deleted_error"] = "Cannot Delete ~b~%s~s~!", - ["owned_furni"] = "Owned Furniture", - ["menu_stores"] = "Furniture Stores", - ["menu_stores_desc"] = "Buy Furniture", - ["menu_reset"] = "Reset", - ["menu_reset_desc"] = "Clears All Furniture", - ["menu_edit"] = "Edit", - ["menu_edit_desc"] = "Move and/or Delete furniture items", - ["furni_command"] = "furniture", - ["furni_Command_desc"] = "(ESX Property) Open Furniture Menu", - ["furni_command_permission"] = "You ~r~Cannot~s~ Access This Menu!", - ["furni_reset_success"] = "Furniture Reset!", - ["furni_cannot_afford"] = "You Cannot Afford Todo this!", - ["furni_reset_error"] = "You ~r~Cannot~s~ Reset This Property!", - ["furni_management"] = "Manage Furniture", - - --------- Key Strings --------------- - - ["you_granted"] = 'You Have Been Granted Keys To ~b~%s~s~.', - ["already_has"] = "This Player Already Has Keys!", - ["do_not_own"] = 'You do ~r~not~s~ own this property.', - ["key_revoked"] = 'Your Key Access To ~b~%s~s~. Has Been ~r~Revoked~s~', - ["no_keys"] = "This Player Does Not Have Keys!", - ["nearby"] = "Nearby Players", - ["gave_key"] = "Giving Keys to %s!", - ["key_cannot_give"] = "You Cannot Give This Player A ~r~Key", - ["remove_title"] = "Remove Keys From Player", - ["key_revoke_success"] = "Revoking Keys From ~b~%s~s~.", - ["key_revoke_error"] = "You Cannot ~b~Remove~s~ A ~r~Key~s~ From this Person", - ["key_management"] = "Key Management", - ["key_management_desc"] = "Control Property Access.", - ["give_keys"] = "Give Keys", - ["remove_keys"] = "Remove Keys", - - - --------- Real Estate Strings --------------- - ["office_blip"] = "%s Office", - ["actions"] = "Real Estate Actions", - ["property_create"] = "Create Property", - ["property_manage"] = "Manage Properties", - ["realestate_command"] = "realestatequickmenu", - ["realestate_command_desc"] = "(ESX Property) Open Real Estate Quick Actions", - ["enter_office"] = "~b~Entering~s~ Office.", - ["enter_office_error"] = "You ~r~Cannot~s~ Enter The Office!", - ["exit_office"] = "~b~Exiting~s~ Office.", - ["exit_office_error"] = "You ~r~Cannot~s~ Exit The Office!", - ["realestate_textui"] = "Press ~b~[E]~s~ to Access ~b~%s", - - ------------Command Strings----------------------- - ["refresh_name"] = "property:refresh", - ["refresh_desc"] = "Refresh to Server Start State", - ["save_name"] = "property:save", - ["save_desc"] = "Force Save Properties", - ["create_name"] = "property:create", - ["create_desc"] = "Create A New Property", - ["admin_name"] = "property:admin", - ["admin_desc"] = "Manage/view all properties", - - - ---------- Property Actions Menu ------------------------- - - ["knocking"] = "Someone Is ~b~Knocking~s~ On The Door.", - ["name_edit"] = "Edit Property Name", - ["name"] = "Name", - ["confirm"] = "Confirm", - ["name_edit_success"] = "You Have Set The Property Name To ~b~%s~s~.", - ["name_edit_error"] = "You Cannot Set The Property Name To ~r~%s~s~.", - ["door_locked"] = "Door: Locked", - ["door_unlocked"] = "Door: Unlocked", - ["name_manage"] = "Manage Name", - ["name_manage_desc"] = "Set The Name of the Property.", - ["sell_title"] = "Sell", - ["sell_desc"] = "Sell This Property For $%s", - ["raid_title"] = "Raid", - ["raid_desc"] = "Force Entry Into Property.", - ["cctv_title"] = "CCTV", - ["cctv_desc"] = "Check the CCTV Camera.", - ["inventory_title"] = "Inventory", - ["inventory_desc"] = "Change Position of Property Storage.", - ["wardrobe_title"] = "Wardrobe", - ["wardrobe_desc"] = "Change Position of Property Wardrobe.", - ["furniture_title"] = "Furniture", - ["furniture_desc"] = "Change Position of Property Furniture.", - ["enter_title"] = "Enter", - ["knock_title"] = "Knock On Door", - ["buy_title"] = "Buy", - ["buy_desc"] = "Buy This Property For $%s", - ["sellplayer_title"] = "Sell To Player", - ["sellplayer_desc"] = "Sell This Property For $%s", - ["view_title"] = "Preview Interior", - ["exit_title"] = "Exit", - ["property_editing_error"] = "You Are Currently Editing The Property.", - ["unlock_error"] = "You Cannot ~b~Unlock~s~ This Property", - ["lock_error"] = "You Cannot ~b~Lock~s~ This Property", - ["prep_raid"] = "~b~Preparing~s~ Raid!", - ["raiding"] = "Raiding...", - ["cancel_raiding"] = "~r~Cancelled~s~ Raid!", - ["cannot_raid"] = "You Cannot ~b~Raid~s~ This Property.", - ["storage_pos_textui"] = "Press ~b~[G]~s~ To Set Storage Position", - ["storage_pos_success"] = "~b~Storage~s~ Position Set.", - ["storage_pos_error"] = "~r~Cannot~s~ Set ~b~Storage~s~ Position.", - ["wardrobe_pos_textui"] = "Press ~b~[G]~s~ To Set Wardrobe Position", - ["wardrobe_pos_success"] = "~b~Wardrobe~s~ Position Set.", - ["wardrobe_pos_error"] = "~r~Cannot~s~ Set ~b~Wardrobe~s~ Position.", - ["please_finish"] = "Please Finish Setting ~b~%s~s~ Position", - ["cannot_afford"] = "You Cannot Purchase This Property!", - ["select_player"] = "Select Player", - ["cannot_sell"] = "Cannot Sell To This Player!", - ["knock_on_door"] = "Knocking On Door...", - ["nobody_home"] = "It Seems Nobody is home...", - - ---------- General Strings ---------------- - - ["enabled"] = "Enabled", - ["disabled"] = "Disabled", - ["exiting"] = "Exiting property...", - ["entering"] = "Entering property...", - ["shell_disabled"] ="This Interior Uses Shells, which are disabled!", - ["access_textui"] = "Press ~b~[E]~s~ to Access ~b~%s", - ["raid_notify_error"] = "You need ~b~ %sx %s~s~ to be able to raid!", - ["raid_notify_success"] = "Your Property is Currently Being ~b~Raided!", - - --------------- Garage Strings -------------- - - ["store_success"] = "Vehicle ~b~Stored!", - ["store_error"] = "You Cannot Store This Vehicle!", - ["property_garage"] = "Property Garage", - ["retriving_notify"] = "Retrieving ~b~%s~s~ ...", - ["cannot_access"] = "You Cannot Access This Garage!", - ["store_textui"] = "Press ~b~[E]~s~ to Store ~b~%s", - ["garage_not_enabled"] = 'Garage Not Enabled On This Property.', - ["cannot_access_property"] = 'You ~r~Cannot~s~ Access this property.', - - - ----------------- Creation Menu Strings ---------------- - - ["menu_title"] = "Property Creation", - ["element_title1"] = "Street Number", - ["element_description1"] = "Set the Property Street Number.", - ["element_title2"] = "Price", - ["element_description2"] = "Set the Price of the Property.", - ["element_title3"] = "Interior", - ["element_description3"] = "Select An Interior For The Property", - ["element_title4"] = "Garage", - ["element_description4"] = "(Optional) Manage Garage Settings", - ["element_title5"] = "CCTV", - ["element_description5"] = "(Optional) Manage CCTV Settings", - ["element_title6"] = "Entrance", - ["element_description6"] = "Set The Property`s Entrance Location.", - ["element_create_title"] = "Create Property", - ["element_create_desc_1"] = "Please Fill Out all Required Inputs!", - ["entrance_set_title"] = "Entrance Set.", - ["entrance_set_description"] = "Entrance: %s, %s, %s", - ["interior_set_title"] = "Interior Selected.", - ["interior_set_description"] = "Selected: %s", - ["ipl_title"] = "IPL Interiors", - ["types_title"] = "Interior Types", - ["ipl_description"] = "Native GTA Interiors, Made by R*", - ["shell_title"] = "Custom Interiors", - ["shell_description"] = "Custom Interiors, Made by You", - ["cctv_settings"] = "CCTV Settings", - ["garage_settings"] = "Garage Settings", - ["toggle_title"] = "Toggle Usage", - ["toggle_description"] = "Current Status: %s", - ["cctv_set_title"] = "Set CCTV Angle", - ["cctv_set_description"] = "Sets the Camera angle to your Cameras Direction", - ["back_description"] = "return to property creation.", - ["garage_set_title"] = "Set Garage Position", - ["garage_set_description"] = "Set the position of the Property Garage.", - ["garage_textui"] = "Press ~b~[E]~s~ to Set Position", - ["cctv_textui_1"] = "Press ~b~[E]~s~ to Set Angle", - ["cctv_textui_2"] = "Press ~b~[E]~s~ to Set Max Right Roation", - ["cctv_textui_3"] = "Press ~b~[E]~s~ to Set Max Left Roation", - ["create_success"] = "Property created!", - ["missing_data"] = "Please Fill Out all Required Inputs!", - - -- Saving Translations - ["server_restart"] = "Server Restarting", - ["server_shutdown"] = "Server Shutdown", - ["manual_save"] = "Manual Save (Requested By %s)", - ["resource_stop"] = "Resource Stopping", - ["force_save"] = "Force Save (Requested By %s)", - ["interval_saving"] = "Interval Saving" - } +Locales["en"] = { + --- CCTV Strings ------ + + ["take_picture"] = "Take Picture", + ["rot_left_right"] = "Left/Right", + ["rot_up_down"] = "Up/Down", + ["Zoom"] = "Zoom In/Out", + ["Zoom_level"] = "Zoom Level: %s %", + ["night_vision"] = "Toggle Night Vision", + ["clipboard"] = "Link Copied To ~b~Cipboard", + ["picture_taken"] = "Picture Taken!", + ["please_wait"] = "Please Wait Before taking another ~b~Picture", + ["exit"] = "Exit", + + --- Furniture Strings ------ + + ["Height"] = "Height", + ["rotate"] = "Rotation", + ["place"] = "Place Furniture", + ["delete_furni"] = "Delete", + ["confirm_buy"] = "Do You Want To Buy %s ?", + ["price"] = "Price: $&s", + ["yes"] = "Yes", + ["no"] = "No", + ["action"] = "You %s ~b~%s~s~ !", + ["bought_furni"] = "You Have ~g~Bought~s~ A ~b~%s~s~ !", + ["edited_furni"] = "You Have Edited ~b~%s~s~ !", + ["cannot_buy"] = "You ~r~Cannot~s~ Buy This!", + ["cannot_edit"] = "You ~r~Cannot~s~ Edit This!", + ["store_title"] = "Store - %s", + ["back"] = "Return", + ["edit_title"] = "Editing - %s", + ["move_title"] = "Move", + ["deleted_confirm"] = "Deleting ~b~%s~s~!", + ["deleted_error"] = "Cannot Delete ~b~%s~s~!", + ["owned_furni"] = "Owned Furniture", + ["menu_stores"] = "Furniture Stores", + ["menu_stores_desc"] = "Buy Furniture", + ["menu_reset"] = "Reset", + ["menu_reset_desc"] = "Clears All Furniture", + ["menu_edit"] = "Edit", + ["menu_edit_desc"] = "Move and/or Delete furniture items", + ["furni_command"] = "furniture", + ["furni_Command_desc"] = "(ESX Property) Open Furniture Menu", + ["furni_command_permission"] = "You ~r~Cannot~s~ Access This Menu!", + ["furni_reset_success"] = "Furniture Reset!", + ["furni_cannot_afford"] = "You Cannot Afford Todo this!", + ["furni_reset_error"] = "You ~r~Cannot~s~ Reset This Property!", + ["furni_management"] = "Manage Furniture", + + --------- Key Strings --------------- + + ["you_granted"] = "You Have Been Granted Keys To ~b~%s~s~.", + ["already_has"] = "This Player Already Has Keys!", + ["do_not_own"] = "You do ~r~not~s~ own this property.", + ["key_revoked"] = "Your Key Access To ~b~%s~s~. Has Been ~r~Revoked~s~", + ["no_keys"] = "This Player Does Not Have Keys!", + ["nearby"] = "Nearby Players", + ["gave_key"] = "Giving Keys to %s!", + ["key_cannot_give"] = "You Cannot Give This Player A ~r~Key", + ["remove_title"] = "Remove Keys From Player", + ["key_revoke_success"] = "Revoking Keys From ~b~%s~s~.", + ["key_revoke_error"] = "You Cannot ~b~Remove~s~ A ~r~Key~s~ From this Person", + ["key_management"] = "Key Management", + ["key_management_desc"] = "Control Property Access.", + ["give_keys"] = "Give Keys", + ["remove_keys"] = "Remove Keys", + + --------- Real Estate Strings --------------- + ["office_blip"] = "%s Office", + ["actions"] = "Real Estate Actions", + ["property_create"] = "Create Property", + ["property_manage"] = "Manage Properties", + ["realestate_command"] = "realestatequickmenu", + ["realestate_command_desc"] = "(ESX Property) Open Real Estate Quick Actions", + ["enter_office"] = "~b~Entering~s~ Office.", + ["enter_office_error"] = "You ~r~Cannot~s~ Enter The Office!", + ["exit_office"] = "~b~Exiting~s~ Office.", + ["exit_office_error"] = "You ~r~Cannot~s~ Exit The Office!", + ["realestate_textui"] = "Press ~b~[E]~s~ to Access ~b~%s", + + ------------Command Strings----------------------- + ["refresh_name"] = "property:refresh", + ["refresh_desc"] = "Refresh to Server Start State", + ["save_name"] = "property:save", + ["save_desc"] = "Force Save Properties", + ["create_name"] = "property:create", + ["create_desc"] = "Create A New Property", + ["admin_name"] = "property:admin", + ["admin_desc"] = "Manage/view all properties", + + ---------- Property Actions Menu ------------------------- + + ["knocking"] = "Someone Is ~b~Knocking~s~ On The Door.", + ["name_edit"] = "Edit Property Name", + ["name"] = "Name", + ["confirm"] = "Confirm", + ["name_edit_success"] = "You Have Set The Property Name To ~b~%s~s~.", + ["name_edit_error"] = "You Cannot Set The Property Name To ~r~%s~s~.", + ["door_locked"] = "Door: Locked", + ["door_unlocked"] = "Door: Unlocked", + ["name_manage"] = "Manage Name", + ["name_manage_desc"] = "Set The Name of the Property.", + ["sell_title"] = "Sell", + ["sell_desc"] = "Sell This Property For $%s", + ["raid_title"] = "Raid", + ["raid_desc"] = "Force Entry Into Property.", + ["cctv_title"] = "CCTV", + ["cctv_desc"] = "Check the CCTV Camera.", + ["inventory_title"] = "Inventory", + ["inventory_desc"] = "Change Position of Property Storage.", + ["wardrobe_title"] = "Wardrobe", + ["wardrobe_desc"] = "Change Position of Property Wardrobe.", + ["furniture_title"] = "Furniture", + ["furniture_desc"] = "Change Position of Property Furniture.", + ["enter_title"] = "Enter", + ["knock_title"] = "Knock On Door", + ["buy_title"] = "Buy", + ["buy_desc"] = "Buy This Property For $%s", + ["sellplayer_title"] = "Sell To Player", + ["sellplayer_desc"] = "Sell This Property For $%s", + ["view_title"] = "Preview Interior", + ["exit_title"] = "Exit", + ["property_editing_error"] = "You Are Currently Editing The Property.", + ["unlock_error"] = "You Cannot ~b~Unlock~s~ This Property", + ["lock_error"] = "You Cannot ~b~Lock~s~ This Property", + ["prep_raid"] = "~b~Preparing~s~ Raid!", + ["raiding"] = "Raiding...", + ["cancel_raiding"] = "~r~Cancelled~s~ Raid!", + ["cannot_raid"] = "You Cannot ~b~Raid~s~ This Property.", + ["storage_pos_textui"] = "Press ~b~[G]~s~ To Set Storage Position", + ["storage_pos_success"] = "~b~Storage~s~ Position Set.", + ["storage_pos_error"] = "~r~Cannot~s~ Set ~b~Storage~s~ Position.", + ["wardrobe_pos_textui"] = "Press ~b~[G]~s~ To Set Wardrobe Position", + ["wardrobe_pos_success"] = "~b~Wardrobe~s~ Position Set.", + ["wardrobe_pos_error"] = "~r~Cannot~s~ Set ~b~Wardrobe~s~ Position.", + ["please_finish"] = "Please Finish Setting ~b~%s~s~ Position", + ["cannot_afford"] = "You Cannot Purchase This Property!", + ["select_player"] = "Select Player", + ["cannot_sell"] = "Cannot Sell To This Player!", + ["knock_on_door"] = "Knocking On Door...", + ["nobody_home"] = "It Seems Nobody is home...", + + ---------- General Strings ---------------- + + ["enabled"] = "Enabled", + ["disabled"] = "Disabled", + ["exiting"] = "Exiting property...", + ["entering"] = "Entering property...", + ["shell_disabled"] = "This Interior Uses Shells, which are disabled!", + ["access_textui"] = "Press ~b~[E]~s~ to Access ~b~%s", + ["raid_notify_error"] = "You need ~b~ %sx %s~s~ to be able to raid!", + ["raid_notify_success"] = "Your Property is Currently Being ~b~Raided!", + + --------------- Garage Strings -------------- + + ["store_success"] = "Vehicle ~b~Stored!", + ["store_error"] = "You Cannot Store This Vehicle!", + ["property_garage"] = "Property Garage", + ["retriving_notify"] = "Retrieving ~b~%s~s~ ...", + ["cannot_access"] = "You Cannot Access This Garage!", + ["store_textui"] = "Press ~b~[E]~s~ to Store ~b~%s", + ["garage_not_enabled"] = "Garage Not Enabled On This Property.", + ["cannot_access_property"] = "You ~r~Cannot~s~ Access this property.", + + ----------------- Creation Menu Strings ---------------- + + ["menu_title"] = "Property Creation", + ["element_title1"] = "Street Number", + ["element_description1"] = "Set the Property Street Number.", + ["element_title2"] = "Price", + ["element_description2"] = "Set the Price of the Property.", + ["element_title3"] = "Interior", + ["element_description3"] = "Select An Interior For The Property", + ["element_title4"] = "Garage", + ["element_description4"] = "(Optional) Manage Garage Settings", + ["element_title5"] = "CCTV", + ["element_description5"] = "(Optional) Manage CCTV Settings", + ["element_title6"] = "Entrance", + ["element_description6"] = "Set The Property`s Entrance Location.", + ["element_create_title"] = "Create Property", + ["element_create_desc_1"] = "Please Fill Out all Required Inputs!", + ["entrance_set_title"] = "Entrance Set.", + ["entrance_set_description"] = "Entrance: %s, %s, %s", + ["interior_set_title"] = "Interior Selected.", + ["interior_set_description"] = "Selected: %s", + ["ipl_title"] = "IPL Interiors", + ["types_title"] = "Interior Types", + ["ipl_description"] = "Native GTA Interiors, Made by R*", + ["shell_title"] = "Custom Interiors", + ["shell_description"] = "Custom Interiors, Made by You", + ["cctv_settings"] = "CCTV Settings", + ["garage_settings"] = "Garage Settings", + ["toggle_title"] = "Toggle Usage", + ["toggle_description"] = "Current Status: %s", + ["cctv_set_title"] = "Set CCTV Angle", + ["cctv_set_description"] = "Sets the Camera angle to your Cameras Direction", + ["back_description"] = "return to property creation.", + ["garage_set_title"] = "Set Garage Position", + ["garage_set_description"] = "Set the position of the Property Garage.", + ["garage_textui"] = "Press ~b~[E]~s~ to Set Position", + ["cctv_textui_1"] = "Press ~b~[E]~s~ to Set Angle", + ["cctv_textui_2"] = "Press ~b~[E]~s~ to Set Max Right Roation", + ["cctv_textui_3"] = "Press ~b~[E]~s~ to Set Max Left Roation", + ["create_success"] = "Property created!", + ["missing_data"] = "Please Fill Out all Required Inputs!", + + -- Saving Translations + ["server_restart"] = "Server Restarting", + ["server_shutdown"] = "Server Shutdown", + ["manual_save"] = "Manual Save (Requested By %s)", + ["resource_stop"] = "Resource Stopping", + ["force_save"] = "Force Save (Requested By %s)", + ["interval_saving"] = "Interval Saving", +} diff --git a/server-data/resources/[esx_addons]/esx_property/locales/it.lua b/server-data/resources/[esx_addons]/esx_property/locales/it.lua index 24496a499..044479bc2 100644 --- a/server-data/resources/[esx_addons]/esx_property/locales/it.lua +++ b/server-data/resources/[esx_addons]/esx_property/locales/it.lua @@ -1,218 +1,215 @@ -Locales['it'] = { - --- CCTV Strings ------ - - ["take_picture"] = "scatta foto", - ["rot_left_right"] = "sinistra/destra", - ["rot_up_down"] = "su/giu'", - ["Zoom"] = "Zoom avanti/indietro", - ["Zoom_level"] = "livello zoom: %s %", - ["night_vision"] = "attiva/disattiva visione notturna", - ["clipboard"] = "collegamento copiato in ~b~clipboard", - ["picture_taken"] = "foto scattata!", - ["please_wait"] = "per favore attendi prima di scattare un'altra ~b~foto", - ["exit"] = "esci", - - --- Furniture Strings ------ - - ["Height"] = "altezza", - ["rotate"] = "Rotazione", - ["place"] = "posiziona mobili", - ["delete_furni"] = "elimina", - ["confirm_buy"] = "vuoi acquistare %s ?", - ["price"] = "Prezzo: $&s", - ["yes"] = "si", - ["no"] = "No", - ["action"] = "tu %s ~b~%s~s~ !", - ["bought_furni"] = "hai ~g~comprato~s~ A ~b~%s~s~ !", - ["edited_furni"] = "hai modificato ~b~%s~s~ !", - ["cannot_buy"] = "tu ~r~non puoi~s~ comprare questo!", - ["cannot_edit"] = "tu ~r~non puoi~s~ modificarlo!", - ["store_title"] = "negozio - %s", - ["back"] = "Ritorna", - ["edit_title"] = "modifica - %s", - ["move_title"] = "sposta", - ["deleted_confirm"] = "eliminare ~b~%s~s~!", - ["deleted_error"] = "impossibile eliminare ~b~%s~s~!", - ["owned_furni"] = "mobili di proprieta'", - ["menu_stores"] = "mobilificio", - ["menu_stores_desc"] = "acquista mobili", - ["menu_reset"] = "Ripristina", - ["menu_reset_desc"] = "Cancella tutti i mobili", - ["menu_edit"] = "modifica", - ["menu_edit_desc"] = "sposta e/o elimina i mobili", - ["furni_command"] = "mobili", - ["furni_Command_desc"] = "apri menu mobili", - ["furni_command_permission"] = "tu ~r~non puoi~s~ accedere a questo menu!", - ["furni_reset_success"] = "ripristina mobili!", - ["furni_cannot_afford"] = "non puoi permetterti di farlo!", - ["furni_reset_error"] = " ~r~non puoi~s~ ripristinare questa proprieta'!", - ["furni_management"] = "gestisci mobili", - - --------- Key Strings --------------- - - ["you_granted"] = 'ti sono state concesse le chiavi di ~b~%s~s~.', - ["already_has"] = "questo giocatore ha gia' le chiavi!", - ["do_not_own"] = "~r~non~s~ possiedi questa proprieta'.", - ["key_revoked"] = 'la tua chiave di accesso a ~b~%s~s~. e\' stata ~r~revocata~s~', - ["no_keys"] = "questo giocatore non ha le chiavi!", - ["nearby"] = "giocatori vicini", - ["gave_key"] = "stai dando le chiavi a %s!", - ["key_cannot_give"] = "non puoi consegnare a questo giocatore ~r~la chiave", - ["remove_title"] = "rimuovi le chiavi", - ["key_revoke_success"] = "revocare le chiavi ~b~%s~s~.", - ["key_revoke_error"] = "non puoi ~b~rimuovere~s~ la ~r~chiave~s~ a questa persona", - ["key_management"] = "gestione chiavi", - ["key_management_desc"] = "controlla l'accesso alla proprieta'.", - ["give_keys"] = "dai chiavi", - ["remove_keys"] = "rimuovi chiavi", - - - --------- Real Estate Strings --------------- - ["office_blip"] = "%s ufficio", - ["actions"] = "azioni immobililiari", - ["property_create"] = "crea proprieta'", - ["property_manage"] = "gestisci proprieta'", - ["realestate_command"] = "menu rapido immobiliare", - ["realestate_command_desc"] = "apri azioni rapide immobiliari", - ["enter_office"] = "~b~entra in~s~ ufficio.", - ["enter_office_error"] = "tu ~r~non puoi~s~ entrare in ufficio!", - ["exit_office"] = "~b~esci~s~ dall'ufficio.", - ["exit_office_error"] = "~r~non puoi~s~ uscire dall'ufficio!", - ["realestate_textui"] = "Premi ~b~[E]~s~ per accedere ~b~%s", - - ------------Command Strings----------------------- - ["refresh_name"] = "property:refresh", - ["refresh_desc"] = "aggiorna allo stato iniziale del server", - ["save_name"] = "property:save", - ["save_desc"] = "forza il salvataggio delle proprieta'", - ["create_name"] = "property:create", - ["create_desc"] = "crea una nuova proprieta'", - ["admin_name"] = "property:admin", - ["admin_desc"] = "gestisci/visualizza tutte le proprieta'", - - - ---------- Property Actions Menu ------------------------- - - ["knocking"] = "qualcuno sta ~b~bussando~s~ alla porta.", - ["name_edit"] = "modifica il nome della proprieta'", - ["name"] = "Nome", - ["confirm"] = "Conferma", - ["name_edit_success"] = "hai impostato il nome della proprieta' su ~b~%s~s~.", - ["name_edit_error"] = "non puoi impostare il nome della proprieta' su ~r~%s~s~.", - ["door_locked"] = "porta: chiusa", - ["door_unlocked"] = "porta: aperta", - ["name_manage"] = "gestisci nome", - ["name_manage_desc"] = "imposta il nome della proprieta'.", - ["sell_title"] = "vendi", - ["sell_desc"] = "vendi questa proprieta' per $%s", - ["raid_title"] = "Raid", - ["raid_desc"] = "forza l'ingresso nella proprieta'.", - ["cctv_title"] = "CCTV", - ["cctv_desc"] = "controlla la telecamera CCTV.", - ["inventory_title"] = "Inventario", - ["inventory_desc"] = "cambia la posizione dell'inventario.", - ["wardrobe_title"] = "guardaroba", - ["wardrobe_desc"] = "cambia la posizione del guardaroba.", - ["furniture_title"] = "mobili", - ["furniture_desc"] = "Cambia la posizione dei mobili.", - ["enter_title"] = "entra", - ["knock_title"] = "bussare alla porta", - ["buy_title"] = "acquista", - ["buy_desc"] = "acquista questa proprieta' per $%s", - ["sellplayer_title"] = "vendi al giocatore", - ["sellplayer_desc"] = "vendi questa' proprieta' per $%s", - ["view_title"] = "anteprima interni", - ["exit_title"] = "Esci", - ["property_editing_error"] = "stai modificando la proprieta'.", - ["unlock_error"] = "non puoi ~b~sbloccare~s~ questa proprieta'", - ["lock_error"] = "non puoi ~b~bloccare~s~ questa proprieta'", - ["prep_raid"] = "~b~Preparazione~s~ Raid!", - ["raiding"] = "Raid in corso...", - ["cancel_raiding"] = "~r~Raid~s~ cancellato!", - ["cannot_raid"] = "non puoi fare un ~b~Raid~s~ in questa proprieta'.", - ["storage_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione del deposito", - ["storage_pos_success"] = "~b~deposito~s~ posizione impostata.", - ["storage_pos_error"] = "~r~impossibile~s~ impostare il ~b~deposito~s~ qui.", - ["wardrobe_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione del guardaroba", - ["wardrobe_pos_success"] = "~b~guardaroba~s~ posizione impostata.", - ["wardrobe_pos_error"] = "~r~impossibile~s~ impostare il ~b~guardaroba~s~ qui.", - ["please_finish"] = "per favore termina di impostare le ~b~%s~s~ posizioni", - ["cannot_afford"] = "non puoi acquistare questa proprieta'!", - ["select_player"] = "Seleziona giocatore", - ["cannot_sell"] = "impossibile vendere a questo giocatore!", - ["knock_on_door"] = "bussare alla porta...", - ["nobody_home"] = "sembra che nessuno sia in casa...", - - ---------- General Strings ---------------- - - ["enabled"] = "abilitato", - ["disabled"] = "disattivato", - ["exiting"] = "uscendo da casa...", - ["entering"] = "entrando in casa...", - ["shell_disabled"] ="questa proprieta' usa arredamenti che sono disabilitati!", - ["access_textui"] = "Premi ~b~[E]~s~ per accedere a ~b~%s", - ["raid_notify_error"] = "hai bisogno di ~b~ %sx %s~s~ per poter fare il raid!", - ["raid_notify_success"] = "la tua proprieta' e' in fase di ~b~Raid!", - - --------------- Garage Strings -------------- - - ["store_success"] = "Veicolo ~b~depositato!", - ["store_error"] = "non puoi riporre questo veicolo!", - ["property_garage"] = "Garage di proprieta'", - ["retriving_notify"] = "Recupera ~b~%s~s~ ...", - ["cannot_access"] = "non puoi accedere a questo garage!", - ["store_textui"] = "Premi ~b~[E]~s~ per depositare ~b~%s", - ["garage_not_enabled"] = "Garage non abilitato su questa proprieta'.", - ["cannot_access_property"] = "~r~non puoi~s~ accedere a questa proprieta'.", - - - ----------------- Creation Menu Strings ---------------- - - ["menu_title"] = "creazione proprieta'", - ["element_title1"] = "numero civico", - ["element_description1"] = "imposta il numero civico della struttura.", - ["element_title2"] = "Prezzo", - ["element_description2"] = "imposta il prezzo della proprieta'.", - ["element_title3"] = "Interni", - ["element_description3"] = "seleziona un interno per la proprieta'", - ["element_title4"] = "Garage", - ["element_description4"] = "(facoltativo) gestisci le impostazioni del garage", - ["element_title5"] = "CCTV", - ["element_description5"] = "(facoltativo) gestisci le impostazioni CCTV", - ["element_title6"] = "ingresso", - ["element_description6"] = "imposta la posizione di ingresso della struttura.", - ["element_create_title"] = "Crea proprieta'", - ["element_create_desc_1"] = "compila tutti i campi richiesti!", - ["entrance_set_title"] = "posiziona ingresso.", - ["entrance_set_description"] = "Entrata: %s, %s, %s", - ["interior_set_title"] = "Interno selezionato.", - ["interior_set_description"] = "Selezionato: %s", - ["ipl_title"] = "interni IPL", - ["types_title"] = "tipi di interni", - ["ipl_description"] = "interni nativi GTA", - ["shell_title"] = "interni personalizzati", - ["shell_description"] = "interni peersonalizzati, realizzati da te", - ["cctv_settings"] = "impostazioni CCTV", - ["garage_settings"] = " impostazioni Garage", - ["toggle_title"] = "attiva/disattiva utilizzo", - ["toggle_description"] = "stato corrente: %s", - ["cctv_set_title"] = "imposta angola CCTV", - ["cctv_set_description"] = "imposta l'angolo della telecamera", - ["back_description"] = "ritorna alla creazione della proprieta'.", - ["garage_set_title"] = "imposta posizione garage", - ["garage_set_description"] = "imposta la posizione del garage di proprieta'.", - ["garage_textui"] = "Premi ~b~[E]~s~ per impostare la posizione", - ["cctv_textui_1"] = "Premi ~b~[E]~s~ per impostare l'angolo", - ["cctv_textui_2"] = "Premi ~b~[E]~s~ per impostare la rotazione massima a destra", - ["cctv_textui_3"] = "Premi ~b~[E]~s~ per impostare la rotazione massima a sinistra", - ["create_success"] = "Proprieta creata!", - ["missing_data"] = "compila tutti i campi richiesti!", - - -- Saving Translations - ["server_restart"] = "Server in riavvio", - ["server_shutdown"] = "spegnimento server", - ["manual_save"] = "salvataggio manuale (richiesto da %s)", - ["resource_stop"] = "arresto risorsa", - ["force_save"] = "salvataggio forzato (richiesto da %s)", - ["interval_saving"] = "Intervallo salvataggio" - } +Locales["it"] = { + --- CCTV Strings ------ + + ["take_picture"] = "scatta foto", + ["rot_left_right"] = "sinistra/destra", + ["rot_up_down"] = "su/giu'", + ["Zoom"] = "Zoom avanti/indietro", + ["Zoom_level"] = "livello zoom: %s %", + ["night_vision"] = "attiva/disattiva visione notturna", + ["clipboard"] = "collegamento copiato in ~b~clipboard", + ["picture_taken"] = "foto scattata!", + ["please_wait"] = "per favore attendi prima di scattare un'altra ~b~foto", + ["exit"] = "esci", + + --- Furniture Strings ------ + + ["Height"] = "altezza", + ["rotate"] = "Rotazione", + ["place"] = "posiziona mobili", + ["delete_furni"] = "elimina", + ["confirm_buy"] = "vuoi acquistare %s ?", + ["price"] = "Prezzo: $&s", + ["yes"] = "si", + ["no"] = "No", + ["action"] = "tu %s ~b~%s~s~ !", + ["bought_furni"] = "hai ~g~comprato~s~ A ~b~%s~s~ !", + ["edited_furni"] = "hai modificato ~b~%s~s~ !", + ["cannot_buy"] = "tu ~r~non puoi~s~ comprare questo!", + ["cannot_edit"] = "tu ~r~non puoi~s~ modificarlo!", + ["store_title"] = "negozio - %s", + ["back"] = "Ritorna", + ["edit_title"] = "modifica - %s", + ["move_title"] = "sposta", + ["deleted_confirm"] = "eliminare ~b~%s~s~!", + ["deleted_error"] = "impossibile eliminare ~b~%s~s~!", + ["owned_furni"] = "mobili di proprieta'", + ["menu_stores"] = "mobilificio", + ["menu_stores_desc"] = "acquista mobili", + ["menu_reset"] = "Ripristina", + ["menu_reset_desc"] = "Cancella tutti i mobili", + ["menu_edit"] = "modifica", + ["menu_edit_desc"] = "sposta e/o elimina i mobili", + ["furni_command"] = "mobili", + ["furni_Command_desc"] = "apri menu mobili", + ["furni_command_permission"] = "tu ~r~non puoi~s~ accedere a questo menu!", + ["furni_reset_success"] = "ripristina mobili!", + ["furni_cannot_afford"] = "non puoi permetterti di farlo!", + ["furni_reset_error"] = " ~r~non puoi~s~ ripristinare questa proprieta'!", + ["furni_management"] = "gestisci mobili", + + --------- Key Strings --------------- + + ["you_granted"] = "ti sono state concesse le chiavi di ~b~%s~s~.", + ["already_has"] = "questo giocatore ha gia' le chiavi!", + ["do_not_own"] = "~r~non~s~ possiedi questa proprieta'.", + ["key_revoked"] = "la tua chiave di accesso a ~b~%s~s~. e' stata ~r~revocata~s~", + ["no_keys"] = "questo giocatore non ha le chiavi!", + ["nearby"] = "giocatori vicini", + ["gave_key"] = "stai dando le chiavi a %s!", + ["key_cannot_give"] = "non puoi consegnare a questo giocatore ~r~la chiave", + ["remove_title"] = "rimuovi le chiavi", + ["key_revoke_success"] = "revocare le chiavi ~b~%s~s~.", + ["key_revoke_error"] = "non puoi ~b~rimuovere~s~ la ~r~chiave~s~ a questa persona", + ["key_management"] = "gestione chiavi", + ["key_management_desc"] = "controlla l'accesso alla proprieta'.", + ["give_keys"] = "dai chiavi", + ["remove_keys"] = "rimuovi chiavi", + + --------- Real Estate Strings --------------- + ["office_blip"] = "%s ufficio", + ["actions"] = "azioni immobililiari", + ["property_create"] = "crea proprieta'", + ["property_manage"] = "gestisci proprieta'", + ["realestate_command"] = "menu rapido immobiliare", + ["realestate_command_desc"] = "apri azioni rapide immobiliari", + ["enter_office"] = "~b~entra in~s~ ufficio.", + ["enter_office_error"] = "tu ~r~non puoi~s~ entrare in ufficio!", + ["exit_office"] = "~b~esci~s~ dall'ufficio.", + ["exit_office_error"] = "~r~non puoi~s~ uscire dall'ufficio!", + ["realestate_textui"] = "Premi ~b~[E]~s~ per accedere ~b~%s", + + ------------Command Strings----------------------- + ["refresh_name"] = "property:refresh", + ["refresh_desc"] = "aggiorna allo stato iniziale del server", + ["save_name"] = "property:save", + ["save_desc"] = "forza il salvataggio delle proprieta'", + ["create_name"] = "property:create", + ["create_desc"] = "crea una nuova proprieta'", + ["admin_name"] = "property:admin", + ["admin_desc"] = "gestisci/visualizza tutte le proprieta'", + + ---------- Property Actions Menu ------------------------- + + ["knocking"] = "qualcuno sta ~b~bussando~s~ alla porta.", + ["name_edit"] = "modifica il nome della proprieta'", + ["name"] = "Nome", + ["confirm"] = "Conferma", + ["name_edit_success"] = "hai impostato il nome della proprieta' su ~b~%s~s~.", + ["name_edit_error"] = "non puoi impostare il nome della proprieta' su ~r~%s~s~.", + ["door_locked"] = "porta: chiusa", + ["door_unlocked"] = "porta: aperta", + ["name_manage"] = "gestisci nome", + ["name_manage_desc"] = "imposta il nome della proprieta'.", + ["sell_title"] = "vendi", + ["sell_desc"] = "vendi questa proprieta' per $%s", + ["raid_title"] = "Raid", + ["raid_desc"] = "forza l'ingresso nella proprieta'.", + ["cctv_title"] = "CCTV", + ["cctv_desc"] = "controlla la telecamera CCTV.", + ["inventory_title"] = "Inventario", + ["inventory_desc"] = "cambia la posizione dell'inventario.", + ["wardrobe_title"] = "guardaroba", + ["wardrobe_desc"] = "cambia la posizione del guardaroba.", + ["furniture_title"] = "mobili", + ["furniture_desc"] = "Cambia la posizione dei mobili.", + ["enter_title"] = "entra", + ["knock_title"] = "bussare alla porta", + ["buy_title"] = "acquista", + ["buy_desc"] = "acquista questa proprieta' per $%s", + ["sellplayer_title"] = "vendi al giocatore", + ["sellplayer_desc"] = "vendi questa' proprieta' per $%s", + ["view_title"] = "anteprima interni", + ["exit_title"] = "Esci", + ["property_editing_error"] = "stai modificando la proprieta'.", + ["unlock_error"] = "non puoi ~b~sbloccare~s~ questa proprieta'", + ["lock_error"] = "non puoi ~b~bloccare~s~ questa proprieta'", + ["prep_raid"] = "~b~Preparazione~s~ Raid!", + ["raiding"] = "Raid in corso...", + ["cancel_raiding"] = "~r~Raid~s~ cancellato!", + ["cannot_raid"] = "non puoi fare un ~b~Raid~s~ in questa proprieta'.", + ["storage_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione del deposito", + ["storage_pos_success"] = "~b~deposito~s~ posizione impostata.", + ["storage_pos_error"] = "~r~impossibile~s~ impostare il ~b~deposito~s~ qui.", + ["wardrobe_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione del guardaroba", + ["wardrobe_pos_success"] = "~b~guardaroba~s~ posizione impostata.", + ["wardrobe_pos_error"] = "~r~impossibile~s~ impostare il ~b~guardaroba~s~ qui.", + ["please_finish"] = "per favore termina di impostare le ~b~%s~s~ posizioni", + ["cannot_afford"] = "non puoi acquistare questa proprieta'!", + ["select_player"] = "Seleziona giocatore", + ["cannot_sell"] = "impossibile vendere a questo giocatore!", + ["knock_on_door"] = "bussare alla porta...", + ["nobody_home"] = "sembra che nessuno sia in casa...", + + ---------- General Strings ---------------- + + ["enabled"] = "abilitato", + ["disabled"] = "disattivato", + ["exiting"] = "uscendo da casa...", + ["entering"] = "entrando in casa...", + ["shell_disabled"] = "questa proprieta' usa arredamenti che sono disabilitati!", + ["access_textui"] = "Premi ~b~[E]~s~ per accedere a ~b~%s", + ["raid_notify_error"] = "hai bisogno di ~b~ %sx %s~s~ per poter fare il raid!", + ["raid_notify_success"] = "la tua proprieta' e' in fase di ~b~Raid!", + + --------------- Garage Strings -------------- + + ["store_success"] = "Veicolo ~b~depositato!", + ["store_error"] = "non puoi riporre questo veicolo!", + ["property_garage"] = "Garage di proprieta'", + ["retriving_notify"] = "Recupera ~b~%s~s~ ...", + ["cannot_access"] = "non puoi accedere a questo garage!", + ["store_textui"] = "Premi ~b~[E]~s~ per depositare ~b~%s", + ["garage_not_enabled"] = "Garage non abilitato su questa proprieta'.", + ["cannot_access_property"] = "~r~non puoi~s~ accedere a questa proprieta'.", + + ----------------- Creation Menu Strings ---------------- + + ["menu_title"] = "creazione proprieta'", + ["element_title1"] = "numero civico", + ["element_description1"] = "imposta il numero civico della struttura.", + ["element_title2"] = "Prezzo", + ["element_description2"] = "imposta il prezzo della proprieta'.", + ["element_title3"] = "Interni", + ["element_description3"] = "seleziona un interno per la proprieta'", + ["element_title4"] = "Garage", + ["element_description4"] = "(facoltativo) gestisci le impostazioni del garage", + ["element_title5"] = "CCTV", + ["element_description5"] = "(facoltativo) gestisci le impostazioni CCTV", + ["element_title6"] = "ingresso", + ["element_description6"] = "imposta la posizione di ingresso della struttura.", + ["element_create_title"] = "Crea proprieta'", + ["element_create_desc_1"] = "compila tutti i campi richiesti!", + ["entrance_set_title"] = "posiziona ingresso.", + ["entrance_set_description"] = "Entrata: %s, %s, %s", + ["interior_set_title"] = "Interno selezionato.", + ["interior_set_description"] = "Selezionato: %s", + ["ipl_title"] = "interni IPL", + ["types_title"] = "tipi di interni", + ["ipl_description"] = "interni nativi GTA", + ["shell_title"] = "interni personalizzati", + ["shell_description"] = "interni peersonalizzati, realizzati da te", + ["cctv_settings"] = "impostazioni CCTV", + ["garage_settings"] = " impostazioni Garage", + ["toggle_title"] = "attiva/disattiva utilizzo", + ["toggle_description"] = "stato corrente: %s", + ["cctv_set_title"] = "imposta angola CCTV", + ["cctv_set_description"] = "imposta l'angolo della telecamera", + ["back_description"] = "ritorna alla creazione della proprieta'.", + ["garage_set_title"] = "imposta posizione garage", + ["garage_set_description"] = "imposta la posizione del garage di proprieta'.", + ["garage_textui"] = "Premi ~b~[E]~s~ per impostare la posizione", + ["cctv_textui_1"] = "Premi ~b~[E]~s~ per impostare l'angolo", + ["cctv_textui_2"] = "Premi ~b~[E]~s~ per impostare la rotazione massima a destra", + ["cctv_textui_3"] = "Premi ~b~[E]~s~ per impostare la rotazione massima a sinistra", + ["create_success"] = "Proprieta creata!", + ["missing_data"] = "compila tutti i campi richiesti!", + + -- Saving Translations + ["server_restart"] = "Server in riavvio", + ["server_shutdown"] = "spegnimento server", + ["manual_save"] = "salvataggio manuale (richiesto da %s)", + ["resource_stop"] = "arresto risorsa", + ["force_save"] = "salvataggio forzato (richiesto da %s)", + ["interval_saving"] = "Intervallo salvataggio", +} diff --git a/server-data/resources/[esx_addons]/esx_property/properties.json b/server-data/resources/[esx_addons]/esx_property/properties.json index a99deb4e0..e728f3e95 100644 --- a/server-data/resources/[esx_addons]/esx_property/properties.json +++ b/server-data/resources/[esx_addons]/esx_property/properties.json @@ -1 +1,3593 @@ -[{"Locked":false,"Price":25000,"Entrance":{"z":28.57,"y":6206.16,"x":-467.88},"furniture":[],"plysinside":[],"Keys":[],"Owned":false,"Owner":"","OwnerName":"","setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":90.71163940429688,"maxright":-88.02642059326172,"enabled":true,"rot":{"z":2.7542073726654,"y":2.7045992112562097e-8,"x":-9.43104267120361}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1076 Procopio Dr","Interior":"low-end"},{"Locked":false,"Price":25000,"Entrance":{"z":29.07,"y":6260.23,"x":-448.02},"furniture":[],"plysinside":[],"Keys":[],"Owned":false,"Owner":"","OwnerName":"","setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-113.61099243164064,"maxright":70.65039825439453,"enabled":true,"rot":{"z":162.9940643310547,"y":-0.0,"x":3.75689458847045}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1075 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":27.96,"y":6314.13,"x":-407.35},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-54.77568435668945,"maxright":135.13072204589845,"enabled":true,"rot":{"z":-138.95835876464845,"y":-0.0,"x":-1.16786921024322}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1074 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":28.86,"y":6341.62,"x":-368.23},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-51.56189727783203,"maxright":132.70008850097657,"enabled":true,"rot":{"z":-139.94163513183598,"y":-0.0,"x":-2.56643605232238}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1073 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.52,"y":6400.88,"x":-272.61},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-65.34387969970703,"maxright":123.2501983642578,"enabled":true,"rot":{"z":-152.39810180664066,"y":-0.0,"x":-7.54235982894897}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1071 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.48,"y":6414.46,"x":-246.14},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-148.38644409179688,"maxright":38.33782577514648,"enabled":true,"rot":{"z":128.27305603027345,"y":4.379791960218428e-7,"x":-12.92249584197998}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1071 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.22,"y":6445.48,"x":-229.63},"furniture":[],"plysinside":[],"Price":27500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-135.48313903808598,"maxright":48.30059432983398,"enabled":true,"rot":{"z":137.8870849609375,"y":2.1444458297992242e-7,"x":-5.53862285614013}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"1070 Procopio Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":28.89,"y":6551.76,"x":-130.8},"furniture":[],"plysinside":[],"Price":27500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-46.79578399658203,"maxright":138.85032653808598,"enabled":true,"rot":{"z":-134.93411254882813,"y":1.0691521623584777e-7,"x":3.44796895980834}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"1067 Procopio Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.11,"y":6637.3,"x":-41.72},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-56.39479827880859,"maxright":129.07382202148438,"enabled":true,"rot":{"z":-144.0503692626953,"y":-1.3340336835199196e-8,"x":-0.24611411988735}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1065 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.72,"y":6654.13,"x":-9.62},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-68.07413482666016,"maxright":116.67019653320313,"enabled":true,"rot":{"z":-155.01153564453126,"y":-1.068413766347477e-7,"x":-2.71219563484191}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1064 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.86,"y":6207.33,"x":-356.82},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-45.94052505493164,"maxright":135.7574005126953,"enabled":true,"rot":{"z":-133.8831787109375,"y":-0.0,"x":-2.77191710472106}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1034 Paleto Blvd","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.87,"y":6252.75,"x":-379.92},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":42.09032440185547,"maxright":-131.2773895263672,"enabled":true,"rot":{"z":-40.4444465637207,"y":4.32035335506953e-7,"x":-8.85426330566406}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1034 Procopio Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":31.91,"y":6326.99,"x":-302.19},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":133.55870056152345,"maxright":-42.54082870483398,"enabled":true,"rot":{"z":44.16030502319336,"y":-9.440947223993136e-7,"x":-25.26673126220703}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1047 Paleto Blvd","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":30.9,"y":6225.21,"x":-347.3},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-43.60107040405273,"maxright":134.7738800048828,"enabled":true,"rot":{"z":-137.5096435546875,"y":-0.0,"x":-1.57497417926788}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"1043 Paleto Blvd","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":32.26,"y":6557.45,"x":-15.3},"furniture":[],"plysinside":[],"Price":25000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":43.89247512817383,"maxright":-133.83499145507813,"enabled":true,"rot":{"z":-45.87245941162109,"y":-0.0,"x":-11.80154037475586}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"1059 Paleto Blvd","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":32.1,"y":6568.19,"x":4.43},"furniture":[],"plysinside":[],"Price":27500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-139.30752563476566,"maxright":44.53319549560547,"enabled":true,"rot":{"z":129.4863433837891,"y":2.144746105159357e-7,"x":-5.62087059020996}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"1061 Paleto Blvd","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":31.84,"y":6596.46,"x":31.0},"furniture":[],"plysinside":[],"Price":27500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":-43.43285751342773,"maxright":-159.96804809570313,"enabled":true,"rot":{"z":-94.7632293701172,"y":-0.0,"x":-5.83577966690063}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"1061 Paleto Blvd","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":42.9,"y":4642.33,"x":1725.06},"furniture":[],"plysinside":[],"Price":12500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-63.00457000732422,"y":-0.0,"x":-6.35934734344482}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"2016 Grapeseed Main St","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":42.39,"y":4658.22,"x":1674.01},"furniture":[],"plysinside":[],"Price":12500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":91.53390502929688,"y":2.7858778395284394e-8,"x":-16.72389602661132}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"2015 Grapeseed Main St","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":42.68,"y":4677.34,"x":1718.91},"furniture":[],"plysinside":[],"Price":7500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-93.13695526123049,"y":-0.0,"x":-29.83987236022949}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"2014 Grapeseed Main St","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":42.09,"y":4689.52,"x":1682.85},"furniture":[],"plysinside":[],"Price":7500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":91.7155303955078,"y":-0.0,"x":-6.32857131958007}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"2013 Grapeseed Main St","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":41.03,"y":4739.5,"x":1664.0},"furniture":[],"plysinside":[],"Price":10000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":110.03758239746094,"y":-0.0,"x":-18.96443367004394}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"2011 Grapeseed Main St","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":32.23,"y":3920.59,"x":1880.27},"furniture":[],"plysinside":[],"Price":10000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-77.30774688720703,"y":-0.0,"x":-14.36374378204345}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"3012 Niland Ave","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":32.48,"y":3914.59,"x":1846.06},"furniture":[],"plysinside":[],"Price":9000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":103.60260009765624,"y":-2.1725810483985698e-7,"x":-10.75266551971435}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"3013 Niland Ave","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":36.08,"y":3913.8,"x":1803.57},"furniture":[],"plysinside":[],"Price":11500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-76.59026336669922,"y":-0.0,"x":-20.23343658447265}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"3013 Marina Dr","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":33.45,"y":3657.13,"x":1435.31},"furniture":[],"plysinside":[],"Price":11500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":95.02767944335938,"y":-0.0,"x":-5.87784767150878}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"3025 Lesbos Ln","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":43.5,"y":2607.8,"x":471.15},"furniture":[],"plysinside":[],"Price":12500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-166.2356719970703,"y":-0.0,"x":-20.86568069458007}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"4018 Route 68","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":42.28,"y":3087.1,"x":181.03},"furniture":[],"plysinside":[],"Price":7500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-93.07178497314452,"y":-0.0,"x":-11.2086534500122}},"positions":{"Wardrobe":{"z":-99.00859832763672,"y":-1003.45947265625,"x":259.9942932128906}},"Name":"4013 Joshua Rd","Interior":"low-end"},{"Locked":false,"Owned":false,"Entrance":{"z":73.50999999999999,"y":-593.38,"x":1386.22},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-127.72049713134766,"y":-0.0,"x":-9.48588275909423}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7340 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":73.52,"y":-569.49,"x":1388.94},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-69.5700912475586,"y":-0.0,"x":-9.84068393707275}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7341 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":73.71,"y":-555.82,"x":1373.19},"furniture":[],"plysinside":[],"Price":4500,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-114.24230194091796,"y":-0.0,"x":-12.52571487426757}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7341 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":73.72999999999999,"y":-606.62,"x":1367.33},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-177.74884033203126,"y":-0.0,"x":-10.93433380126953}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7340 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":73.72,"y":-597.26,"x":1341.64},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":62.37366104125976,"y":-0.0,"x":-17.39539337158203}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7339 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":72.91,"y":-546.97,"x":1348.31},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-27.96370315551757,"y":4.342483350683324e-7,"x":-10.56496334075927}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7342 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":72.27,"y":-583.06,"x":1323.3},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":152.2796173095703,"y":4.441767487151084e-7,"x":-16.03893852233886}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7339 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":71.46,"y":-535.91,"x":1328.57},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-111.59012603759766,"y":-0.00000144736395,"x":-53.85140228271484}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7342 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":70.75,"y":-574.08,"x":1301.02},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":164.71957397460938,"y":4.6078031346041828e-7,"x":-22.11302947998047}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7339 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":70.47999999999999,"y":-527.3,"x":1303.1},"furniture":[],"plysinside":[],"Price":45000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-19.26140213012695,"y":4.363083689895575e-7,"x":-11.92860603332519}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7342 Nikola Pl","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":56.84,"y":-729.5,"x":996.89},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":125.62109375,"y":-0.0,"x":-58.0705451965332}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7322 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.24,"y":-716.31,"x":979.11},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":131.13587951660157,"y":-0.0,"x":-15.06083393096923}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7320 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.5,"y":-701.3,"x":970.88},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":170.76788330078126,"y":3.3350637806961464e-9,"x":-0.14884614944458}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7320 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.47,"y":-669.85,"x":960.15},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":115.8887939453125,"y":4.346124455878453e-7,"x":-10.81925582885742}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7319 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.45,"y":-653.51,"x":943.45},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":38.34314727783203,"y":0.00000168464464,"x":-59.54927444458008}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7319 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":58.26,"y":-627.65,"x":980.25},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-144.15000915527345,"y":-0.0,"x":-36.16230392456055}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7318 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.26,"y":-639.71,"x":928.82},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":137.4777984619141,"y":-0.0,"x":-15.65773868560791}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7317 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.47,"y":-615.51,"x":902.95},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":46.20460510253906,"y":-0.00000160100864,"x":-57.77318572998047}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7317 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.47,"y":-608.21,"x":886.77},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":138.07872009277345,"y":-8.718344588487525e-7,"x":-11.68268966674804}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7316 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.18,"y":-583.65,"x":861.7},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-176.59844970703126,"y":-0.0,"x":-3.38041257858276}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7316 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.01,"y":-562.66,"x":844.12},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":12.50613498687744,"y":-2.1754524937023245e-7,"x":-11.14390087127685}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7312 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":56.95,"y":-532.68,"x":850.25},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":85.02394104003906,"y":-5.362977262279856e-8,"x":-5.74017667770385}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7314 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":56.74,"y":-508.98,"x":861.51},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":46.49221038818359,"y":0.00000154111978,"x":-56.35844421386719}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7313 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.11000000000001,"y":-497.87,"x":878.44},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":44.91729354858398,"y":-0.0,"x":-64.80823516845703}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7313 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":58.46,"y":-489.76,"x":906.46},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":19.29909515380859,"y":-0.0,"x":-14.44456386566162}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7311 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":60.1,"y":-477.8,"x":921.78},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-8.25692367553711,"y":-0.0,"x":-19.33738899230957}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7311 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":60.57,"y":-463.17,"x":944.54},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-55.23443603515625,"y":-8.953837777880835e-7,"x":-17.53591918945312}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7309 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":61.81,"y":-451.65,"x":967.16},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":33.32376480102539,"y":8.936335120779404e-7,"x":-17.17726707458496}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7309 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":63.06000000000001,"y":-433.03,"x":987.57},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":34.80197525024414,"y":8.771137913754501e-7,"x":-13.24740600585937}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7307 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":64.36999999999999,"y":-423.38,"x":1010.38},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":123.14452362060549,"y":-4.402644719903037e-7,"x":-14.16050624847412}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7307 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":65.36,"y":-408.36,"x":1028.78},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":41.270263671875,"y":-4.386202476780454e-7,"x":-13.28245830535888}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7305 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":67.25,"y":-378.13,"x":1060.52},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":54.3464241027832,"y":-8.817532943794504e-7,"x":-14.47243404388427}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7305 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":63.52,"y":-469.3,"x":1014.67},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-144.52737426757813,"y":-9.047982416632294e-7,"x":-19.33366966247558}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7306 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":61.16,"y":-502.36,"x":970.55},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-107.44925689697266,"y":-0.0,"x":-8.07564449310302}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7308 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":59.64,"y":-518.94,"x":945.9},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":119.70294189453124,"y":-0.0,"x":-61.49639892578125}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7310 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":58.81,"y":-526.05,"x":924.39},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-151.43536376953126,"y":-0.0,"x":-17.66978073120117}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7312 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.53,"y":-540.58,"x":893.24},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-69.45809936523438,"y":-9.24586970540986e-7,"x":-22.57007217407226}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7312 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":57.39,"y":-569.56,"x":919.7},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":28.74713134765625,"y":4.412431167111208e-7,"x":-14.65564727783203}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7312 Nikola Ave","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":58.75,"y":-541.93,"x":965.25},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":32.70853805541992,"y":-4.381802227726439e-7,"x":-13.03651428222656}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7310 Nikola Ave","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":59.71,"y":-525.76,"x":987.84},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":30.89822769165039,"y":9.366781910102872e-7,"x":-24.28778457641601}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7310 Nikola Ave","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":60.01,"y":-510.98,"x":1006.48},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-65.29899597167969,"y":-0.0,"x":-16.08703422546386}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7308 Nikola Ave","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":63.1,"y":-498.06,"x":1046.29},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":144.13137817382813,"y":9.091479000744585e-7,"x":-20.10037040710449}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7306 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":63.32,"y":-470.58,"x":1051.04},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":76.4620132446289,"y":-0.0,"x":-11.98972129821777}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7306 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":65.28,"y":-448.93,"x":1056.24},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":162.82366943359376,"y":-0.0,"x":-8.78071689605712}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7306 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":64.67999999999999,"y":-484.37,"x":1090.46},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-102.9858856201172,"y":-4.4310172597761268e-7,"x":-15.54805183410644}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7344 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":66.33999999999999,"y":-464.52,"x":1098.58},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-15.62946987152099,"y":2.17306606487e-7,"x":-10.81984233856201}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7346 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":66.81,"y":-438.69,"x":1099.44},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":179.49822998046876,"y":-0.0,"x":-11.32894706726074}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7346 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":66.58,"y":-411.33,"x":1101.06},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-93.88529205322266,"y":-5.391471091797939e-8,"x":-8.21971225738525}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7348 Bridge St","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":67.97,"y":-391.27,"x":1114.44},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-112.49811553955078,"y":-0.0,"x":-24.5419979095459}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7348 West Mirror Drive","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":69.03999999999999,"y":-429.86,"x":1262.35},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":112.37248229980468,"y":-2.144359569911103e-7,"x":-5.51487922668457}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7345 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":69.53999999999999,"y":-458.06,"x":1265.74},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":94.98734283447266,"y":-0.0,"x":-14.86165904998779}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7945 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":69.21,"y":-480.18,"x":1259.51},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":125.15465545654296,"y":-0.0,"x":-10.50986766815185}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7343 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":68.92999999999999,"y":-494.1,"x":1251.53},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":63.34117126464844,"y":-0.0,"x":-16.31183433532715}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7343 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":68.36999999999999,"y":-515.5,"x":1250.9},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":77.79755401611328,"y":-0.0,"x":-17.28229522705078}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7343 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":68.67999999999999,"y":-566.43,"x":1241.53},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":130.3302459716797,"y":-0.0,"x":-22.43321228027343}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7338 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":68.8,"y":-601.65,"x":1240.54},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":91.53223419189452,"y":-1.3435412782314417e-8,"x":-6.82489442825317}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7338 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":68.58999999999999,"y":-620.99,"x":1250.79},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Price":40000,"Owner":"","OwnerName":"","setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":27.77294158935547,"y":-2.145688853261163e-7,"x":-5.87094974517822}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7336 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":67.14,"y":-648.63,"x":1265.69},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-152.5341949462891,"y":-0.0,"x":-14.65502071380615}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7333 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":65.05,"y":-683.53,"x":1270.98},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-171.3050994873047,"y":-0.0,"x":-12.5356969833374}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7333 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":63.93,"y":-702.82,"x":1264.75},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":58.4541015625,"y":0.00000175048376,"x":-12.71638584136962}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7328 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":59.98,"y":-725.27,"x":1229.58},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-88.46087646484375,"y":-0.0,"x":-11.09668827056884}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7328 East Mirror Dr","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":59.82,"y":-696.93,"x":1223.0},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-81.23240661621094,"y":-0.0,"x":-17.37718200683593}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7328 Mirror Park Blvd","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":62.71,"y":-669.31,"x":1221.46},"furniture":[],"plysinside":[],"garage":{"enabled":false,"StoredVehicles":[]},"Owner":"","Price":40000,"setName":"","Keys":[],"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-164.38833618164066,"y":-0.0,"x":-11.55613040924072}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7333 Mirror Park Blvd","Interior":"mid-end"},{"Locked":false,"Owned":false,"Entrance":{"z":65.46,"y":-620.26,"x":1207.46},"furniture":[],"plysinside":[],"Price":40000,"Owner":"","Keys":[],"setName":"","garage":{"enabled":false,"StoredVehicles":[]},"cctv":{"maxleft":80,"maxright":-20,"enabled":false,"rot":{"z":-87.679443359375,"y":1.3399391818325056e-8,"x":-5.38702487945556}},"positions":{"Wardrobe":{"z":-99.14720153808594,"y":-994.2987060546876,"x":350.7424926757813}},"Name":"7336 Mirror Park Blvd","Interior":"mid-end"},{"Locked":false,"Price":40000,"Entrance":{"z":67.08,"y":-598.41,"x":1203.75},"furniture":[],"setName":"","Owned":false,"Owner":"","garage":{"enabled":false},"cctv":{"enabled":false,"maxright":-20,"maxleft":80,"rot":{"x":-16.58763313293457,"y":-0.0,"z":3.90023970603942}},"Keys":[],"Interior":"mid-end","positions":{"Storage":{"x":343.86859130859377,"y":-1001.140380859375,"z":-99.19619750976563},"Wardrobe":{"x":350.74249267578127,"y":-994.2987060546875,"z":-99.14720153808594}},"Name":"7338 Mirror Park Blvd","plysinside":[]},{"Locked":false,"Price":40000,"Entrance":{"z":68.16,"y":-575.59,"x":1201.01},"furniture":[],"setName":"","Owned":false,"Owner":"","garage":{"enabled":false},"cctv":{"enabled":false,"maxright":-20,"maxleft":80,"rot":{"x":-20.23956108093261,"y":9.099596240957908e-7,"z":-37.31895446777344}},"Keys":[],"Interior":"mid-end","positions":{"Storage":{"x":343.86859130859377,"y":-1001.140380859375,"z":-99.19619750976563},"Wardrobe":{"x":350.74249267578127,"y":-994.2987060546875,"z":-99.14720153808594}},"Name":"7338 Mirror Park Blvd","plysinside":[]}] \ No newline at end of file +[ + { + "cctv": { + "rot": { + "z": 2.7542073726654, + "y": 2.7045992112562097e-8, + "x": -9.43104267120361 + }, + "maxright": -88.02642059326172, + "enabled": true, + "maxleft": 90.71163940429688 + }, + "setName": "", + "Owned": false, + "Owner": "", + "Price": 25000, + "Locked": false, + "Name": "1076 Procopio Dr", + "Entrance": { + "z": 28.57, + "y": 6206.16, + "x": -467.88 + }, + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Interior": "low-end", + "OwnerName": "", + "plysinside": [], + "Keys": [], + "furniture": [], + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + } + }, + { + "cctv": { + "rot": { + "z": 162.9940643310547, + "y": -0.0, + "x": 3.75689458847045 + }, + "maxright": 70.65039825439453, + "enabled": true, + "maxleft": -113.61099243164064 + }, + "setName": "", + "Owned": false, + "Owner": "", + "Price": 25000, + "Locked": false, + "Name": "1075 Procopio Dr", + "Entrance": { + "z": 29.07, + "y": 6260.23, + "x": -448.02 + }, + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Interior": "low-end", + "OwnerName": "", + "plysinside": [], + "Keys": [], + "furniture": [], + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 27.96, + "y": 6314.13, + "x": -407.35 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1074 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -138.95835876464845, + "y": -0.0, + "x": -1.16786921024322 + }, + "maxright": 135.13072204589845, + "enabled": true, + "maxleft": -54.77568435668945 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 28.86, + "y": 6341.62, + "x": -368.23 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1073 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -139.94163513183598, + "y": -0.0, + "x": -2.56643605232238 + }, + "maxright": 132.70008850097657, + "enabled": true, + "maxleft": -51.56189727783203 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.52, + "y": 6400.88, + "x": -272.61 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1071 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -152.39810180664066, + "y": -0.0, + "x": -7.54235982894897 + }, + "maxright": 123.2501983642578, + "enabled": true, + "maxleft": -65.34387969970703 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.48, + "y": 6414.46, + "x": -246.14 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1071 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 128.27305603027345, + "y": 4.379791960218428e-7, + "x": -12.92249584197998 + }, + "maxright": 38.33782577514648, + "enabled": true, + "maxleft": -148.38644409179688 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.22, + "y": 6445.48, + "x": -229.63 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "1070 Procopio Dr", + "plysinside": [], + "Price": 27500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 137.8870849609375, + "y": 2.1444458297992242e-7, + "x": -5.53862285614013 + }, + "maxright": 48.30059432983398, + "enabled": true, + "maxleft": -135.48313903808598 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 28.89, + "y": 6551.76, + "x": -130.8 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "1067 Procopio Dr", + "plysinside": [], + "Price": 27500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -134.93411254882813, + "y": 1.0691521623584777e-7, + "x": 3.44796895980834 + }, + "maxright": 138.85032653808598, + "enabled": true, + "maxleft": -46.79578399658203 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.11, + "y": 6637.3, + "x": -41.72 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1065 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -144.0503692626953, + "y": -1.3340336835199196e-8, + "x": -0.24611411988735 + }, + "maxright": 129.07382202148438, + "enabled": true, + "maxleft": -56.39479827880859 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.72, + "y": 6654.13, + "x": -9.62 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1064 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -155.01153564453126, + "y": -1.068413766347477e-7, + "x": -2.71219563484191 + }, + "maxright": 116.67019653320313, + "enabled": true, + "maxleft": -68.07413482666016 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.86, + "y": 6207.33, + "x": -356.82 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1034 Paleto Blvd", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -133.8831787109375, + "y": -0.0, + "x": -2.77191710472106 + }, + "maxright": 135.7574005126953, + "enabled": true, + "maxleft": -45.94052505493164 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.87, + "y": 6252.75, + "x": -379.92 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1034 Procopio Dr", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -40.4444465637207, + "y": 4.32035335506953e-7, + "x": -8.85426330566406 + }, + "maxright": -131.2773895263672, + "enabled": true, + "maxleft": 42.09032440185547 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 31.91, + "y": 6326.99, + "x": -302.19 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1047 Paleto Blvd", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 44.16030502319336, + "y": -9.440947223993136e-7, + "x": -25.26673126220703 + }, + "maxright": -42.54082870483398, + "enabled": true, + "maxleft": 133.55870056152345 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 30.9, + "y": 6225.21, + "x": -347.3 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "1043 Paleto Blvd", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -137.5096435546875, + "y": -0.0, + "x": -1.57497417926788 + }, + "maxright": 134.7738800048828, + "enabled": true, + "maxleft": -43.60107040405273 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 32.26, + "y": 6557.45, + "x": -15.3 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "1059 Paleto Blvd", + "plysinside": [], + "Price": 25000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -45.87245941162109, + "y": -0.0, + "x": -11.80154037475586 + }, + "maxright": -133.83499145507813, + "enabled": true, + "maxleft": 43.89247512817383 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 32.1, + "y": 6568.19, + "x": 4.43 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "1061 Paleto Blvd", + "plysinside": [], + "Price": 27500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 129.4863433837891, + "y": 2.144746105159357e-7, + "x": -5.62087059020996 + }, + "maxright": 44.53319549560547, + "enabled": true, + "maxleft": -139.30752563476566 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 31.84, + "y": 6596.46, + "x": 31.0 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "1061 Paleto Blvd", + "plysinside": [], + "Price": 27500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -94.7632293701172, + "y": -0.0, + "x": -5.83577966690063 + }, + "maxright": -159.96804809570313, + "enabled": true, + "maxleft": -43.43285751342773 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 42.9, + "y": 4642.33, + "x": 1725.06 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "2016 Grapeseed Main St", + "plysinside": [], + "Price": 12500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -63.00457000732422, + "y": -0.0, + "x": -6.35934734344482 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 42.39, + "y": 4658.22, + "x": 1674.01 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "2015 Grapeseed Main St", + "plysinside": [], + "Price": 12500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 91.53390502929688, + "y": 2.7858778395284394e-8, + "x": -16.72389602661132 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 42.68, + "y": 4677.34, + "x": 1718.91 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "2014 Grapeseed Main St", + "plysinside": [], + "Price": 7500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -93.13695526123049, + "y": -0.0, + "x": -29.83987236022949 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 42.09, + "y": 4689.52, + "x": 1682.85 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "2013 Grapeseed Main St", + "plysinside": [], + "Price": 7500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 91.7155303955078, + "y": -0.0, + "x": -6.32857131958007 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 41.03, + "y": 4739.5, + "x": 1664.0 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "2011 Grapeseed Main St", + "plysinside": [], + "Price": 10000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 110.03758239746094, + "y": -0.0, + "x": -18.96443367004394 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 32.23, + "y": 3920.59, + "x": 1880.27 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "3012 Niland Ave", + "plysinside": [], + "Price": 10000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -77.30774688720703, + "y": -0.0, + "x": -14.36374378204345 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 32.48, + "y": 3914.59, + "x": 1846.06 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "3013 Niland Ave", + "plysinside": [], + "Price": 9000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 103.60260009765624, + "y": -2.1725810483985698e-7, + "x": -10.75266551971435 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 36.08, + "y": 3913.8, + "x": 1803.57 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "3013 Marina Dr", + "plysinside": [], + "Price": 11500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -76.59026336669922, + "y": -0.0, + "x": -20.23343658447265 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 33.45, + "y": 3657.13, + "x": 1435.31 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "3025 Lesbos Ln", + "plysinside": [], + "Price": 11500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 95.02767944335938, + "y": -0.0, + "x": -5.87784767150878 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 43.5, + "y": 2607.8, + "x": 471.15 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "4018 Route 68", + "plysinside": [], + "Price": 12500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -166.2356719970703, + "y": -0.0, + "x": -20.86568069458007 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "low-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 42.28, + "y": 3087.1, + "x": 181.03 + }, + "positions": { + "Wardrobe": { + "z": -99.00859832763672, + "y": -1003.45947265625, + "x": 259.9942932128906 + } + }, + "Name": "4013 Joshua Rd", + "plysinside": [], + "Price": 7500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -93.07178497314452, + "y": -0.0, + "x": -11.2086534500122 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 73.50999999999999, + "y": -593.38, + "x": 1386.22 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7340 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -127.72049713134766, + "y": -0.0, + "x": -9.48588275909423 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 73.52, + "y": -569.49, + "x": 1388.94 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7341 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -69.5700912475586, + "y": -0.0, + "x": -9.84068393707275 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 73.71, + "y": -555.82, + "x": 1373.19 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7341 Nikola Pl", + "plysinside": [], + "Price": 4500, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -114.24230194091796, + "y": -0.0, + "x": -12.52571487426757 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 73.72999999999999, + "y": -606.62, + "x": 1367.33 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7340 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -177.74884033203126, + "y": -0.0, + "x": -10.93433380126953 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 73.72, + "y": -597.26, + "x": 1341.64 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7339 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 62.37366104125976, + "y": -0.0, + "x": -17.39539337158203 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 72.91, + "y": -546.97, + "x": 1348.31 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7342 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -27.96370315551757, + "y": 4.342483350683324e-7, + "x": -10.56496334075927 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 72.27, + "y": -583.06, + "x": 1323.3 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7339 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 152.2796173095703, + "y": 4.441767487151084e-7, + "x": -16.03893852233886 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 71.46, + "y": -535.91, + "x": 1328.57 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7342 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -111.59012603759766, + "y": -0.00000144736395, + "x": -53.85140228271484 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 70.75, + "y": -574.08, + "x": 1301.02 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7339 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 164.71957397460938, + "y": 4.6078031346041828e-7, + "x": -22.11302947998047 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 70.47999999999999, + "y": -527.3, + "x": 1303.1 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7342 Nikola Pl", + "plysinside": [], + "Price": 45000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -19.26140213012695, + "y": 4.363083689895575e-7, + "x": -11.92860603332519 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "cctv": { + "rot": { + "z": 125.62109375, + "y": -0.0, + "x": -58.0705451965332 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + }, + "setName": "", + "Owned": true, + "Owner": "char1:4da15f5fc4b8fa838372ac19665a1a11b82c4c74", + "Price": 40000, + "Locked": false, + "Name": "7322 West Mirror Drive", + "Entrance": { + "z": 56.84, + "y": -729.5, + "x": 996.89 + }, + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Interior": "mid-end", + "OwnerName": "Jhonatha Dinozzo", + "plysinside": [], + "Keys": [], + "furniture": [], + "positions": { + "Storage": { + "z": -99.2, + "y": -1008.07, + "x": 348.37 + }, + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.24, + "y": -716.31, + "x": 979.11 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7320 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 131.13587951660157, + "y": -0.0, + "x": -15.06083393096923 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.5, + "y": -701.3, + "x": 970.88 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7320 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 170.76788330078126, + "y": 3.3350637806961464e-9, + "x": -0.14884614944458 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.47, + "y": -669.85, + "x": 960.15 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7319 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 115.8887939453125, + "y": 4.346124455878453e-7, + "x": -10.81925582885742 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.45, + "y": -653.51, + "x": 943.45 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7319 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 38.34314727783203, + "y": 0.00000168464464, + "x": -59.54927444458008 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 58.26, + "y": -627.65, + "x": 980.25 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7318 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -144.15000915527345, + "y": -0.0, + "x": -36.16230392456055 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.26, + "y": -639.71, + "x": 928.82 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7317 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 137.4777984619141, + "y": -0.0, + "x": -15.65773868560791 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.47, + "y": -615.51, + "x": 902.95 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7317 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 46.20460510253906, + "y": -0.00000160100864, + "x": -57.77318572998047 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.47, + "y": -608.21, + "x": 886.77 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7316 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 138.07872009277345, + "y": -8.718344588487525e-7, + "x": -11.68268966674804 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.18, + "y": -583.65, + "x": 861.7 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7316 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -176.59844970703126, + "y": -0.0, + "x": -3.38041257858276 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.01, + "y": -562.66, + "x": 844.12 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7312 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 12.50613498687744, + "y": -2.1754524937023245e-7, + "x": -11.14390087127685 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 56.95, + "y": -532.68, + "x": 850.25 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7314 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 85.02394104003906, + "y": -5.362977262279856e-8, + "x": -5.74017667770385 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 56.74, + "y": -508.98, + "x": 861.51 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7313 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 46.49221038818359, + "y": 0.00000154111978, + "x": -56.35844421386719 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.11000000000001, + "y": -497.87, + "x": 878.44 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7313 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 44.91729354858398, + "y": -0.0, + "x": -64.80823516845703 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 58.46, + "y": -489.76, + "x": 906.46 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7311 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 19.29909515380859, + "y": -0.0, + "x": -14.44456386566162 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 60.1, + "y": -477.8, + "x": 921.78 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7311 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -8.25692367553711, + "y": -0.0, + "x": -19.33738899230957 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 60.57, + "y": -463.17, + "x": 944.54 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7309 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -55.23443603515625, + "y": -8.953837777880835e-7, + "x": -17.53591918945312 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 61.81, + "y": -451.65, + "x": 967.16 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7309 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 33.32376480102539, + "y": 8.936335120779404e-7, + "x": -17.17726707458496 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 63.06000000000001, + "y": -433.03, + "x": 987.57 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7307 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 34.80197525024414, + "y": 8.771137913754501e-7, + "x": -13.24740600585937 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 64.36999999999999, + "y": -423.38, + "x": 1010.38 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7307 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 123.14452362060549, + "y": -4.402644719903037e-7, + "x": -14.16050624847412 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 65.36, + "y": -408.36, + "x": 1028.78 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7305 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 41.270263671875, + "y": -4.386202476780454e-7, + "x": -13.28245830535888 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 67.25, + "y": -378.13, + "x": 1060.52 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7305 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 54.3464241027832, + "y": -8.817532943794504e-7, + "x": -14.47243404388427 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 63.52, + "y": -469.3, + "x": 1014.67 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7306 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -144.52737426757813, + "y": -9.047982416632294e-7, + "x": -19.33366966247558 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 61.16, + "y": -502.36, + "x": 970.55 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7308 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -107.44925689697266, + "y": -0.0, + "x": -8.07564449310302 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 59.64, + "y": -518.94, + "x": 945.9 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7310 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 119.70294189453124, + "y": -0.0, + "x": -61.49639892578125 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 58.81, + "y": -526.05, + "x": 924.39 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7312 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -151.43536376953126, + "y": -0.0, + "x": -17.66978073120117 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.53, + "y": -540.58, + "x": 893.24 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7312 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -69.45809936523438, + "y": -9.24586970540986e-7, + "x": -22.57007217407226 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 57.39, + "y": -569.56, + "x": 919.7 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7312 Nikola Ave", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 28.74713134765625, + "y": 4.412431167111208e-7, + "x": -14.65564727783203 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 58.75, + "y": -541.93, + "x": 965.25 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7310 Nikola Ave", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 32.70853805541992, + "y": -4.381802227726439e-7, + "x": -13.03651428222656 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 59.71, + "y": -525.76, + "x": 987.84 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7310 Nikola Ave", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 30.89822769165039, + "y": 9.366781910102872e-7, + "x": -24.28778457641601 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 60.01, + "y": -510.98, + "x": 1006.48 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7308 Nikola Ave", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -65.29899597167969, + "y": -0.0, + "x": -16.08703422546386 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 63.1, + "y": -498.06, + "x": 1046.29 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7306 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 144.13137817382813, + "y": 9.091479000744585e-7, + "x": -20.10037040710449 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 63.32, + "y": -470.58, + "x": 1051.04 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7306 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 76.4620132446289, + "y": -0.0, + "x": -11.98972129821777 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 65.28, + "y": -448.93, + "x": 1056.24 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7306 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 162.82366943359376, + "y": -0.0, + "x": -8.78071689605712 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 64.67999999999999, + "y": -484.37, + "x": 1090.46 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7344 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -102.9858856201172, + "y": -4.4310172597761268e-7, + "x": -15.54805183410644 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 66.33999999999999, + "y": -464.52, + "x": 1098.58 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7346 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -15.62946987152099, + "y": 2.17306606487e-7, + "x": -10.81984233856201 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 66.81, + "y": -438.69, + "x": 1099.44 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7346 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 179.49822998046876, + "y": -0.0, + "x": -11.32894706726074 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 66.58, + "y": -411.33, + "x": 1101.06 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7348 Bridge St", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -93.88529205322266, + "y": -5.391471091797939e-8, + "x": -8.21971225738525 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 67.97, + "y": -391.27, + "x": 1114.44 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7348 West Mirror Drive", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -112.49811553955078, + "y": -0.0, + "x": -24.5419979095459 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 69.03999999999999, + "y": -429.86, + "x": 1262.35 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7345 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 112.37248229980468, + "y": -2.144359569911103e-7, + "x": -5.51487922668457 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 69.53999999999999, + "y": -458.06, + "x": 1265.74 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7945 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 94.98734283447266, + "y": -0.0, + "x": -14.86165904998779 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 69.21, + "y": -480.18, + "x": 1259.51 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7343 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 125.15465545654296, + "y": -0.0, + "x": -10.50986766815185 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 68.92999999999999, + "y": -494.1, + "x": 1251.53 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7343 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 63.34117126464844, + "y": -0.0, + "x": -16.31183433532715 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 68.36999999999999, + "y": -515.5, + "x": 1250.9 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7343 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 77.79755401611328, + "y": -0.0, + "x": -17.28229522705078 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 68.67999999999999, + "y": -566.43, + "x": 1241.53 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7338 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 130.3302459716797, + "y": -0.0, + "x": -22.43321228027343 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 68.8, + "y": -601.65, + "x": 1240.54 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7338 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 91.53223419189452, + "y": -1.3435412782314417e-8, + "x": -6.82489442825317 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "cctv": { + "rot": { + "z": 27.77294158935547, + "y": -2.145688853261163e-7, + "x": -5.87094974517822 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + }, + "setName": "", + "Owned": false, + "Owner": "", + "Price": 40000, + "Locked": false, + "Name": "7336 East Mirror Dr", + "Entrance": { + "z": 68.58999999999999, + "y": -620.99, + "x": 1250.79 + }, + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Interior": "mid-end", + "OwnerName": "", + "plysinside": [], + "Keys": [], + "furniture": [], + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 67.14, + "y": -648.63, + "x": 1265.69 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7333 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -152.5341949462891, + "y": -0.0, + "x": -14.65502071380615 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 65.05, + "y": -683.53, + "x": 1270.98 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7333 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -171.3050994873047, + "y": -0.0, + "x": -12.5356969833374 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 63.93, + "y": -702.82, + "x": 1264.75 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7328 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 58.4541015625, + "y": 0.00000175048376, + "x": -12.71638584136962 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 59.98, + "y": -725.27, + "x": 1229.58 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7328 East Mirror Dr", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -88.46087646484375, + "y": -0.0, + "x": -11.09668827056884 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 59.82, + "y": -696.93, + "x": 1223.0 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7328 Mirror Park Blvd", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -81.23240661621094, + "y": -0.0, + "x": -17.37718200683593 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 62.71, + "y": -669.31, + "x": 1221.46 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7333 Mirror Park Blvd", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -164.38833618164066, + "y": -0.0, + "x": -11.55613040924072 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 65.46, + "y": -620.26, + "x": 1207.46 + }, + "positions": { + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7336 Mirror Park Blvd", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -87.679443359375, + "y": 1.3399391818325056e-8, + "x": -5.38702487945556 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 67.08, + "y": -598.41, + "x": 1203.75 + }, + "positions": { + "Storage": { + "z": -99.19619750976564, + "y": -1001.140380859375, + "x": 343.86859130859377 + }, + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7338 Mirror Park Blvd", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": 3.90023970603942, + "y": -0.0, + "x": -16.58763313293457 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + }, + { + "Interior": "mid-end", + "Owned": false, + "setName": "", + "garage": { + "StoredVehicles": [], + "enabled": false + }, + "Owner": "", + "Locked": false, + "Entrance": { + "z": 68.16, + "y": -575.59, + "x": 1201.01 + }, + "positions": { + "Storage": { + "z": -99.19619750976564, + "y": -1001.140380859375, + "x": 343.86859130859377 + }, + "Wardrobe": { + "z": -99.14720153808594, + "y": -994.2987060546876, + "x": 350.7424926757813 + } + }, + "Name": "7338 Mirror Park Blvd", + "plysinside": [], + "Price": 40000, + "Keys": [], + "furniture": [], + "cctv": { + "rot": { + "z": -37.31895446777344, + "y": 9.099596240957908e-7, + "x": -20.23956108093261 + }, + "maxright": -20, + "enabled": false, + "maxleft": 80 + } + } +] \ No newline at end of file diff --git a/server-data/resources/[esx_addons]/esx_property/server/main.lua b/server-data/resources/[esx_addons]/esx_property/server/main.lua index d340f9cc3..a379d3813 100644 --- a/server-data/resources/[esx_addons]/esx_property/server/main.lua +++ b/server-data/resources/[esx_addons]/esx_property/server/main.lua @@ -1,1170 +1,1304 @@ local function Log(title, color, fields, Level) - if Level <= Config.Logs.LogLevel then - local webHook = Config.Logs.Webhook - local embedData = {{ - ['title'] = title, ['color'] = color, ['footer'] = {['text'] = "ESX-Property | " .. os.date(), - ['icon_url'] = 'https://cdn.discordapp.com/attachments/944789399852417096/1004915039414788116/imageedit_1_2564956129.png'}, - ['fields'] = fields, ['description'] = "", ['author'] = {['name'] = "ESX-Framework | Log Level " .. Level, - ['icon_url'] = 'https://cdn.discordapp.com/emojis/939245183621558362.webp?size=128&quality=lossless'}}} - PerformHttpRequest(webHook, function() - end, 'POST', json.encode({username = 'ESX-Framework', embeds = embedData}), {['Content-Type'] = 'application/json'}) - end + if Level <= Config.Logs.LogLevel then + local webHook = Config.Logs.Webhook + local embedData = { + { + ["title"] = title, + ["color"] = color, + ["footer"] = { ["text"] = "ESX-Property | " .. os.date(), ["icon_url"] = "https://cdn.discordapp.com/attachments/944789399852417096/1004915039414788116/imageedit_1_2564956129.png" }, + ["fields"] = fields, + ["description"] = "", + ["author"] = { ["name"] = "ESX-Framework | Log Level " .. Level, ["icon_url"] = "https://cdn.discordapp.com/emojis/939245183621558362.webp?size=128&quality=lossless" }, + }, + } + PerformHttpRequest(webHook, function() end, "POST", json.encode({ username = "ESX-Framework", embeds = embedData }), { ["Content-Type"] = "application/json" }) + end end local PM = Config.PlayerManagement local Properties = {} function PropertiesRefresh() - Properties = {} - local PropertiesList = LoadResourceFile(GetCurrentResourceName(), 'properties.json') - if PropertiesList then - Properties = json.decode(PropertiesList) - Wait(10) - for i = 1, #Properties do - if not Properties[i].furniture then - Properties[i].furniture = {} - end - if not Properties[i].cctv then - Properties[i].cctv = {enabled = false} - end - if not Properties[i].garage then - Properties[i].garage = {enabled = false} - end - if not Properties[i].garage.StoredVehicles then - Properties[i].garage.StoredVehicles = {} - end - if not Properties[i].setName then - Properties[i].setName = "" - end - if not Properties[i].positions then - local Interior = GetInteriorValues(Properties[i].Interior) - Properties[i].positions = Interior.positions - end - Properties[i].plysinside = {} - if Config.OxInventory then - if Properties[i].Owned then - exports.ox_inventory:RegisterStash("property-" .. i, Properties[i].Name, 15, 100000, Properties[i].Owner) + Properties = {} + local PropertiesList = LoadResourceFile(GetCurrentResourceName(), "properties.json") + if PropertiesList then + Properties = json.decode(PropertiesList) + Wait(10) + for i = 1, #Properties do + if not Properties[i].furniture then + Properties[i].furniture = {} + end + if not Properties[i].cctv then + Properties[i].cctv = { enabled = false } + end + if not Properties[i].garage then + Properties[i].garage = { enabled = false } + end + if not Properties[i].garage.StoredVehicles then + Properties[i].garage.StoredVehicles = {} + end + if not Properties[i].setName then + Properties[i].setName = "" + end + if not Properties[i].positions then + local Interior = GetInteriorValues(Properties[i].Interior) + Properties[i].positions = Interior.positions + end + Properties[i].plysinside = {} + if Config.OxInventory then + if Properties[i].Owned then + exports.ox_inventory:RegisterStash("property-" .. i, Properties[i].Name, 15, 100000, Properties[i].Owner) + end + else + Properties[i].positions.Storage = nil + end end - else - Properties[i].positions.Storage = nil - end - end - local Players = ESX.GetExtendedPlayers() - Log("ESX-Property Loaded", 11141375, {{name = "Property Count", value = #Properties, inline = true}, - {name = "OX Inventory", value = Config.OxInventory and "Enabled" or "Disabled", inline = true}}, 1) - for _, xPlayer in pairs(Players) do - TriggerClientEvent("esx_property:syncProperties", xPlayer.source, Properties, xPlayer.get("lastProperty")) + local Players = ESX.GetExtendedPlayers() + Log("ESX-Property Loaded", 11141375, { { name = "Property Count", value = #Properties, inline = true }, { name = "OX Inventory", value = Config.OxInventory and "Enabled" or "Disabled", inline = true } }, 1) + for _, xPlayer in pairs(Players) do + TriggerClientEvent("esx_property:syncProperties", xPlayer.source, Properties, xPlayer.get("lastProperty")) + end + else + Properties = {} + print("[^1ERROR^7]: ^5Properties.json^7 Not Found!") end - else - Properties = {} - print("[^1ERROR^7]: ^5Properties.json^7 Not Found!") - end end function IsPlayerAdmin(player, action) - local xPlayer = ESX.GetPlayerFromId(player) + local xPlayer = ESX.GetPlayerFromId(player) - for i = 1, #Config.AllowedGroups do - if xPlayer.group == Config.AllowedGroups[i] then - return true + for i = 1, #Config.AllowedGroups do + if xPlayer.group == Config.AllowedGroups[i] then + return true + end end - end - if Config.PlayerManagement.Enabled and action then - if xPlayer.job.name == Config.PlayerManagement.job and xPlayer.job.grade >= Config.PlayerManagement.Permissions[action] then - return true + if Config.PlayerManagement.Enabled and action then + if xPlayer.job.name == Config.PlayerManagement.job and xPlayer.job.grade >= Config.PlayerManagement.Permissions[action] then + return true + end end - end - return false + return false end CreateThread(function() - Wait(3000) - PropertiesRefresh() - MySQL.query("ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `last_property` LONGTEXT NULL", function(result) - if result then - print("[^2INFO^7] Adding ^5last_property^7 column to users table") - end - end) - MySQL.insert("INSERT IGNORE INTO `datastore` (name, label, shared) VALUES ('property', 'Property' , 1)", function(result) - if result then - print("[^2INFO^7] Adding ^5Property^7 into ^5datastore^7 table") - end - end) - MySQL.insert("INSERT IGNORE INTO `datastore_data` (name, owner, data) VALUES ('property', NULL, '{}')", function(result) - if result then - print("[^2INFO^7] Adding ^5Property^7 into ^5datastore_data^7 table") - end - end) - if PM.Enabled then - MySQL.insert("INSERT IGNORE INTO `addon_account` (name, label, shared) VALUES (?, ? , 1)", {PM.society, PM.joblabel}, function(result) - if result then - print("[^2INFO^7] Adding ^5" .. PM.society .. " - " .. PM.joblabel .. "^7 into ^5addon_account^7 table") - end + Wait(3000) + PropertiesRefresh() + MySQL.query("ALTER TABLE `users` ADD COLUMN IF NOT EXISTS `last_property` LONGTEXT NULL", function(result) + if result then + print("[^2INFO^7] Adding ^5last_property^7 column to users table") + end end) - local Existance = ESX.DoesJobExist(PM.job, 0) - if not Existance then - MySQL.query("INSERT INTO `jobs` VALUES (?, ?, 1)", {PM.job, PM.joblabel}, function(result) + MySQL.insert("INSERT IGNORE INTO `datastore` (name, label, shared) VALUES ('property', 'Property' , 1)", function(result) if result then - print("[^2INFO^7] Inserting ^5" .. PM.job .. " - " .. PM.joblabel .. "^7 into ^5jobs^7 table") + print("[^2INFO^7] Adding ^5Property^7 into ^5datastore^7 table") end - end) - end - for i = 1, #PM.jobRanks do - local Existance = ESX.DoesJobExist(PM.job, PM.jobRanks[i].grade) - if not Existance then - MySQL.query("INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?,?, ?, ?,'{}','{}')", - {PM.job, PM.jobRanks[i].grade, PM.jobRanks[i].name, PM.jobRanks[i].label, PM.jobRanks[i].salary}, function(result) + end) + MySQL.insert("INSERT IGNORE INTO `datastore_data` (name, owner, data) VALUES ('property', NULL, '{}')", function(result) + if result then + print("[^2INFO^7] Adding ^5Property^7 into ^5datastore_data^7 table") + end + end) + if PM.Enabled then + MySQL.insert("INSERT IGNORE INTO `addon_account` (name, label, shared) VALUES (?, ? , 1)", { PM.society, PM.joblabel }, function(result) if result then - print("[^2INFO^7] Inserting ^5" .. PM.job .. " - " .. PM.jobRanks[i].grade .. " - " .. PM.jobRanks[i].label .. - "^7 into ^5job_grades^7 table") + print("[^2INFO^7] Adding ^5" .. PM.society .. " - " .. PM.joblabel .. "^7 into ^5addon_account^7 table") end - end) - end + end) + local Existance = ESX.DoesJobExist(PM.job, 0) + if not Existance then + MySQL.query("INSERT INTO `jobs` VALUES (?, ?, 1)", { PM.job, PM.joblabel }, function(result) + if result then + print("[^2INFO^7] Inserting ^5" .. PM.job .. " - " .. PM.joblabel .. "^7 into ^5jobs^7 table") + end + end) + end + for i = 1, #PM.jobRanks do + local Existance = ESX.DoesJobExist(PM.job, PM.jobRanks[i].grade) + if not Existance then + MySQL.query("INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_female) VALUES (?, ?,?, ?, ?,'{}','{}')", { PM.job, PM.jobRanks[i].grade, PM.jobRanks[i].name, PM.jobRanks[i].label, PM.jobRanks[i].salary }, function(result) + if result then + print("[^2INFO^7] Inserting ^5" .. PM.job .. " - " .. PM.jobRanks[i].grade .. " - " .. PM.jobRanks[i].label .. "^7 into ^5job_grades^7 table") + end + end) + end + end + Wait(10) + ESX.RefreshJobs() + TriggerEvent("esx_society:registerSociety", "realestateagent", "realestateagent", "society_realestateagent", "society_realestateagent", "society_realestateagent", { type = "private" }) end - Wait(10) - ESX.RefreshJobs() - TriggerEvent('esx_society:registerSociety', 'realestateagent', 'realestateagent', 'society_realestateagent', 'society_realestateagent', - 'society_realestateagent', {type = 'private'}) - end end) AddEventHandler("esx:playerLoaded", function(playerId, xPlayer) - Wait(1000) - local lastProperty = nil - MySQL.query("SELECT last_property FROM users WHERE identifier = ?", {xPlayer.identifier}, function(result) - if result then - if result[1].last_property then - local Data = json.decode(result[1].last_property) - xPlayer.set("lastProperty", Data) - lastProperty = Data - end - end - TriggerClientEvent("esx_property:syncProperties", playerId, Properties, lastProperty) - end) + Wait(1000) + local lastProperty = nil + MySQL.query("SELECT last_property FROM users WHERE identifier = ?", { xPlayer.identifier }, function(result) + if result then + if result[1].last_property then + local Data = json.decode(result[1].last_property) + xPlayer.set("lastProperty", Data) + lastProperty = Data + end + end + TriggerClientEvent("esx_property:syncProperties", playerId, Properties, lastProperty) + end) end) --- Commands ESX.RegisterCommand(_U("refresh_name"), Config.AllowedGroups, function() - PropertiesRefresh() -end, false, {help = _U("refresh_desc")}) + PropertiesRefresh() +end, false, { help = _U("refresh_desc") }) ESX.RegisterCommand(_U("create_name"), "user", function(xPlayer) - if IsPlayerAdmin(xPlayer.source) or (PM.Enabled and xPlayer.job.name == PM.job) then - xPlayer.triggerEvent("esx_property:CreateProperty") - end -end, false,{help = _U("create_desc")}) + if IsPlayerAdmin(xPlayer.source) or (PM.Enabled and xPlayer.job.name == PM.job) then + xPlayer.triggerEvent("esx_property:CreateProperty") + end +end, false, { help = _U("create_desc") }) ESX.RegisterCommand(_("admin_name"), Config.AllowedGroups, function(xPlayer) - xPlayer.triggerEvent("esx_property:AdminMenu") -end, false,{help = _U("admin_desc")}) + xPlayer.triggerEvent("esx_property:AdminMenu") +end, false, { help = _U("admin_desc") }) -- Buy Property ESX.RegisterServerCallback("esx_property:buyProperty", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Price = Properties[PropertyId].Price - if xPlayer.getAccount("bank").money >= Price then - xPlayer.removeAccountMoney("bank", Price, "Bought Property") - Properties[PropertyId].Owner = xPlayer.identifier - Properties[PropertyId].OwnerName = xPlayer.getName() - Properties[PropertyId].Owned = true - Log("Property Bought", 65280, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}}, 1) - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - if Config.OxInventory then - exports.ox_inventory:RegisterStash("property-" .. PropertyId, Properties[PropertyId].Name, 15, 100000, xPlayer.identifier) + local xPlayer = ESX.GetPlayerFromId(source) + local Price = Properties[PropertyId].Price + if xPlayer.getAccount("bank").money >= Price then + xPlayer.removeAccountMoney("bank", Price, "Bought Property") + Properties[PropertyId].Owner = xPlayer.identifier + Properties[PropertyId].OwnerName = xPlayer.getName() + Properties[PropertyId].Owned = true + Log("Property Bought", 65280, { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + }, 1) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + if Config.OxInventory then + exports.ox_inventory:RegisterStash("property-" .. PropertyId, Properties[PropertyId].Name, 15, 100000, xPlayer.identifier) + end end - end - cb(xPlayer.getAccount("bank").money >= Price) + cb(xPlayer.getAccount("bank").money >= Price) end) ESX.RegisterServerCallback("esx_property:attemptSellToPlayer", function(source, cb, PropertyId, PlayerId) - local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromId(PlayerId) - local Price = Properties[PropertyId].Price - if xTarget and (xTarget.getAccount("bank").money >= Price) and (xPlayer.job.name == PM.job) then - xTarget.removeAccountMoney("bank", Price, "Sold Property") - Properties[PropertyId].Owner = xTarget.identifier - Properties[PropertyId].OwnerName = xTarget.getName() - Properties[PropertyId].Owned = true - Log("Property Sold To Player", 65280, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true}, - {name = "**Player**", value = xTarget.getName(), inline = true}, - {name = "**Agent**", value = xPlayer.getName(), inline = true}}, 1) - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - if Config.OxInventory then - exports.ox_inventory:RegisterStash("property-" .. PropertyId, Properties[PropertyId].Name, 15, 100000, xTarget.identifier) - end - if PM.Enabled then - local PlayerPrice = Price * PM.SalePercentage - local SocietyPrice = Price - PlayerPrice - TriggerEvent('esx_addonaccount:getSharedAccount', PM.society, function(account) - account.addMoney(SocietyPrice) - end) - xPlayer.addAccountMoney("bank", PlayerPrice, "Sold Property") + local xPlayer = ESX.GetPlayerFromId(source) + local xTarget = ESX.GetPlayerFromId(PlayerId) + local Price = Properties[PropertyId].Price + if xTarget and (xTarget.getAccount("bank").money >= Price) and (xPlayer.job.name == PM.job) then + xTarget.removeAccountMoney("bank", Price, "Sold Property") + Properties[PropertyId].Owner = xTarget.identifier + Properties[PropertyId].OwnerName = xTarget.getName() + Properties[PropertyId].Owned = true + Log( + "Property Sold To Player", + 65280, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true }, + { name = "**Player**", value = xTarget.getName(), inline = true }, + { name = "**Agent**", value = xPlayer.getName(), inline = true }, + }, + 1 + ) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + if Config.OxInventory then + exports.ox_inventory:RegisterStash("property-" .. PropertyId, Properties[PropertyId].Name, 15, 100000, xTarget.identifier) + end + if PM.Enabled then + local PlayerPrice = Price * PM.SalePercentage + local SocietyPrice = Price - PlayerPrice + TriggerEvent("esx_addonaccount:getSharedAccount", PM.society, function(account) + account.addMoney(SocietyPrice) + end) + xPlayer.addAccountMoney("bank", PlayerPrice, "Sold Property") + end end - end - cb(xPlayer.getAccount("bank").money >= Price) + cb(xPlayer.getAccount("bank").money >= Price) end) -- Buy Property ESX.RegisterServerCallback("esx_property:buyFurniture", function(source, cb, PropertyId, PropName, PropIndex, PropCatagory, pos, heading) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - local Price = Config.FurnitureCatagories[PropCatagory][PropIndex].price - if xPlayer.getAccount("bank").money >= Price then - xPlayer.removeAccountMoney("bank", Price, "Furniture") - cb(true) - local furniture = {Name = PropName, Index = PropIndex, Catagory = PropCatagory, Pos = pos, Heading = heading, Price = Price} - table.insert(Properties[PropertyId].furniture, furniture) - for i = 1, #Properties[PropertyId].plysinside do - TriggerClientEvent("esx_property:placeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furniture, - #Properties[PropertyId].furniture) - end - TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + local Price = Config.FurnitureCatagories[PropCatagory][PropIndex].price + if xPlayer.getAccount("bank").money >= Price then + xPlayer.removeAccountMoney("bank", Price, "Furniture") + cb(true) + local furniture = { Name = PropName, Index = PropIndex, Catagory = PropCatagory, Pos = pos, Heading = heading, Price = Price } + table.insert(Properties[PropertyId].furniture, furniture) + for i = 1, #Properties[PropertyId].plysinside do + TriggerClientEvent("esx_property:placeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furniture, #Properties[PropertyId].furniture) + end + TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) + else + cb(false) + ESX.ShowNotification(_U("furni_cannot_afford")) + end else - cb(false) - ESX.ShowNotification(_U("furni_cannot_afford")) + cb(false) end - else - cb(false) - end - Log("Furniture Bought", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, {name = "**Has Access**", - value = (xPlayer.identifier == Owner or IsPlayerAdmin(source) or - (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", inline = true}, - {name = "**Prop Name**", value = Config.FurnitureCatagories[PropCatagory][PropIndex].title, inline = true}, - {name = "**Price**", value = tostring(Config.FurnitureCatagories[PropCatagory][PropIndex].price), inline = true}, - {name = "**Can Afford**", - value = xPlayer.getAccount("bank").money >= Config.FurnitureCatagories[PropCatagory][PropIndex].price and "Yes" or "No", inline = true}}, 1) + Log( + "Furniture Bought", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { name = "**Has Access**", value = (xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", inline = true }, + { name = "**Prop Name**", value = Config.FurnitureCatagories[PropCatagory][PropIndex].title, inline = true }, + { name = "**Price**", value = tostring(Config.FurnitureCatagories[PropCatagory][PropIndex].price), inline = true }, + { name = "**Can Afford**", value = xPlayer.getAccount("bank").money >= Config.FurnitureCatagories[PropCatagory][PropIndex].price and "Yes" or "No", inline = true }, + }, + 1 + ) end) -- Selling Property ESX.RegisterServerCallback("esx_property:sellProperty", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner then - local Price = ESX.Math.Round(Properties[PropertyId].Price * 0.6) - xPlayer.addAccountMoney("bank", Price, "Sold Property") - Properties[PropertyId].Owner = "" - Properties[PropertyId].OwnerName = "" - Properties[PropertyId].Owned = false - Properties[PropertyId].Locked = false - Properties[PropertyId].Keys = {} - local furn = #(Properties[PropertyId].furniture) - if Config.WipeFurnitureOnSell then - Properties[PropertyId].furniture = {} - end - if Config.WipeCustomNameOnSell then - Properties[PropertyId].setName = "" - end - Properties[PropertyId].plysinside = {} - Log("Property Sold", 16711680, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true}, - {name = "**Owner**", value = xPlayer.getName(), inline = true}, - {name = "**Furniture Count**", value = tostring(furn), inline = true}, - {name = "**Vehicle Count**", value = tostring(Properties[PropertyId].garage.StoredVehicles and #Properties[PropertyId].garage.StoredVehicles or "N/A"), inline = true}}, 1) - if Properties[PropertyId].garage.StoredVehicles then - Properties[PropertyId].garage.StoredVehicles = {} - end - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - if Config.OxInventory then - exports.ox_inventory:ClearInventory("property-" .. PropertyId) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner then + local Price = ESX.Math.Round(Properties[PropertyId].Price * 0.6) + xPlayer.addAccountMoney("bank", Price, "Sold Property") + Properties[PropertyId].Owner = "" + Properties[PropertyId].OwnerName = "" + Properties[PropertyId].Owned = false + Properties[PropertyId].Locked = false + Properties[PropertyId].Keys = {} + local furn = #Properties[PropertyId].furniture + if Config.WipeFurnitureOnSell then + Properties[PropertyId].furniture = {} + end + if Config.WipeCustomNameOnSell then + Properties[PropertyId].setName = "" + end + Properties[PropertyId].plysinside = {} + Log( + "Property Sold", + 16711680, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Price**", value = ESX.Math.GroupDigits(Price), inline = true }, + { name = "**Owner**", value = xPlayer.getName(), inline = true }, + { name = "**Furniture Count**", value = tostring(furn), inline = true }, + { name = "**Vehicle Count**", value = tostring(Properties[PropertyId].garage.StoredVehicles and #Properties[PropertyId].garage.StoredVehicles or "N/A"), inline = true }, + }, + 1 + ) + if Properties[PropertyId].garage.StoredVehicles then + Properties[PropertyId].garage.StoredVehicles = {} + end + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + if Config.OxInventory then + exports.ox_inventory:ClearInventory("property-" .. PropertyId) + end end - end - cb(xPlayer.identifier == Owner) + cb(xPlayer.identifier == Owner) end) -- Admin Menu Options ESX.RegisterServerCallback("esx_property:toggleLock", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner or IsPlayerAdmin(source, "ToggleLock") or - (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - Properties[PropertyId].Locked = not Properties[PropertyId].Locked - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - end - Log("Lock Toggled", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Executing User**", value = xPlayer.getName(), inline = true}, - {name = "**Status**", value = Properties[PropertyId].Locked and "Locked" or "Unlocked", inline = true}}, 3) - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source, "ToggleLock") or - (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner or IsPlayerAdmin(source, "ToggleLock") or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + Properties[PropertyId].Locked = not Properties[PropertyId].Locked + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + end + Log( + "Lock Toggled", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Executing User**", value = xPlayer.getName(), inline = true }, + { name = "**Status**", value = Properties[PropertyId].Locked and "Locked" or "Unlocked", inline = true }, + }, + 3 + ) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source, "ToggleLock") or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:toggleGarage", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ToggleGarage") then - Properties[PropertyId].garage.enabled = not Properties[PropertyId].garage.enabled - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Garage Toggled", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Status**", value = Properties[PropertyId].garage.enabled and "Enabled" or "Disabled", - inline = true}}, 2) - cb(true, Properties[PropertyId].garage.enabled) - else - cb(false) - end + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ToggleGarage") then + Properties[PropertyId].garage.enabled = not Properties[PropertyId].garage.enabled + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Garage Toggled", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Status**", value = Properties[PropertyId].garage.enabled and "Enabled" or "Disabled", inline = true }, + }, + 2 + ) + cb(true, Properties[PropertyId].garage.enabled) + else + cb(false) + end end) ESX.RegisterServerCallback("esx_property:toggleCCTV", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ToggleCCTV") then - Properties[PropertyId].cctv.enabled = not Properties[PropertyId].cctv.enabled - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - cb(true, Properties[PropertyId].cctv.enabled) - Log("Property CCTV Toggled", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Status**", value = Properties[PropertyId].cctv.enabled and "Enabled" or "Disabled", - inline = true}}, 2) - else - cb(false) - end + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ToggleCCTV") then + Properties[PropertyId].cctv.enabled = not Properties[PropertyId].cctv.enabled + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + cb(true, Properties[PropertyId].cctv.enabled) + Log( + "Property CCTV Toggled", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Status**", value = Properties[PropertyId].cctv.enabled and "Enabled" or "Disabled", inline = true }, + }, + 2 + ) + else + cb(false) + end end) ESX.RegisterServerCallback("esx_property:SetGaragePos", function(source, cb, PropertyId, heading) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ToggleGarage") then - local PlayerPed = GetPlayerPed(source) - local PlayerPos = GetEntityCoords(PlayerPed) - local Property = Properties[PropertyId] - local Original = Properties[PropertyId].garage.pos and Properties[PropertyId].garage.pos.x .. ", " .. Properties[PropertyId].garage.pos.y .. ", " .. Properties[PropertyId].garage.pos.z or "N/A" - Properties[PropertyId].garage.pos = PlayerPos - Properties[PropertyId].garage.Heading = heading - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Garage Location Changed", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Original Position**", value = tostring(Original), inline = true}, - {name = "**New Position**", value = tostring(PlayerPos), inline = true}}, 2) - cb(true) - else - cb(false) - end + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ToggleGarage") then + local PlayerPed = GetPlayerPed(source) + local PlayerPos = GetEntityCoords(PlayerPed) + local Property = Properties[PropertyId] + local Original = Properties[PropertyId].garage.pos and Properties[PropertyId].garage.pos.x .. ", " .. Properties[PropertyId].garage.pos.y .. ", " .. Properties[PropertyId].garage.pos.z or "N/A" + Properties[PropertyId].garage.pos = PlayerPos + Properties[PropertyId].garage.Heading = heading + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Garage Location Changed", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Original Position**", value = tostring(Original), inline = true }, + { name = "**New Position**", value = tostring(PlayerPos), inline = true }, + }, + 2 + ) + cb(true) + else + cb(false) + end end) ESX.RegisterServerCallback("esx_property:SetCCTVangle", function(source, cb, PropertyId, angles) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ToggleCCTV") then - local Property = Properties[PropertyId] - Properties[PropertyId].cctv.rot = angles.rot - Properties[PropertyId].cctv.maxleft = angles.maxleft - Properties[PropertyId].cctv.maxright = angles.maxright - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - cb(true) - Log("Property CCTV Angle Changed", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}}, 2) - else - cb(false) - end + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ToggleCCTV") then + local Property = Properties[PropertyId] + Properties[PropertyId].cctv.rot = angles.rot + Properties[PropertyId].cctv.maxleft = angles.maxleft + Properties[PropertyId].cctv.maxright = angles.maxright + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + cb(true) + Log("Property CCTV Angle Changed", 3640511, { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + }, 2) + else + cb(false) + end end) ESX.RegisterServerCallback("esx_property:CCTV", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - local Property = Properties[PropertyId] - if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - SetEntityCoords(GetPlayerPed(source), vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + 5.0)) - SetPlayerRoutingBucket(source, 0) - end - Log("Player Entered CCTV", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}}, 3) - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + local Property = Properties[PropertyId] + if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + SetEntityCoords(GetPlayerPed(source), vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z + 5.0)) + SetPlayerRoutingBucket(source, 0) + end + Log("Player Entered CCTV", 3640511, { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Player**", value = xPlayer.getName(), inline = true } }, 3) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:ExitCCTV", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - local Property = Properties[PropertyId] - if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - local Interior = GetInteriorValues(Property.Interior) - if Interior.type == "shell" then - SetEntityCoords(GetPlayerPed(source), vector3(Property.Entrance.x, Property.Entrance.y, 2001)) - else - SetEntityCoords(GetPlayerPed(source), Interior.pos) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + local Property = Properties[PropertyId] + if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + local Interior = GetInteriorValues(Property.Interior) + if Interior.type == "shell" then + SetEntityCoords(GetPlayerPed(source), vector3(Property.Entrance.x, Property.Entrance.y, 2001)) + else + SetEntityCoords(GetPlayerPed(source), Interior.pos) + end + SetPlayerRoutingBucket(source, PropertyId + 1) end - SetPlayerRoutingBucket(source, PropertyId + 1) - end - Log("Player Exited CCTV", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}}, 3) - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + Log("Player Exited CCTV", 3640511, { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Player**", value = xPlayer.getName(), inline = true } }, 3) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:SetPropertyName", function(source, cb, PropertyId, name) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - local Property = Properties[PropertyId] - if xPlayer.identifier == Owner or IsPlayerAdmin(source) then - if name and #name <= Config.MaxNameLength then - Properties[PropertyId].setName = name - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Name Changed", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, {name = "**New Name**", value = name, inline = true}}, 2) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + local Property = Properties[PropertyId] + if xPlayer.identifier == Owner or IsPlayerAdmin(source) then + if name and #name <= Config.MaxNameLength then + Properties[PropertyId].setName = name + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log("Property Name Changed", 3640511, { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Player**", value = xPlayer.getName(), inline = true }, { name = "**New Name**", value = name, inline = true } }, 2) + end end - end - cb((xPlayer.identifier == Owner or IsPlayerAdmin(source, "SetPropertyName")) and name and #name <= Config.MaxNameLength) + cb((xPlayer.identifier == Owner or IsPlayerAdmin(source, "SetPropertyName")) and name and #name <= Config.MaxNameLength) end) ESX.RegisterServerCallback("esx_property:KnockOnDoor", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Property = Properties[PropertyId] - local Owner = ESX.GetPlayerFromIdentifier(Property.Owner) - if Owner then - for i = 1, #(Property.plysinside) do - if Property.plysinside[i] == Owner.source then - Owner.showNotification(_U("knocking"), "info") - cb(true) - Log("Player Knocked On Door", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}}, 3) - end + local xPlayer = ESX.GetPlayerFromId(source) + local Property = Properties[PropertyId] + local Owner = ESX.GetPlayerFromIdentifier(Property.Owner) + if Owner then + for i = 1, #Property.plysinside do + if Property.plysinside[i] == Owner.source then + Owner.showNotification(_U("knocking"), "info") + cb(true) + Log("Player Knocked On Door", 3640511, { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + }, 3) + end + end + cb(false) + else + cb(false) end - cb(false) - else - cb(false) - end end) ESX.RegisterServerCallback("esx_property:RemoveCustomName", function(source, cb, PropertyId) - local Property = Properties[PropertyId] - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "RemovePropertyName") then - local n = Properties[PropertyId].setName - Properties[PropertyId].setName = "" - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Name Reset", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Removed Name**", value = n, inline = true}}, 3) - cb(true) - else - cb(false) - end + local Property = Properties[PropertyId] + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "RemovePropertyName") then + local n = Properties[PropertyId].setName + Properties[PropertyId].setName = "" + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Name Reset", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Removed Name**", value = n, inline = true }, + }, + 3 + ) + cb(true) + else + cb(false) + end end) ESX.RegisterServerCallback("esx_property:deleteProperty", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "DeleteProperty") then - Log("Property Deleted", 16711680, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName ~= "" and Properties[PropertyId].OwnerName or "N/A", inline = true}, - {name = "**Furniture Count**", value = #(Properties[PropertyId].furniture), inline = true}, - {name = "**Vehicle Count**", value = Properties[PropertyId].garage.StoredVehicles and #(Properties[PropertyId].garage.StoredVehicles) or "N/A", inline = true}}, 1) - table.remove(Properties, PropertyId) - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - if Config.OxInventory then - exports.ox_inventory:ClearInventory("property-" .. PropertyId) + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "DeleteProperty") then + Log( + "Property Deleted", + 16711680, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName ~= "" and Properties[PropertyId].OwnerName or "N/A", inline = true }, + { name = "**Furniture Count**", value = #Properties[PropertyId].furniture, inline = true }, + { name = "**Vehicle Count**", value = Properties[PropertyId].garage.StoredVehicles and #Properties[PropertyId].garage.StoredVehicles or "N/A", inline = true }, + }, + 1 + ) + table.remove(Properties, PropertyId) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + if Config.OxInventory then + exports.ox_inventory:ClearInventory("property-" .. PropertyId) + end end - end - cb(IsPlayerAdmin(source, "DeleteProperty")) + cb(IsPlayerAdmin(source, "DeleteProperty")) end) ESX.RegisterServerCallback("esx_property:ChangePrice", function(source, cb, PropertyId, NewPrice) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "SetPropertyPrice") then - local Original = Properties[PropertyId].Price - Properties[PropertyId].Price = NewPrice - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Price Changed", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, {name = "**Original Price**", value = tostring(Original), inline = true}, - {name = "**New Price**", value = tostring(NewPrice), inline = true}}, 2) - end - cb(IsPlayerAdmin(source, "SetPropertyPrice")) + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "SetPropertyPrice") then + local Original = Properties[PropertyId].Price + Properties[PropertyId].Price = NewPrice + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Price Changed", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Original Price**", value = tostring(Original), inline = true }, + { name = "**New Price**", value = tostring(NewPrice), inline = true }, + }, + 2 + ) + end + cb(IsPlayerAdmin(source, "SetPropertyPrice")) end) ESX.RegisterServerCallback("esx_property:ChangeInterior", function(source, cb, PropertyId, Interior) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ChangeInterior") then - local Original = GetInteriorValues(Properties[PropertyId].Interior).label - Properties[PropertyId].Interior = Interior - Properties[PropertyId].furniture = {} - Properties[PropertyId].positions = GetInteriorValues(Interior).positions - if not Config.OxInventory then - Properties[PropertyId].positions.Storage = nil + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ChangeInterior") then + local Original = GetInteriorValues(Properties[PropertyId].Interior).label + Properties[PropertyId].Interior = Interior + Properties[PropertyId].furniture = {} + Properties[PropertyId].positions = GetInteriorValues(Interior).positions + if not Config.OxInventory then + Properties[PropertyId].positions.Storage = nil + end + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Interior Changed", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Original**", value = tostring(Original), inline = true }, + { name = "**New Interior**", value = GetInteriorValues(Properties[PropertyId].Interior).label, inline = true }, + }, + 2 + ) end - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Interior Changed", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, {name = "**Original**", value = tostring(Original), inline = true}, - {name = "**New Interior**", value = GetInteriorValues(Properties[PropertyId].Interior).label, inline = true}}, 2) - end - cb(IsPlayerAdmin(source, "ChangeInterior")) + cb(IsPlayerAdmin(source, "ChangeInterior")) end) ESX.RegisterServerCallback("esx_property:RemoveAllfurniture", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner or IsPlayerAdmin(source, "ResetFurniture") or - (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - for i = 1, #Properties[PropertyId].plysinside do - for furniture = 1, #Properties[PropertyId].furniture do - TriggerClientEvent("esx_property:removeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furniture) - end + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner or IsPlayerAdmin(source, "ResetFurniture") or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + for i = 1, #Properties[PropertyId].plysinside do + for furniture = 1, #Properties[PropertyId].furniture do + TriggerClientEvent("esx_property:removeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furniture) + end + end + Properties[PropertyId].furniture = {} + TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) end - Properties[PropertyId].furniture = {} - TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) - end - Log("Property Furniture Reset", 16711680, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}}, 1) - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source, "ResetFurniture") or - (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + Log("Property Furniture Reset", 16711680, { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Admin**", value = xPlayer.getName(), inline = true } }, 1) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source, "ResetFurniture") or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:deleteFurniture", function(source, cb, PropertyId, furnitureIndex) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - if Properties[PropertyId].furniture[furnitureIndex] then - Properties[PropertyId].furniture[furnitureIndex] = nil - TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) - end - for i = 1, #Properties[PropertyId].plysinside do - TriggerClientEvent("esx_property:removeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furnitureIndex) + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + if Properties[PropertyId].furniture[furnitureIndex] then + Properties[PropertyId].furniture[furnitureIndex] = nil + TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) + end + for i = 1, #Properties[PropertyId].plysinside do + TriggerClientEvent("esx_property:removeFurniture", Properties[PropertyId].plysinside[i], PropertyId, furnitureIndex) + end end - end - Log("Property Furniture Deleted", 16711680, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Furniture Name**", value = xPlayer.getName(), inline = true}}, 3) - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + Log("Property Furniture Deleted", 16711680, { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Admin**", value = xPlayer.getName(), inline = true }, { name = "**Furniture Name**", value = xPlayer.getName(), inline = true } }, 3) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:editFurniture", function(source, cb, PropertyId, furnitureIndex, Pos, Heading) - local xPlayer = ESX.GetPlayerFromId(source) - local Owner = Properties[PropertyId].Owner - if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then - if Properties[PropertyId].furniture[furnitureIndex] then - Properties[PropertyId].furniture[furnitureIndex].Pos = Pos - Properties[PropertyId].furniture[furnitureIndex].Heading = Heading - TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) - for i = 1, #Properties[PropertyId].plysinside do - TriggerClientEvent("esx_property:editFurniture", Properties[PropertyId].plysinside[i], PropertyId, furnitureIndex, Pos, Heading) - end + local xPlayer = ESX.GetPlayerFromId(source) + local Owner = Properties[PropertyId].Owner + if xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier]) then + if Properties[PropertyId].furniture[furnitureIndex] then + Properties[PropertyId].furniture[furnitureIndex].Pos = Pos + Properties[PropertyId].furniture[furnitureIndex].Heading = Heading + TriggerClientEvent("esx_property:syncFurniture", -1, PropertyId, Properties[PropertyId].furniture) + for i = 1, #Properties[PropertyId].plysinside do + TriggerClientEvent("esx_property:editFurniture", Properties[PropertyId].plysinside[i], PropertyId, furnitureIndex, Pos, Heading) + end + end end - end - cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) + cb(xPlayer.identifier == Owner or IsPlayerAdmin(source) or (Properties[PropertyId].Keys and Properties[PropertyId].Keys[xPlayer.identifier])) end) ESX.RegisterServerCallback("esx_property:evictOwner", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "EvictOwner") then - local xOwner = ESX.GetPlayerFromIdentifier(Properties[PropertyId].Owner) - if xOwner then - xOwner.showNotification("Your Have Been ~r~Evicted~s~.", "error") - end - local pName = Properties[PropertyId].OwnerName - Properties[PropertyId].Owner = "" - Properties[PropertyId].Owned = false - Properties[PropertyId].OwnerName = "" - Properties[PropertyId].Locked = false - Properties[PropertyId].Keys = {} - if Config.WipeFurnitureOnSell then - Properties[PropertyId].furniture = {} - end - Properties[PropertyId].setName = "" - Properties[PropertyId].plysinside = {} - if Properties[PropertyId].garage.StoredVehicles then - Properties[PropertyId].garage.StoredVehicles = {} - end - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - if Config.OxInventory then - exports.ox_inventory:ClearInventory("property-" .. PropertyId) + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "EvictOwner") then + local xOwner = ESX.GetPlayerFromIdentifier(Properties[PropertyId].Owner) + if xOwner then + xOwner.showNotification("Your Have Been ~r~Evicted~s~.", "error") + end + local pName = Properties[PropertyId].OwnerName + Properties[PropertyId].Owner = "" + Properties[PropertyId].Owned = false + Properties[PropertyId].OwnerName = "" + Properties[PropertyId].Locked = false + Properties[PropertyId].Keys = {} + if Config.WipeFurnitureOnSell then + Properties[PropertyId].furniture = {} + end + Properties[PropertyId].setName = "" + Properties[PropertyId].plysinside = {} + if Properties[PropertyId].garage.StoredVehicles then + Properties[PropertyId].garage.StoredVehicles = {} + end + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + if Config.OxInventory then + exports.ox_inventory:ClearInventory("property-" .. PropertyId) + end + Log( + "Property Owner Evicted", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = pName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Has Access**", value = IsPlayerAdmin(source, "EvictOwner") and "Yes" or "No", inline = true }, + }, + 1 + ) end - Log("Property Owner Evicted", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, {name = "**Owner**", value = pName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Has Access**", value = IsPlayerAdmin(source, "EvictOwner") and "Yes" or "No", inline = true}}, 1) - end - cb(IsPlayerAdmin(source, "EvictOwner")) + cb(IsPlayerAdmin(source, "EvictOwner")) end) ESX.RegisterServerCallback("esx_property:CanRaid", function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Can = false - if Config.Raiding.Enabled then - if (Config.CanAdminsRaid and IsPlayerAdmin(source)) or xPlayer.job.name == "police" then - if Config.Raiding.ItemRequired then - local itemCount = xPlayer.getInventoryItem(Config.Raiding.ItemRequired.name).count - if itemCount >= Config.Raiding.ItemRequired.ItemCount then - if Config.Raiding.ItemRequired.RemoveItem then - xPlayer.removeInventoryItem(Config.Raiding.ItemRequired.name, Config.Raiding.ItemRequired.ItemCount) - end - Can = true - else - xPlayer.showNotification(_U("raid_notify_error", Config.Raiding.ItemRequired.ItemCount, Config.Raiding.ItemRequired.name), "error") + local xPlayer = ESX.GetPlayerFromId(source) + local Can = false + if Config.Raiding.Enabled then + if (Config.CanAdminsRaid and IsPlayerAdmin(source)) or xPlayer.job.name == "police" then + if Config.Raiding.ItemRequired then + local itemCount = xPlayer.getInventoryItem(Config.Raiding.ItemRequired.name).count + if itemCount >= Config.Raiding.ItemRequired.ItemCount then + if Config.Raiding.ItemRequired.RemoveItem then + xPlayer.removeInventoryItem(Config.Raiding.ItemRequired.name, Config.Raiding.ItemRequired.ItemCount) + end + Can = true + else + xPlayer.showNotification(_U("raid_notify_error", Config.Raiding.ItemRequired.ItemCount, Config.Raiding.ItemRequired.name), "error") + end + else + Can = true + end end - else - Can = true - end end - end - cb(Can) - if Can then - local xOwner = ESX.GetPlayerFromIdentifier(Properties[PropertyId].Owner) - if xOwner then - xOwner.showNotification(_U("raid_notify_success"), "error") + cb(Can) + if Can then + local xOwner = ESX.GetPlayerFromIdentifier(Properties[PropertyId].Owner) + if xOwner then + xOwner.showNotification(_U("raid_notify_success"), "error") + end + Wait(15000) + Properties[PropertyId].Locked = false + TriggerClientEvent("esx_property:syncProperties", -1, Properties) end - Wait(15000) - Properties[PropertyId].Locked = false - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - end end) ESX.RegisterServerCallback("esx_property:ChangeEntrance", function(source, cb, PropertyId, Coords) - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "ChangeEntrance") then - local Origonal = Properties[PropertyId].Entrance.x .. "," .. Properties[PropertyId].Entrance.y .. "," .. Properties[PropertyId].Entrance.z - Properties[PropertyId].Entrance = {x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2) - 0.8} - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - Log("Property Entrance Changed", 3640511, {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true}, - {name = "**Admin**", value = xPlayer.getName(), inline = true}, - {name = "**Has Access**", value = IsPlayerAdmin(source, "ChangeEntrance") and "Yes" or "No", - inline = true}, {name = "**Original**", value = Origonal, inline = true}, - {name = "**New**", - value = Properties[PropertyId].Entrance.x .. "," .. Properties[PropertyId].Entrance.y .. "," .. - Properties[PropertyId].Entrance.z, inline = true}}, 1) - end - cb(IsPlayerAdmin(source, "ChangeEntrance")) + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "ChangeEntrance") then + local Origonal = Properties[PropertyId].Entrance.x .. "," .. Properties[PropertyId].Entrance.y .. "," .. Properties[PropertyId].Entrance.z + Properties[PropertyId].Entrance = { x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2) - 0.8 } + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + Log( + "Property Entrance Changed", + 3640511, + { + { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, + { name = "**Owner**", value = Properties[PropertyId].OwnerName, inline = true }, + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Has Access**", value = IsPlayerAdmin(source, "ChangeEntrance") and "Yes" or "No", inline = true }, + { name = "**Original**", value = Origonal, inline = true }, + { name = "**New**", value = Properties[PropertyId].Entrance.x .. "," .. Properties[PropertyId].Entrance.y .. "," .. Properties[PropertyId].Entrance.z, inline = true }, + }, + 1 + ) + end + cb(IsPlayerAdmin(source, "ChangeEntrance")) end) ESX.RegisterServerCallback("esx_property:SetInventoryPosition", function(source, cb, PropertyId, Coords, Reset) - if Config.OxInventory then + if Config.OxInventory then + local Property = Properties[PropertyId] + local xPlayer = ESX.GetPlayerFromId(source) + if IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier]) then + local Interior = GetInteriorValues(Property.Interior) + if Reset then + Properties[PropertyId].positions.Storage = { x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2) } + else + if Interior.type == "ipl" then + Properties[PropertyId].positions.Storage = { x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2) } + else + Properties[PropertyId].positions.Storage = vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Coords + end + end + Log( + "Property Storage Location Set", + 3640511, + { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = Property.OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { + name = "**Has Access**", + value = (IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", + inline = true, + }, + { name = "**Reset?**", value = Reset and "Yes" or "No", inline = true }, + }, + 1 + ) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) + end + cb(IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) + else + cb(false) + end +end) +-- Wardrobe +ESX.RegisterServerCallback("esx_property:SetWardrobePosition", function(source, cb, PropertyId, Coords, Reset) local Property = Properties[PropertyId] local xPlayer = ESX.GetPlayerFromId(source) if IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier]) then - local Interior = GetInteriorValues(Property.Interior) - if Reset then - Properties[PropertyId].positions.Storage = {x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2)} - else - if Interior.type == "ipl" then - Properties[PropertyId].positions.Storage = {x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), - z = ESX.Math.Round(Coords.z, 2)} + local Interior = GetInteriorValues(Property.Interior) + if Reset then + Properties[PropertyId].positions.Wardrobe = Interior.positions.Wardrobe else - Properties[PropertyId].positions.Storage = vector3(Property.Entrance.x, Property.Entrance.y, 2000) - Coords + if Interior.type == "ipl" then + Properties[PropertyId].positions.Wardrobe = { x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2) } + else + Properties[PropertyId].positions.Wardrobe = vector3(Property.Entrance.x, Property.Entrance.y, 1999.8) - Coords + end + Log( + "Property Wardrobe Location Set", + 3640511, + { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = Property.OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { + name = "**Has Access**", + value = (IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", + inline = true, + }, + { name = "**Reset?**", value = Reset and "Yes" or "No", inline = true }, + }, + 1 + ) end - end - Log("Property Storage Location Set", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = Property.OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, {name = "**Has Access**", - value = (IsPlayerAdmin(source, "EditInteriorPositions") or - (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", inline = true}, - {name = "**Reset?**", value = Reset and "Yes" or "No", inline = true}}, 1) - TriggerClientEvent("esx_property:syncProperties", -1, Properties) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) end cb(IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) - else - cb(false) - end -end) --- Wardrobe -ESX.RegisterServerCallback("esx_property:SetWardrobePosition", function(source, cb, PropertyId, Coords, Reset) - local Property = Properties[PropertyId] - local xPlayer = ESX.GetPlayerFromId(source) - if IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier]) then - local Interior = GetInteriorValues(Property.Interior) - if Reset then - Properties[PropertyId].positions.Wardrobe = Interior.positions.Wardrobe - else - if Interior.type == "ipl" then - Properties[PropertyId].positions.Wardrobe = - {x = ESX.Math.Round(Coords.x, 2), y = ESX.Math.Round(Coords.y, 2), z = ESX.Math.Round(Coords.z, 2)} - else - Properties[PropertyId].positions.Wardrobe = vector3(Property.Entrance.x, Property.Entrance.y, 1999.8) - Coords - end - Log("Property Wardrobe Location Set", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = Property.OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, {name = "**Has Access**", - value = (IsPlayerAdmin(source, "EditInteriorPositions") or - (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) and "Yes" or "No", inline = true}, - {name = "**Reset?**", value = Reset and "Yes" or "No", inline = true}}, 1) - end - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - end - cb(IsPlayerAdmin(source, "EditInteriorPositions") or (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier])) end) -ESX.RegisterServerCallback('esx_property:getPlayerDressing', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) +ESX.RegisterServerCallback("esx_property:getPlayerDressing", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) - TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - local count = store.count('dressing') - local labels = {} + TriggerEvent("esx_datastore:getDataStore", "property", xPlayer.identifier, function(store) + local count = store.count("dressing") + local labels = {} - for i = 1, count, 1 do - local entry = store.get('dressing', i) - table.insert(labels, entry.label) - end + for i = 1, count, 1 do + local entry = store.get("dressing", i) + table.insert(labels, entry.label) + end - cb(labels) - end) + cb(labels) + end) end) -ESX.RegisterServerCallback('esx_property:GetInsidePlayers', function(source, cb, property) - local Property = Properties[property] - local Players = {} - local xPlayer = ESX.GetPlayerFromId(source) - local NearbyPlayers = Property.plysinside +ESX.RegisterServerCallback("esx_property:GetInsidePlayers", function(source, cb, property) + local Property = Properties[property] + local Players = {} + local xPlayer = ESX.GetPlayerFromId(source) + local NearbyPlayers = Property.plysinside - for _, v in pairs(NearbyPlayers) do - local xPlayer = ESX.GetPlayerFromId(v) - if not Properties[property].Keys then - Properties[property].Keys = {} - end - if xPlayer.identifier ~= Property.Owner and not Properties[property].Keys[xPlayer.identifier] then - Players[#Players + 1] = {Name = xPlayer.getName(), Id = xPlayer.source} + for _, v in pairs(NearbyPlayers) do + local xPlayer = ESX.GetPlayerFromId(v) + if not Properties[property].Keys then + Properties[property].Keys = {} + end + if xPlayer.identifier ~= Property.Owner and not Properties[property].Keys[xPlayer.identifier] then + Players[#Players + 1] = { Name = xPlayer.getName(), Id = xPlayer.source } + end end - end - cb(Players) + cb(Players) end) -ESX.RegisterServerCallback('esx_property:GetNearbyPlayers', function(source, cb, property) - local Property = Properties[property] - local Players = {} - local xPlayer = ESX.GetPlayerFromId(source) - local NearbyPlayers = ESX.OneSync.GetPlayersInArea(vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z), 5.0) - Wait(100) +ESX.RegisterServerCallback("esx_property:GetNearbyPlayers", function(source, cb, property) + local Property = Properties[property] + local Players = {} + local xPlayer = ESX.GetPlayerFromId(source) + local NearbyPlayers = ESX.OneSync.GetPlayersInArea(vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z), 5.0) + Wait(100) for _, v in pairs(NearbyPlayers) do - local xTarget = ESX.GetPlayerFromId(v.id) - if xPlayer.identifier ~= xTarget.identifier then - Players[#Players + 1] = {name = xTarget.getName(), source = xTarget.source} - end + local xTarget = ESX.GetPlayerFromId(v.id) + if xPlayer.identifier ~= xTarget.identifier then + Players[#Players + 1] = { name = xTarget.getName(), source = xTarget.source } + end end cb(Players) end) -ESX.RegisterServerCallback('esx_property:GetPlayersWithKeys', function(source, cb, property) - local Property = Properties[property] - local Players = {} - local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer.identifier == Property.Owner then - cb(Property.Keys or {}) - end +ESX.RegisterServerCallback("esx_property:GetPlayersWithKeys", function(source, cb, property) + local Property = Properties[property] + local Players = {} + local xPlayer = ESX.GetPlayerFromId(source) + if xPlayer.identifier == Property.Owner then + cb(Property.Keys or {}) + end end) -ESX.RegisterServerCallback('esx_property:ShouldHaveKey', function(source, cb, property) - local xPlayer = ESX.GetPlayerFromId(source) - cb(Properties[property].Keys[xPlayer.identifier]) +ESX.RegisterServerCallback("esx_property:ShouldHaveKey", function(source, cb, property) + local xPlayer = ESX.GetPlayerFromId(source) + cb(Properties[property].Keys[xPlayer.identifier]) end) -ESX.RegisterServerCallback('esx_property:GetWebhook', function(_, cb) - cb(Config.CCTV.PictureWebook) +ESX.RegisterServerCallback("esx_property:GetWebhook", function(_, cb) + cb(Config.CCTV.PictureWebook) end) -ESX.RegisterServerCallback('esx_property:RemoveLastProperty', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - MySQL.query("UPDATE `users` SET `last_property` = NULL WHERE `identifier` = ?", {xPlayer.identifier}) -- Remove Saved Data - SetPlayerRoutingBucket(source, 0) -- Reset Routing Bucket - xPlayer.set("lastProperty", nil) - cb() +ESX.RegisterServerCallback("esx_property:RemoveLastProperty", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + MySQL.query("UPDATE `users` SET `last_property` = NULL WHERE `identifier` = ?", { xPlayer.identifier }) -- Remove Saved Data + SetPlayerRoutingBucket(source, 0) -- Reset Routing Bucket + xPlayer.set("lastProperty", nil) + cb() end) -ESX.RegisterServerCallback('esx_property:GiveKey', function(source, cb, property, player) - local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromId(player) - local Property = Properties[property] +ESX.RegisterServerCallback("esx_property:GiveKey", function(source, cb, property, player) + local xPlayer = ESX.GetPlayerFromId(source) + local xTarget = ESX.GetPlayerFromId(player) + local Property = Properties[property] - if Property.Owner == xPlayer.identifier then - if not Property.Keys then - Properties[property].Keys = {} - end + if Property.Owner == xPlayer.identifier then + if not Property.Keys then + Properties[property].Keys = {} + end - local id = xTarget.identifier - if not Properties[property].Keys[id] then - Property.Keys[id] = {name = xTarget.getName(), identifier = id} - xTarget.showNotification(_U("you_granted", Property.Name), 'success') - xTarget.triggerEvent("esx_property:giveKeyAccess") - cb(true) + local id = xTarget.identifier + if not Properties[property].Keys[id] then + Property.Keys[id] = { name = xTarget.getName(), identifier = id } + xTarget.showNotification(_U("you_granted", Property.Name), "success") + xTarget.triggerEvent("esx_property:giveKeyAccess") + cb(true) + else + xPlayer.showNotification(_U("already_has"), "error") + cb(false) + end else - xPlayer.showNotification(_U("already_has"), 'error') - cb(false) + xPlayer.showNotification(_U("do_not_own"), "error") + cb(false) end - else - xPlayer.showNotification(_U("do_not_own"), 'error') - cb(false) - end - Log("Property Key Given", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = Property.OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, - {name = "**Has Access**", value = Property.Owner == xPlayer.identifier and "Yes" or "No", inline = true}}, 1) + Log( + "Property Key Given", + 3640511, + { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = Property.OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { name = "**Has Access**", value = Property.Owner == xPlayer.identifier and "Yes" or "No", inline = true }, + }, + 1 + ) end) -ESX.RegisterServerCallback('esx_property:StoreVehicle', function(source, cb, PropertyId, VehicleProperties) - local xPlayer = ESX.GetPlayerFromId(source) - local Property = Properties[PropertyId] - - if Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier] then - if Property.garage.enabled then - if Config.Garage.OwnedVehiclesOnly then - MySQL.scalar("SELECT `owner` FROM `owned_vehicles` WHERE `plate` = ?", {VehicleProperties.plate}, function(result) - if result then - if result == xPlayer.identifier then - Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = {owner = xPlayer.identifier, - vehicle = VehicleProperties} - cb(true) - elseif (Properties[PropertyId].Keys[result] or Property.Owner == result) then - Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = {owner = xPlayer.identifier, - vehicle = VehicleProperties} - cb(true) +ESX.RegisterServerCallback("esx_property:StoreVehicle", function(source, cb, PropertyId, VehicleProperties) + local xPlayer = ESX.GetPlayerFromId(source) + local Property = Properties[PropertyId] + + if Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier] then + if Property.garage.enabled then + if Config.Garage.OwnedVehiclesOnly then + MySQL.scalar("SELECT `owner` FROM `owned_vehicles` WHERE `plate` = ?", { VehicleProperties.plate }, function(result) + if result then + if result == xPlayer.identifier then + Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = { owner = xPlayer.identifier, vehicle = VehicleProperties } + cb(true) + elseif Properties[PropertyId].Keys[result] or Property.Owner == result then + Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = { owner = xPlayer.identifier, vehicle = VehicleProperties } + cb(true) + else + cb(false) + end + else + cb(false) + end + end) else - cb(false) + Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = { owner = xPlayer.identifier, vehicle = VehicleProperties } + cb(true) end - else + MySQL.query(Config.Garage.MySQLquery, { 1, VehicleProperties.plate }) -- Set vehicle as stored in MySQL + else + xPlayer.showNotification(_U("garage_not_enabled"), "error") cb(false) - end - end) - else - Properties[PropertyId].garage.StoredVehicles[#Properties[PropertyId].garage.StoredVehicles + 1] = {owner = xPlayer.identifier, - vehicle = VehicleProperties} - cb(true) - end - MySQL.query(Config.Garage.MySQLquery, {1, VehicleProperties.plate}) -- Set vehicle as stored in MySQL + end else - xPlayer.showNotification(_U("garage_not_enabled"), 'error') - cb(false) + xPlayer.showNotification(_U("cannot_access_property"), "error") + cb(false) end - else - xPlayer.showNotification(_U("cannot_access_property"), 'error') - cb(false) - end - Log("User Attempted To Store Vehicle", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = Property.OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, - {name = "**Has Access**", value = (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier]) and "Yes" or "No", - inline = true}, {name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true}, - {name = "**Vehicle Name**", value = VehicleProperties.DisplayName, inline = true}}, 2) + Log( + "User Attempted To Store Vehicle", + 3640511, + { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = Property.OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { name = "**Has Access**", value = (Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier]) and "Yes" or "No", inline = true }, + { name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true }, + { name = "**Vehicle Name**", value = VehicleProperties.DisplayName, inline = true }, + }, + 2 + ) end) -ESX.RegisterServerCallback('esx_property:AccessGarage', function(source, cb, PropertyId) - local xPlayer = ESX.GetPlayerFromId(source) - local Property = Properties[PropertyId] +ESX.RegisterServerCallback("esx_property:AccessGarage", function(source, cb, PropertyId) + local xPlayer = ESX.GetPlayerFromId(source) + local Property = Properties[PropertyId] - if Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier] then - if Property.garage.enabled then - cb(Property.garage.StoredVehicles) + if Property.Owner == xPlayer.identifier or Properties[PropertyId].Keys[xPlayer.identifier] then + if Property.garage.enabled then + cb(Property.garage.StoredVehicles) + else + xPlayer.showNotification(_U("garage_not_enabled"), "error") + cb(false) + end else - xPlayer.showNotification(_U("garage_not_enabled"), 'error') - cb(false) + xPlayer.showNotification(_U("cannot_access_property"), "error") + cb(false) end - else - xPlayer.showNotification(_U("cannot_access_property"), 'error') - cb(false) - end - - Log("User Opened Garage Menu", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = Property.OwnerName, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, - {name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true}}, 2) -end) -ESX.RegisterServerCallback('esx_property:RemoveKey', function(source, cb, property, player) - local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromIdentifier(player) - local Property = Properties[property] + Log( + "User Opened Garage Menu", + 3640511, + { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = Property.OwnerName, inline = true }, + { name = "**Player**", value = xPlayer.getName(), inline = true }, + { name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true }, + }, + 2 + ) +end) - if Property.Owner == xPlayer.identifier then - if Property.Keys then - if Properties[property].Keys[player] then - Log("Property Key Revoked", 3640511, - {{name = "**Property Name**", value = Property.Name, inline = true}, {name = "**Owner**", value = xPlayer.getName(), inline = true}, - {name = "**Removed From**", value = tostring(Properties[property].Keys[player].name), inline = true}}, 3) - Properties[property].Keys[player] = nil - xTarget.showNotification(_U("key_revoked", Property.Name), 'error') - xTarget.triggerEvent("esx_property:RemoveKeyAccess", property) - cb(true) - else - xPlayer.showNotification(_U("no_keys"), 'error') - cb(false) - end +ESX.RegisterServerCallback("esx_property:RemoveKey", function(source, cb, property, player) + local xPlayer = ESX.GetPlayerFromId(source) + local xTarget = ESX.GetPlayerFromIdentifier(player) + local Property = Properties[property] + + if Property.Owner == xPlayer.identifier then + if Property.Keys then + if Properties[property].Keys[player] then + Log("Property Key Revoked", 3640511, { + { name = "**Property Name**", value = Property.Name, inline = true }, + { name = "**Owner**", value = xPlayer.getName(), inline = true }, + { name = "**Removed From**", value = tostring(Properties[property].Keys[player].name), inline = true }, + }, 3) + Properties[property].Keys[player] = nil + xTarget.showNotification(_U("key_revoked", Property.Name), "error") + xTarget.triggerEvent("esx_property:RemoveKeyAccess", property) + cb(true) + else + xPlayer.showNotification(_U("no_keys"), "error") + cb(false) + end + else + cb(false) + end else - cb(false) + xPlayer.showNotification(_U("do_not_own"), "error") + cb(false) end - else - xPlayer.showNotification(_U("do_not_own"), 'error') - cb(false) - end end) -ESX.RegisterServerCallback('esx_property:CanOpenFurniture', function(source, cb, property) - local xPlayer = ESX.GetPlayerFromId(source) - local Property = Properties[property] - cb(Property.Owner == xPlayer.identifier or (Property.Keys and Properties[property].Keys[xPlayer.identifier])) +ESX.RegisterServerCallback("esx_property:CanOpenFurniture", function(source, cb, property) + local xPlayer = ESX.GetPlayerFromId(source) + local Property = Properties[property] + cb(Property.Owner == xPlayer.identifier or (Property.Keys and Properties[property].Keys[xPlayer.identifier])) end) -ESX.RegisterServerCallback('esx_property:getPlayerOutfit', function(source, cb, num) - local xPlayer = ESX.GetPlayerFromId(source) +ESX.RegisterServerCallback("esx_property:getPlayerOutfit", function(source, cb, num) + local xPlayer = ESX.GetPlayerFromId(source) - TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.identifier, function(store) - local outfit = store.get('dressing', num) - cb(outfit.skin) - end) + TriggerEvent("esx_datastore:getDataStore", "property", xPlayer.identifier, function(store) + local outfit = store.get("dressing", num) + cb(outfit.skin) + end) end) -- Player Management if PM.Enabled then - ESX.RegisterServerCallback('esx_property:PMenterOffice', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - local PlayerPed = GetPlayerPed(source) - - if xPlayer.job.name == PM.job then - SetEntityCoords(PlayerPed, PM.Locations.Exit) - SetPlayerRoutingBucket(source, 1) - cb(true) - else - cb(false) - end - end) + ESX.RegisterServerCallback("esx_property:PMenterOffice", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local PlayerPed = GetPlayerPed(source) + + if xPlayer.job.name == PM.job then + SetEntityCoords(PlayerPed, PM.Locations.Exit) + SetPlayerRoutingBucket(source, 1) + cb(true) + else + cb(false) + end + end) - ESX.RegisterServerCallback('esx_property:PMexitOffice', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - local PlayerPed = GetPlayerPed(source) + ESX.RegisterServerCallback("esx_property:PMexitOffice", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local PlayerPed = GetPlayerPed(source) - if xPlayer.job.name == PM.job then - SetEntityCoords(PlayerPed, PM.Locations.Entrance) - SetPlayerRoutingBucket(source, 0) - cb(true) - else - cb(false) - end - end) + if xPlayer.job.name == PM.job then + SetEntityCoords(PlayerPed, PM.Locations.Entrance) + SetPlayerRoutingBucket(source, 0) + cb(true) + else + cb(false) + end + end) end -- Enter/leave Events -RegisterNetEvent('esx_property:enter', function(PropertyId) - local player = source - local PlayerPed = GetPlayerPed(player) - local xPlayer = ESX.GetPlayerFromId(player) - local Property = Properties[PropertyId] - local Interior = GetInteriorValues(Property.Interior) - if not Properties[PropertyId].plysinside then - Properties[PropertyId].plysinside = {} - end - table.insert(Properties[PropertyId].plysinside, player) - - local PropertyData = {id = PropertyId, coords = Property.Entrance} -- Save the property data to the table - MySQL.query("UPDATE `users` SET `last_property` = ? WHERE `identifier` = ?", {json.encode(PropertyData), xPlayer.identifier}) -- Save the property data to the database - xPlayer.set("lastProperty", PropertyData) - if Interior.type == "shell" then - SetEntityCoords(PlayerPed, vector3(Property.Entrance.x, Property.Entrance.y, 2001)) - else - SetEntityCoords(PlayerPed, Interior.pos) - SetEntityHeading(PlayerPed, 0.0) - end - SetPlayerRoutingBucket(player, PropertyId + 1) - Log("Player Entered Property", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, - {name = "**Property Player Count**", value = tostring(#(Properties[PropertyId].plysinside)), inline = true}}, 3) -end) +RegisterNetEvent("esx_property:enter", function(PropertyId) + local player = source + local PlayerPed = GetPlayerPed(player) + local xPlayer = ESX.GetPlayerFromId(player) + local Property = Properties[PropertyId] + local Interior = GetInteriorValues(Property.Interior) + if not Properties[PropertyId].plysinside then + Properties[PropertyId].plysinside = {} + end + table.insert(Properties[PropertyId].plysinside, player) -RegisterNetEvent('esx_property:leave', function(PropertyId) - local player = source - local Property = Properties[PropertyId] - local xPlayer = ESX.GetPlayerFromId(player) - MySQL.query("UPDATE `users` SET `last_property` = NULL WHERE `identifier` = ?", {xPlayer.identifier}) -- Remove Saved Data - xPlayer.set("lastProperty", nil) - SetEntityCoords(player, vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z)) - SetEntityHeading(player, 0.0) - SetPlayerRoutingBucket(player, 0) - for i = 1, #(Properties[PropertyId].plysinside) do - if Properties[PropertyId].plysinside[i] == player then - table.remove(Properties[PropertyId].plysinside, i) - break + local PropertyData = { id = PropertyId, coords = Property.Entrance } -- Save the property data to the table + MySQL.query("UPDATE `users` SET `last_property` = ? WHERE `identifier` = ?", { json.encode(PropertyData), xPlayer.identifier }) -- Save the property data to the database + xPlayer.set("lastProperty", PropertyData) + if Interior.type == "shell" then + SetEntityCoords(PlayerPed, vector3(Property.Entrance.x, Property.Entrance.y, 2001)) + else + SetEntityCoords(PlayerPed, Interior.pos) + SetEntityHeading(PlayerPed, 0.0) end - end - Log("Player Left Property", 3640511, - {{name = "**Property Name**", value = Properties[PropertyId].Name, inline = true}, - {name = "**Player**", value = xPlayer.getName(), inline = true}, - {name = "**Property Player Count**", value = tostring(#(Properties[PropertyId].plysinside)), inline = true}}, 3) + SetPlayerRoutingBucket(player, PropertyId + 1) + Log( + "Player Entered Property", + 3640511, + { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Player**", value = xPlayer.getName(), inline = true }, { name = "**Property Player Count**", value = tostring(#Properties[PropertyId].plysinside), inline = true } }, + 3 + ) end) -RegisterNetEvent('esx_property:SetVehicleOut', function(PropertyId, VehIndex) - local VehicleData = Properties[PropertyId].garage.StoredVehicles[VehIndex] - local plate = VehicleData.vehicle.plate - table.remove(Properties[PropertyId].garage.StoredVehicles, VehIndex) - MySQL.query(Config.Garage.MySQLquery, {0, plate}) -- Set vehicle as no longer stored +RegisterNetEvent("esx_property:leave", function(PropertyId) + local player = source + local Property = Properties[PropertyId] + local xPlayer = ESX.GetPlayerFromId(player) + MySQL.query("UPDATE `users` SET `last_property` = NULL WHERE `identifier` = ?", { xPlayer.identifier }) -- Remove Saved Data + xPlayer.set("lastProperty", nil) + SetEntityCoords(player, vector3(Property.Entrance.x, Property.Entrance.y, Property.Entrance.z)) + SetEntityHeading(player, 0.0) + SetPlayerRoutingBucket(player, 0) + for i = 1, #Properties[PropertyId].plysinside do + if Properties[PropertyId].plysinside[i] == player then + table.remove(Properties[PropertyId].plysinside, i) + break + end + end + Log( + "Player Left Property", + 3640511, + { { name = "**Property Name**", value = Properties[PropertyId].Name, inline = true }, { name = "**Player**", value = xPlayer.getName(), inline = true }, { name = "**Property Player Count**", value = tostring(#Properties[PropertyId].plysinside), inline = true } }, + 3 + ) end) +RegisterNetEvent("esx_property:SetVehicleOut", function(PropertyId, VehIndex) + local VehicleData = Properties[PropertyId].garage.StoredVehicles[VehIndex] + local plate = VehicleData.vehicle.plate + table.remove(Properties[PropertyId].garage.StoredVehicles, VehIndex) + MySQL.query(Config.Garage.MySQLquery, { 0, plate }) -- Set vehicle as no longer stored +end) -AddEventHandler('playerDropped', function() - local source = source - for PropertyId = 1, #Properties do - for i = 1, #(Properties[PropertyId].plysinside) do - if Properties[PropertyId].plysinside[i] == source then - table.remove(Properties[PropertyId].plysinside, i) - break - end +AddEventHandler("playerDropped", function() + local source = source + for PropertyId = 1, #Properties do + for i = 1, #Properties[PropertyId].plysinside do + if Properties[PropertyId].plysinside[i] == source then + table.remove(Properties[PropertyId].plysinside, i) + break + end + end end - end end) -ESX.RegisterServerCallback('esx_property:CanCreateProperty', function(source, cb) - local Re = false - local xPlayer = ESX.GetPlayerFromId(source) +ESX.RegisterServerCallback("esx_property:CanCreateProperty", function(source, cb) + local Re = false + local xPlayer = ESX.GetPlayerFromId(source) - if xPlayer then - if IsPlayerAdmin(source, "CreateProperty") then - Re = true + if xPlayer then + if IsPlayerAdmin(source, "CreateProperty") then + Re = true + end end - end - cb(Re) + cb(Re) end) -ESX.RegisterServerCallback('esx_property:IsAdmin', function(source, cb) - cb(IsPlayerAdmin(source, "ViewProperties")) +ESX.RegisterServerCallback("esx_property:IsAdmin", function(source, cb) + cb(IsPlayerAdmin(source, "ViewProperties")) end) -ESX.RegisterServerCallback('esx_property:CanAccessRealEstateMenu', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - local Re = (Config.PlayerManagement.Enabled and xPlayer.job.name == Config.PlayerManagement.job and xPlayer.job.grade >= Config.PlayerManagement.Permissions.ManagePropertiesFromQuickActions) and true or false - cb(Re) +ESX.RegisterServerCallback("esx_property:CanAccessRealEstateMenu", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local Re = (Config.PlayerManagement.Enabled and xPlayer.job.name == Config.PlayerManagement.job and xPlayer.job.grade >= Config.PlayerManagement.Permissions.ManagePropertiesFromQuickActions) and true or false + cb(Re) end) -RegisterNetEvent('esx_property:server:createProperty', function(Property) - local source = source - local xPlayer = ESX.GetPlayerFromId(source) - local Interior = GetInteriorValues(Property.interior) - local garageData = - Property.garage.enabled and {enabled = true, pos = Property.garage.pos, Heading = Property.garage.heading, StoredVehicles = {}} or - {enabled = false} - if IsPlayerAdmin(source, "CreateProperty") then - local ActualProperty = {Name = Property.name, setName = "", Price = Property.price, furniture = {}, plysinside = {}, Interior = Property.interior, - Entrance = Property.entrance, Owner = "", Keys = {}, positions = Interior.positions, cctv = Property.cctv, - garage = garageData, Owned = false, Locked = false} - Properties[#Properties + 1] = ActualProperty - end - Log("Property Created", 65280, - {{name = "**Admin**", value = xPlayer.getName(), inline = true}, {name = "**Name**", value = Property.name, inline = true}, - {name = "**Price**", value = ESX.Math.GroupDigits(Property.price), inline = true}, - {name = "**Interior**", value = Interior.label, inline = true}, - {name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true}, - {name = "**CCTV Status**", value = Property.cctv.enabled and "Enabled" or "Disabled", inline = true}, - {name = "**Entrance**", value = tostring(Property.entrance.x .. ", " .. Property.entrance.y .. ", " .. Property.entrance.z), inline = true}}, 1) - TriggerClientEvent("esx_property:syncProperties", -1, Properties) +RegisterNetEvent("esx_property:server:createProperty", function(Property) + local source = source + local xPlayer = ESX.GetPlayerFromId(source) + local Interior = GetInteriorValues(Property.interior) + local garageData = Property.garage.enabled and { enabled = true, pos = Property.garage.pos, Heading = Property.garage.heading, StoredVehicles = {} } or { enabled = false } + if IsPlayerAdmin(source, "CreateProperty") then + local ActualProperty = { + Name = Property.name, + setName = "", + Price = Property.price, + furniture = {}, + plysinside = {}, + Interior = Property.interior, + Entrance = Property.entrance, + Owner = "", + Keys = {}, + positions = Interior.positions, + cctv = Property.cctv, + garage = garageData, + Owned = false, + Locked = false, + } + Properties[#Properties + 1] = ActualProperty + end + Log( + "Property Created", + 65280, + { + { name = "**Admin**", value = xPlayer.getName(), inline = true }, + { name = "**Name**", value = Property.name, inline = true }, + { name = "**Price**", value = ESX.Math.GroupDigits(Property.price), inline = true }, + { name = "**Interior**", value = Interior.label, inline = true }, + { name = "**Garage Status**", value = Property.garage.enabled and "Enabled" or "Disabled", inline = true }, + { name = "**CCTV Status**", value = Property.cctv.enabled and "Enabled" or "Disabled", inline = true }, + { name = "**Entrance**", value = tostring(Property.entrance.x .. ", " .. Property.entrance.y .. ", " .. Property.entrance.z), inline = true }, + }, + 1 + ) + TriggerClientEvent("esx_property:syncProperties", -1, Properties) end) -- Json File Saving --- Save Properties On Server Scheduled Restart -AddEventHandler('txAdmin:events:scheduledRestart', function(eventData) - if eventData.secondsRemaining == 60 then - CreateThread(function() - Wait(50000) - if Properties and #Properties > 0 then - SaveResourceFile(GetCurrentResourceName(), 'properties.json', json.encode(Properties)) - Log("Properties Saving", 11141375, {{name = "**Reason**", value = "Scheduled Server Restart", inline = true}, - {name = "**Property Count**", value = tostring(#Properties), inline = true}}, 1) - end - end) - end +AddEventHandler("txAdmin:events:scheduledRestart", function(eventData) + if eventData.secondsRemaining == 60 then + CreateThread(function() + Wait(50000) + if Properties and #Properties > 0 then + SaveResourceFile(GetCurrentResourceName(), "properties.json", json.encode(Properties)) + Log("Properties Saving", 11141375, { { name = "**Reason**", value = "Scheduled Server Restart", inline = true }, { name = "**Property Count**", value = tostring(#Properties), inline = true } }, 1) + end + end) + end end) function PropertySave(Reason) - if Properties and #Properties > 0 then - SaveResourceFile(GetCurrentResourceName(), 'properties.json', json.encode(Properties)) - Log("Properties Saving", 11141375, - {{name = "**Reason**", value = Reason, inline = true}, {name = "**Property Count**", value = tostring(#Properties), inline = true}}, 1) - end + if Properties and #Properties > 0 then + SaveResourceFile(GetCurrentResourceName(), "properties.json", json.encode(Properties)) + Log("Properties Saving", 11141375, { { name = "**Reason**", value = Reason, inline = true }, { name = "**Property Count**", value = tostring(#Properties), inline = true } }, 1) + end end --- Save Properties On Server Stop/Restart -AddEventHandler('txAdmin:events:serverShuttingDown', function() - PropertySave(_U("server_shutdown")) +AddEventHandler("txAdmin:events:serverShuttingDown", function() + PropertySave(_U("server_shutdown")) end) --- Save Properties On Resource Stop/Restart -AddEventHandler('onResourceStop', function(ResourceName) - if ResourceName == GetCurrentResourceName() then - PropertySave(_U("resource_stop")) - end +AddEventHandler("onResourceStop", function(ResourceName) + if ResourceName == GetCurrentResourceName() then + PropertySave(_U("resource_stop")) + end end) -AddEventHandler('onServerResourceStop', function(ResourceName) - if ResourceName == GetCurrentResourceName() then - PropertySave(_U("resource_stop")) - end +AddEventHandler("onServerResourceStop", function(ResourceName) + if ResourceName == GetCurrentResourceName() then + PropertySave(_U("resource_stop")) + end end) --- Save Properties every x Minutes +-- Save Properties every x Minutes CreateThread(function() - while true do - Wait(60000 * Config.SaveInterval) - PropertySave(_U("interval_save")) - end + while true do + Wait(60000 * Config.SaveInterval) + PropertySave(_U("interval_save")) + end end) ESX.RegisterCommand(_("save_name"), Config.AllowedGroups, function(xPlayer) - PropertySave(_U("manual_save", GetPlayerName(xPlayer.source))) -end, false,{help = _U("save_desc")}) + PropertySave(_U("manual_save", GetPlayerName(xPlayer.source))) +end, false, { help = _U("save_desc") }) ----- Exports ----- exports("GetProperties", function() - return Properties + return Properties end) exports("GetOwnedProperties", function() - local OwnedProperties = {} - for i=1, #Properties do - if Properties[i].Owned then - OwnedProperties[#OwnedProperties + 1] = Properties[i] + local OwnedProperties = {} + for i = 1, #Properties do + if Properties[i].Owned then + OwnedProperties[#OwnedProperties + 1] = Properties[i] + end end - end - return OwnedProperties + return OwnedProperties end) exports("GetNonOwnedProperties", function() - local NonOwnedProperties = {} - for i=1, #Properties do - if not Properties[i].Owned then - NonOwnedProperties[#NonOwnedProperties + 1] = Properties[i] + local NonOwnedProperties = {} + for i = 1, #Properties do + if not Properties[i].Owned then + NonOwnedProperties[#NonOwnedProperties + 1] = Properties[i] + end end - end - return NonOwnedProperties + return NonOwnedProperties end) exports("GetPlayerProperties", function(identifier) - local PlayerProperties = {} - for i=1, #Properties do - if Properties[i].Owned and Properties[i].Owner == identifier then - PlayerProperties[#PlayerProperties + 1] = Properties[i] + local PlayerProperties = {} + for i = 1, #Properties do + if Properties[i].Owned and Properties[i].Owner == identifier then + PlayerProperties[#PlayerProperties + 1] = Properties[i] + end end - end - return PlayerProperties + return PlayerProperties end) exports("GetPropertyKeys", function(PropertyId) - local Property = Properties[PropertyId] - if Property.Keys then - return Property.Keys - end - return {} + local Property = Properties[PropertyId] + if Property.Keys then + return Property.Keys + end + return {} end) exports("DoesPlayerHaveKeys", function(PropertyId, Identifier) - local Property = Properties[PropertyId] - if Property.Keys then - return Property.Keys[Identifier] and true or false - end - return {} + local Property = Properties[PropertyId] + if Property.Keys then + return Property.Keys[Identifier] and true or false + end + return {} end) exports("ForceSaveProperties", function() - local ExecutingResource = GetInvokingResource() - PropertySave(_U("forced_save", ExecutingResource)) -end) \ No newline at end of file + local ExecutingResource = GetInvokingResource() + PropertySave(_U("forced_save", ExecutingResource)) +end)