0.0.1
This commit is contained in:
274
resources/[esx_addons]/esx_property/client/cctv.lua
Normal file
274
resources/[esx_addons]/esx_property/client/cctv.lua
Normal file
@@ -0,0 +1,274 @@
|
||||
--[[
|
||||
ESX Property - Properties Made Right!
|
||||
Copyright (C) 2025 ESX-Framework
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
function CCTV(PropertyID)
|
||||
DoScreenFadeOut(500)
|
||||
Wait(500)
|
||||
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()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_CLEAR_SPACE")
|
||||
PushScaleformMovieFunctionParameterInt(200)
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
if Config.CCTV.PictureWebook ~= "" then
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(1)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Screenshot, true))
|
||||
InstructionButtonMessage(TranslateCap("take_picture"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
end
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(2)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Right, true))
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Left, true))
|
||||
InstructionButtonMessage(TranslateCap("rot_left_right"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(3)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Down, true))
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Up, true))
|
||||
InstructionButtonMessage(TranslateCap("rot_up_down"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(4)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomOut, true))
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.ZoomIn, true))
|
||||
InstructionButtonMessage(TranslateCap("zoom"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(5)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.NightVision, true))
|
||||
InstructionButtonMessage(TranslateCap("night_vision"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(0)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Exit, true))
|
||||
InstructionButtonMessage(TranslateCap("exit"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "DRAW_INSTRUCTIONAL_BUTTONS")
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_BACKGROUND_COLOUR")
|
||||
PushScaleformMovieFunctionParameterInt(0)
|
||||
PushScaleformMovieFunctionParameterInt(0)
|
||||
PushScaleformMovieFunctionParameterInt(0)
|
||||
PushScaleformMovieFunctionParameterInt(80)
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
return scaleform
|
||||
end
|
||||
ESX.CloseContext()
|
||||
local cctvcam = nil
|
||||
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 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
|
||||
|
||||
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.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
|
||||
|
||||
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.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(TranslateCap("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)
|
||||
|
||||
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 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(TranslateCap("picture_taken"), "success")
|
||||
SendNUIMessage({link = image.attachments[1].proxy_url})
|
||||
ESX.ShowNotification(TranslateCap("clipboard"), "success")
|
||||
ShowButtons = true
|
||||
CamTakePic = false
|
||||
SetTimeout(5000, function()
|
||||
CamTakePic = true
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
else
|
||||
ESX.ShowNotification(TranslateCap("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
|
||||
407
resources/[esx_addons]/esx_property/client/furniture.lua
Normal file
407
resources/[esx_addons]/esx_property/client/furniture.lua
Normal file
@@ -0,0 +1,407 @@
|
||||
--[[
|
||||
ESX Property - Properties Made Right!
|
||||
Copyright (C) 2025 ESX-Framework
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
]]
|
||||
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(TranslateCap("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(TranslateCap("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(TranslateCap("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(TranslateCap("rotate"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(9)
|
||||
N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Confirm, true))
|
||||
InstructionButtonMessage(TranslateCap("place"))
|
||||
PopScaleformMovieFunctionVoid()
|
||||
|
||||
PushScaleformMovieFunction(scaleform, "SET_DATA_SLOT")
|
||||
PushScaleformMovieFunctionParameterInt(0)
|
||||
N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.Furniture.Controls.Exit, true))
|
||||
InstructionButtonMessage(TranslateCap("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)
|
||||
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 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
|
||||
|
||||
if IsControlPressed(0, Config.Furniture.Controls.Up) then
|
||||
SetEntityCoordsNoOffset(CurrentlyEditing, CurrentPos.x, CurrentPos.y, CurrentPos.z + Config.Furniture.MovementZspeed)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 IsControlJustPressed(0, Config.Furniture.Controls.Confirm) then
|
||||
if not Existing then
|
||||
ESX.OpenContext("right",
|
||||
{{unslectable = true, title = TranslateCap("confirm_buy",Config.FurnitureCatagories[PropCatagory][PropIndex].title),
|
||||
description = TranslateCap("price",Config.FurnitureCatagories[PropCatagory][PropIndex].price), icon = "fas fa-shopping-cart"},
|
||||
{title = TranslateCap("yes"), value = "buy", icon = "fas fa-check"}, {title = TranslateCap("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(TranslateCap("bought_furni", Config.FurnitureCatagories[PropCatagory][PropIndex].title), "success")
|
||||
ESX.CloseContext()
|
||||
else
|
||||
ESX.ShowNotification(TranslateCap("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(TranslateCap("edited_furni"), "success")
|
||||
ESX.CloseContext()
|
||||
else
|
||||
ESX.ShowNotification(TranslateCap("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
|
||||
|
||||
function FurnitureItems(house, Store, StoreIndex, Catagory)
|
||||
local Items = {{unselectable = true, title = TranslateCap("store_title", Catagory), icon = "fas fa-store"},
|
||||
{title = TranslateCap("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 = _U("price", v.price), icon = "fas fa-shopping-cart"})
|
||||
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
|
||||
|
||||
function FurnitureCatagories(house, Store, StoreIndex)
|
||||
local Catagories = {{unselectable = true, title = TranslateCap("store_title", Store), icon = "fas fa-store"},
|
||||
{title = TranslateCap("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
|
||||
|
||||
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 = TranslateCap("edit_title",Funiture.title), icon = "fas fa-store"},
|
||||
{title = TranslateCap("back"), value = "go-back", icon = "fas fa-arrow-left"},
|
||||
{title = TranslateCap("move_title"), value = "rotate", icon = "fas fa-sync-alt"}, {title = TranslateCap("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(TranslateCap("delete_confirm", Funiture.title), "success")
|
||||
FurnitureEditSelect(propertyId)
|
||||
else
|
||||
ESX.ShowNotification(TranslateCap("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 FurnitureEditSelect(propertyId)
|
||||
local Furni = {{unselectable = true, title = TranslateCap("owned_furni"), icon = "far fa-edit"},
|
||||
{title = TranslateCap("back"), value = "go-back", icon = "fas fa-arrow-left"}}
|
||||
|
||||
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
|
||||
|
||||
ESX.OpenContext("right", Furni, function(data, element)
|
||||
if element.value == "go-back" then
|
||||
FurnitureMenu(propertyId)
|
||||
else
|
||||
FurnitureEdit(propertyId, element.value)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function FurnitureStores(house)
|
||||
local Options = {{unselectable = true, title = TranslateCap("menu_stores"), icon = "fas fa-store"},
|
||||
{title = TranslateCap("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
|
||||
|
||||
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 = TranslateCap("furni_management"), icon = "fas fa-lamp"},
|
||||
{title = TranslateCap("menu_stores"), description = TranslateCap("menu_stores_desc"), icon = "fas fa-dollar-sign", value = "store"}}
|
||||
|
||||
if #SpawnedFurniture > 0 then
|
||||
Options[#Options + 1] = {title = TranslateCap("menu_reset"), description = TranslateCap("menu_reset_desc"), icon = "fas fa-trash", value = "reset"}
|
||||
Options[#Options + 1] = {title = TranslateCap("menu_edit"), description = TranslateCap("menu_edit_desc"), icon = "fas fa-archive", value = "edit"}
|
||||
|
||||
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(TranslateCap("furni_reset_success"), "success")
|
||||
else
|
||||
ESX.ShowNotification(TranslateCap("furni_reset_error"), "error")
|
||||
end
|
||||
end, PropertyId)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ESX.RegisterInput(TranslateCap("furni_command"), TranslateCap("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(TranslateCap("furni_command_permission"), 5000, "error")
|
||||
end
|
||||
end, CurrentId)
|
||||
else
|
||||
return
|
||||
end
|
||||
end)
|
||||
end
|
||||
25
resources/[esx_addons]/esx_property/client/html/copy.html
Normal file
25
resources/[esx_addons]/esx_property/client/html/copy.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!-- Cred: https://github.com/TerbSEC/FiveM-CoordsSaver/tree/master/html -->
|
||||
<html>
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
</head>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
window.addEventListener("message", function(event) {
|
||||
var node = document.createElement("textarea");
|
||||
var selection = document.getSelection();
|
||||
|
||||
node.textContent = event.data.link;
|
||||
document.body.appendChild(node);
|
||||
|
||||
selection.removeAllRanges();
|
||||
node.select();
|
||||
document.execCommand("copy");
|
||||
|
||||
selection.removeAllRanges();
|
||||
document.body.removeChild(node);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
1519
resources/[esx_addons]/esx_property/client/main.lua
Normal file
1519
resources/[esx_addons]/esx_property/client/main.lua
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user