diff --git a/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua b/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua index 145f48678..4d9e6a973 100644 --- a/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua @@ -16,9 +16,15 @@ function ShowBillsMenu() end ESX.OpenContext("right", elements, function(menu, element) - ESX.TriggerServerCallback("bpt_billing:payBill", function() + local billId = element.billId + + ESX.TriggerServerCallback("bpt_billing:payBill", function(resp) + if resp == true then + TriggerEvent("bpt_billing:paidBill", billId) + end + ShowBillsMenu() - end, element.billId) + end, billId) end) else ESX.ShowNotification(TranslateCap("no_invoices")) diff --git a/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua b/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua index 3458cc6c1..ea4fa4cf7 100644 --- a/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua @@ -1,31 +1,69 @@ -RegisterNetEvent("bpt_billing:sendBill", function(playerId, sharedAccountName, label, amount) - local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromId(playerId) +function BillPlayerByIdentifier(targetIdentifier, senderIdentifier, sharedAccountName, label, amount) + local xTarget = ESX.GetPlayerFromIdentifier(targetIdentifier) amount = ESX.Math.Round(amount) - if amount > 0 and xTarget then + if amount > 0 then if string.match(sharedAccountName, "society_") then - local jobName = string.gsub(sharedAccountName, "society_", "") - if xPlayer.job.name ~= jobName then - print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from a society (^5%s^7), but does not have the correct Job - Possibly Cheats"):format(xPlayer.source, sharedAccountName)) - return - end TriggerEvent("bpt_addonaccount:getSharedAccount", sharedAccountName, function(account) if account then - MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "society", sharedAccountName, label, amount }, function(rowsChanged) + MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { targetIdentifier, senderIdentifier, "society", sharedAccountName, label, amount }, function(rowsChanged) + if not xTarget then + return + end + xTarget.showNotification(TranslateCap("received_invoice")) end) else - print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from invalid society - ^5%s^7"):format(xPlayer.source, sharedAccountName)) + print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from invalid society - ^5%s^7"):format(senderIdentifier, sharedAccountName)) end end) else - MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "player", xPlayer.identifier, label, amount }, function(rowsChanged) + MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { targetIdentifier, senderIdentifier, "player", senderIdentifier, label, amount }, function(rowsChanged) + if not xTarget then + return + end + xTarget.showNotification(TranslateCap("received_invoice")) end) end end +end + +function BillPlayer(targetId, senderIdentifier, sharedAccountName, label, amount) + local xTarget = ESX.GetPlayerFromId(targetId) + + if not xTarget then + return + end + + BillPlayerByIdentifier(xTarget.identifier, senderIdentifier, sharedAccountName, label, amount) +end + +RegisterNetEvent("bpt_billing:sendBill", function(targetId, sharedAccountName, label, amount) + local xPlayer = ESX.GetPlayerFromId(source) + local jobName = string.gsub(sharedAccountName, "society_", "") + + if xPlayer.job.name ~= jobName then + print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from a society (^5%s^7), but does not have the correct Job - Possibly Cheats"):format(xPlayer.source, sharedAccountName)) + return + end + + BillPlayer(targetId, xPlayer.identifier, sharedAccountName, label, amount) end) +exports("BillPlayer", BillPlayer) + +RegisterNetEvent("bpt_billing:sendBillToIdentifier", function(targetIdentifier, sharedAccountName, label, amount) + local xPlayer = ESX.GetPlayerFromId(source) + local jobName = string.gsub(sharedAccountName, "society_", "") + + if xPlayer.job.name ~= jobName then + print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from a society (^5%s^7), but does not have the correct Job - Possibly Cheats"):format(xPlayer.source, sharedAccountName)) + return + end + + BillPlayerByIdentifier(targetIdentifier, xPlayer.identifier, sharedAccountName, label, amount) +end) +exports("BillPlayerByIdentifier", BillPlayerByIdentifier) ESX.RegisterServerCallback("bpt_billing:getBills", function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) @@ -62,33 +100,35 @@ ESX.RegisterServerCallback("bpt_billing:payBill", function(source, cb, billId) if rowsChanged == 1 then xPlayer.removeMoney(amount, "Bill Paid") xTarget.addMoney(amount, "Paid bill") - + TriggerEvent("bpt_billing:paidBill", source, billId) xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + cb(true) + else + cb(false) end - - cb() end) elseif xPlayer.getAccount("bank").money >= amount then MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) if rowsChanged == 1 then xPlayer.removeAccountMoney("bank", amount, "Bill Paid") xTarget.addAccountMoney("bank", amount, "Paid bill") - + TriggerEvent("bpt_billing:paidBill", source, billId) xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + cb(true) + else + cb(false) end - - cb() end) else xTarget.showNotification(TranslateCap("target_no_money")) xPlayer.showNotification(TranslateCap("no_money")) - cb() + cb(false) end else xPlayer.showNotification(TranslateCap("player_not_online")) - cb() + cb(false) end else TriggerEvent("bpt_addonaccount:getSharedAccount", result.target, function(account) @@ -97,14 +137,15 @@ ESX.RegisterServerCallback("bpt_billing:payBill", function(source, cb, billId) if rowsChanged == 1 then xPlayer.removeMoney(amount, "Bill Paid") account.addMoney(amount) - + TriggerEvent("bpt_billing:paidBill", source, billId) xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) if xTarget then xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) end + cb(true) + else + cb(false) end - - cb() end) elseif xPlayer.getAccount("bank").money >= amount then MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) @@ -112,13 +153,14 @@ ESX.RegisterServerCallback("bpt_billing:payBill", function(source, cb, billId) xPlayer.removeAccountMoney("bank", amount, "Bill Paid") account.addMoney(amount) xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) - + TriggerEvent("bpt_billing:paidBill", source, billId) if xTarget then xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) end + cb(true) + else + cb(false) end - - cb() end) else if xTarget then @@ -126,7 +168,7 @@ ESX.RegisterServerCallback("bpt_billing:payBill", function(source, cb, billId) end xPlayer.showNotification(TranslateCap("no_money")) - cb() + cb(false) end end) end diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/README.md b/server-data/resources/[esx_addons]/esx-qalle-jail/README.md index 9e646fc29..ed0d1b04c 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/README.md +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/README.md @@ -16,9 +16,9 @@ ```lua elements = { - {label = _U('citizen_interaction'), value = 'citizen_interaction'}, - {label = _U('vehicle_interaction'), value = 'vehicle_interaction'}, - {label = _U('object_spawner'), value = 'object_spawner'}, + {label = TranslateCap('citizen_interaction'), value = 'citizen_interaction'}, + {label = TranslateCap('vehicle_interaction'), value = 'vehicle_interaction'}, + {label = TranslateCap('object_spawner'), value = 'object_spawner'}, {label = "Jail Menu", value = 'jail_menu'} -- You add this line } }, function(data, menu) diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/client/client.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/client/client.lua index fce3583b2..f68d3c6ff 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/client/client.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/client/client.lua @@ -1,427 +1,393 @@ local Keys = { - ["ESC"] = 322, - ["F1"] = 288, - ["F2"] = 289, - ["F3"] = 170, - ["F5"] = 166, - ["F6"] = 167, - ["F7"] = 168, - ["F8"] = 169, - ["F9"] = 56, - ["F10"] = 57, - ["~"] = 243, - ["1"] = 157, - ["2"] = 158, - ["3"] = 160, - ["4"] = 164, - ["5"] = 165, - ["6"] = 159, - ["7"] = 161, - ["8"] = 162, - ["9"] = 163, - ["-"] = 84, - ["="] = 83, - ["BACKSPACE"] = 177, - ["TAB"] = 37, - ["Q"] = 44, - ["W"] = 32, - ["E"] = 38, - ["R"] = 45, - ["T"] = 245, - ["Y"] = 246, - ["U"] = 303, - ["P"] = 199, - ["["] = 39, - ["]"] = 40, - ["ENTER"] = 18, - ["CAPS"] = 137, - ["A"] = 34, - ["S"] = 8, - ["D"] = 9, - ["F"] = 23, - ["G"] = 47, - ["H"] = 74, - ["K"] = 311, - ["L"] = 182, - ["LEFTSHIFT"] = 21, - ["Z"] = 20, - ["X"] = 73, - ["C"] = 26, - ["V"] = 0, - ["B"] = 29, - ["N"] = 249, - ["M"] = 244, - [","] = 82, - ["."] = 81, - ["LEFTCTRL"] = 36, - ["LEFTALT"] = 19, - ["SPACE"] = 22, - ["RIGHTCTRL"] = 70, - ["HOME"] = 213, - ["PAGEUP"] = 10, - ["PAGEDOWN"] = 11, - ["DELETE"] = 178, - ["LEFT"] = 174, - ["RIGHT"] = 175, - ["TOP"] = 27, - ["DOWN"] = 173, - ["NENTER"] = 201, - ["N4"] = 108, - ["N5"] = 60, - ["N6"] = 107, - ["N+"] = 96, - ["N-"] = 97, - ["N7"] = 117, - ["N8"] = 61, - ["N9"] = 118, + ["ESC"] = 322, + ["F1"] = 288, + ["F2"] = 289, + ["F3"] = 170, + ["F5"] = 166, + ["F6"] = 167, + ["F7"] = 168, + ["F8"] = 169, + ["F9"] = 56, + ["F10"] = 57, + ["~"] = 243, + ["1"] = 157, + ["2"] = 158, + ["3"] = 160, + ["4"] = 164, + ["5"] = 165, + ["6"] = 159, + ["7"] = 161, + ["8"] = 162, + ["9"] = 163, + ["-"] = 84, + ["="] = 83, + ["BACKSPACE"] = 177, + ["TAB"] = 37, + ["Q"] = 44, + ["W"] = 32, + ["E"] = 38, + ["R"] = 45, + ["T"] = 245, + ["Y"] = 246, + ["U"] = 303, + ["P"] = 199, + ["["] = 39, + ["]"] = 40, + ["ENTER"] = 18, + ["CAPS"] = 137, + ["A"] = 34, + ["S"] = 8, + ["D"] = 9, + ["F"] = 23, + ["G"] = 47, + ["H"] = 74, + ["K"] = 311, + ["L"] = 182, + ["LEFTSHIFT"] = 21, + ["Z"] = 20, + ["X"] = 73, + ["C"] = 26, + ["V"] = 0, + ["B"] = 29, + ["N"] = 249, + ["M"] = 244, + [","] = 82, + ["."] = 81, + ["LEFTCTRL"] = 36, + ["LEFTALT"] = 19, + ["SPACE"] = 22, + ["RIGHTCTRL"] = 70, + ["HOME"] = 213, + ["PAGEUP"] = 10, + ["PAGEDOWN"] = 11, + ["DELETE"] = 178, + ["LEFT"] = 174, + ["RIGHT"] = 175, + ["TOP"] = 27, + ["DOWN"] = 173, + ["NENTER"] = 201, + ["N4"] = 108, + ["N5"] = 60, + ["N6"] = 107, + ["N+"] = 96, + ["N-"] = 97, + ["N7"] = 117, + ["N8"] = 61, + ["N9"] = 118, } PlayerData = {} local jailTime = 0 CreateThread(function() - ESX = exports["es_extended"]:getSharedObject() - while ESX.GetPlayerData() == nil do - Wait(10) - end + ESX = exports["es_extended"]:getSharedObject() + while ESX.GetPlayerData() == nil do + Wait(10) + end - PlayerData = ESX.GetPlayerData() + PlayerData = ESX.GetPlayerData() - LoadTeleporters() + LoadTeleporters() end) RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(newData) - PlayerData = newData - Wait(25000) + PlayerData = newData + Wait(25000) - ESX.TriggerServerCallback("esx-qalle-jail:retrieveJailTime", function(inJail, newJailTime) - if inJail then - jailTime = newJailTime + ESX.TriggerServerCallback("esx-qalle-jail:retrieveJailTime", function(inJail, newJailTime) + if inJail then + jailTime = newJailTime - JailLogin() - end - end) + JailLogin() + end + end) end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(response) - PlayerData["job"] = response + PlayerData["job"] = response end) RegisterNetEvent("esx-qalle-jail:openJailMenu") AddEventHandler("esx-qalle-jail:openJailMenu", function() - OpenJailMenu() + OpenJailMenu() end) RegisterNetEvent("esx-qalle-jail:jailPlayer") AddEventHandler("esx-qalle-jail:jailPlayer", function(newJailTime) - jailTime = newJailTime - Cutscene() + jailTime = newJailTime + Cutscene() end) RegisterNetEvent("esx-qalle-jail:unJailPlayer") AddEventHandler("esx-qalle-jail:unJailPlayer", function() - jailTime = 0 - UnJail() + jailTime = 0 + UnJail() end) function JailLogin() - local JailPosition = Config.JailPositions["Cell"] - SetEntityCoords(PlayerPedId(), JailPosition["x"], JailPosition["y"], JailPosition["z"] - 1) - ESX.ShowNotification(_U("back_in_jail")) - InJail() + local JailPosition = Config.JailPositions["Cell"] + SetEntityCoords(PlayerPedId(), JailPosition["x"], JailPosition["y"], JailPosition["z"] - 1) + ESX.ShowNotification(TranslateCap("back_in_jail")) + InJail() end function UnJail() - InJail() - ESX.Game.Teleport(PlayerPedId(), Config.Teleports["Boiling Broke"]) + InJail() + ESX.Game.Teleport(PlayerPedId(), Config.Teleports["Boiling Broke"]) - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - ESX.ShowNotification(_U("you_released")) + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + ESX.ShowNotification(TranslateCap("you_released")) end function InJail() - --Jail Timer-- - CreateThread(function() - while jailTime > 0 do - jailTime = jailTime - 1 - ESX.ShowNotification(_U("few_minutes")) - - TriggerServerEvent("esx-qalle-jail:updateJailTime", jailTime) - if jailTime == 0 then - UnJail() - TriggerServerEvent("esx-qalle-jail:updateJailTime", 0) - end - - Wait(60000) - end - end) - --Jail Timer-- - - --Prison Work-- - CreateThread(function() - while jailTime > 0 do - local sleepThread = 500 - local Packages = Config.PrisonWork["Packages"] - local Ped = PlayerPedId() - local PedCoords = GetEntityCoords(Ped) - - for posId, v in pairs(Packages) do - local DistanceCheck = GetDistanceBetweenCoords(PedCoords, v["x"], v["y"], v["z"], true) - - if DistanceCheck <= 10.0 then - sleepThread = 5 - - local PackageText = "Pack" - - if not v["state"] then - PackageText = "Already Taken" - end - - ESX.Game.Utils.DrawText3D(v, "[E] " .. PackageText, 0.4) - - if DistanceCheck <= 1.5 then - if IsControlJustPressed(0, 38) then - if v["state"] then - PackPackage(posId) - else - ESX.ShowNotification(_U("package_taken")) - end - end - end - end - end - Wait(sleepThread) - end - end) - --Prison Work-- + --Jail Timer-- + CreateThread(function() + while jailTime > 0 do + jailTime = jailTime - 1 + ESX.ShowNotification(TranslateCap("few_minutes")) + + TriggerServerEvent("esx-qalle-jail:updateJailTime", jailTime) + if jailTime == 0 then + UnJail() + TriggerServerEvent("esx-qalle-jail:updateJailTime", 0) + end + + Wait(60000) + end + end) + --Jail Timer-- + + --Prison Work-- + CreateThread(function() + while jailTime > 0 do + local sleepThread = 500 + local Packages = Config.PrisonWork["Packages"] + local Ped = PlayerPedId() + local PedCoords = GetEntityCoords(Ped) + + for posId, v in pairs(Packages) do + local DistanceCheck = GetDistanceBetweenCoords(PedCoords, v["x"], v["y"], v["z"], true) + + if DistanceCheck <= 10.0 then + sleepThread = 5 + + local PackageText = "Pack" + + if not v["state"] then + PackageText = "Already Taken" + end + + ESX.Game.Utils.DrawText3D(v, "[E] " .. PackageText, 0.4) + + if DistanceCheck <= 1.5 then + if IsControlJustPressed(0, 38) then + if v["state"] then + PackPackage(posId) + else + ESX.ShowNotification(TranslateCap("package_taken")) + end + end + end + end + end + Wait(sleepThread) + end + end) + --Prison Work-- end function LoadTeleporters() - CreateThread(function() - while true do - local sleepThread = 500 - local Ped = PlayerPedId() - local PedCoords = GetEntityCoords(Ped) - - for _, v in pairs(Config.Teleports) do - local DistanceCheck = GetDistanceBetweenCoords(PedCoords, v["x"], v["y"], v["z"], true) - - if DistanceCheck <= 7.5 then - sleepThread = 5 - - ESX.Game.Utils.DrawText3D(v, "[E] Open Door", 0.4) - - if DistanceCheck <= 1.0 then - if IsControlJustPressed(0, 38) then - TeleportPlayer(v) - end - end - end - end - Wait(sleepThread) - end - end) + CreateThread(function() + while true do + local sleepThread = 500 + local Ped = PlayerPedId() + local PedCoords = GetEntityCoords(Ped) + + for _, v in pairs(Config.Teleports) do + local DistanceCheck = GetDistanceBetweenCoords(PedCoords, v["x"], v["y"], v["z"], true) + + if DistanceCheck <= 7.5 then + sleepThread = 5 + + ESX.Game.Utils.DrawText3D(v, "[E] Open Door", 0.4) + + if DistanceCheck <= 1.0 then + if IsControlJustPressed(0, 38) then + TeleportPlayer(v) + end + end + end + end + Wait(sleepThread) + end + end) end function PackPackage(packageId) - local Package = Config.PrisonWork["Packages"][packageId] + local Package = Config.PrisonWork["Packages"][packageId] - LoadModel("prop_cs_cardbox_01") + LoadModel("prop_cs_cardbox_01") - local PackageObject = CreateObject(GetHashKey("prop_cs_cardbox_01"), Package["x"], Package["y"], Package["z"], true) + local PackageObject = CreateObject(GetHashKey("prop_cs_cardbox_01"), Package["x"], Package["y"], Package["z"], true) - PlaceObjectOnGroundProperly(PackageObject) + PlaceObjectOnGroundProperly(PackageObject) - TaskStartScenarioInPlace(PlayerPedId(), "PROP_HUMAN_BUM_BIN", 0, false) + TaskStartScenarioInPlace(PlayerPedId(), "PROP_HUMAN_BUM_BIN", 0, false) - local Packaging = true - local StartTime = GetGameTimer() + local Packaging = true + local StartTime = GetGameTimer() - while Packaging do - Wait(1) + while Packaging do + Wait(1) - local TimeToTake = 60000 * 1.20 -- Minutes - local PackPercent = (GetGameTimer() - StartTime) / TimeToTake * 100 + local TimeToTake = 60000 * 1.20 -- Minutes + local PackPercent = (GetGameTimer() - StartTime) / TimeToTake * 100 - if not IsPedUsingScenario(PlayerPedId(), "PROP_HUMAN_BUM_BIN") then - DeleteEntity(PackageObject) - ESX.ShowNotification(_U("canceled")) - Packaging = false - end + if not IsPedUsingScenario(PlayerPedId(), "PROP_HUMAN_BUM_BIN") then + DeleteEntity(PackageObject) + ESX.ShowNotification(TranslateCap("canceled")) + Packaging = false + end - if PackPercent >= 100 then - Packaging = false - DeliverPackage(PackageObject) - Package["state"] = false - else - ESX.Game.Utils.DrawText3D(Package, "Packaging... " .. math.ceil(tonumber(PackPercent)) .. "%", 0.4) - end - end + if PackPercent >= 100 then + Packaging = false + DeliverPackage(PackageObject) + Package["state"] = false + else + ESX.Game.Utils.DrawText3D(Package, "Packaging... " .. math.ceil(tonumber(PackPercent)) .. "%", 0.4) + end + end end function DeliverPackage(packageId) - if DoesEntityExist(packageId) then - AttachEntityToEntity( - packageId, - PlayerPedId(), - GetPedBoneIndex(PlayerPedId(), 28422), - 0.0, - -0.03, - 0.0, - 5.0, - 0.0, - 0.0, - 1, - 1, - 0, - 1, - 0, - 1 - ) - - ClearPedTasks(PlayerPedId()) - else - return - end - - local Packaging = true - - LoadAnim("anim@heists@box_carry@") - - while Packaging do - Wait(5) - - if not IsEntityPlayingAnim(PlayerPedId(), "anim@heists@box_carry@", "idle", 3) then - TaskPlayAnim(PlayerPedId(), "anim@heists@box_carry@", "idle", 8.0, 8.0, -1, 50, 0, false, false, false) - end - - if not IsEntityAttachedToEntity(packageId, PlayerPedId()) then - Packaging = false - DeleteEntity(packageId) - else - local DeliverPosition = Config.PrisonWork["DeliverPackage"] - local PedPosition = GetEntityCoords(PlayerPedId()) - local DistanceCheck = GetDistanceBetweenCoords( - PedPosition, - DeliverPosition["x"], - DeliverPosition["y"], - DeliverPosition["z"], - true - ) - - ESX.Game.Utils.DrawText3D(DeliverPosition, "[E] Leave Package", 0.4) - - if DistanceCheck <= 2.0 then - if IsControlJustPressed(0, 38) then - DeleteEntity(packageId) - ClearPedTasksImmediately(PlayerPedId()) - Packaging = false - - TriggerServerEvent("esx-qalle-jail:prisonWorkReward") - end - end - end - end + if DoesEntityExist(packageId) then + AttachEntityToEntity(packageId, PlayerPedId(), GetPedBoneIndex(PlayerPedId(), 28422), 0.0, -0.03, 0.0, 5.0, 0.0, 0.0, 1, 1, 0, 1, 0, 1) + + ClearPedTasks(PlayerPedId()) + else + return + end + + local Packaging = true + + LoadAnim("anim@heists@box_carry@") + + while Packaging do + Wait(5) + + if not IsEntityPlayingAnim(PlayerPedId(), "anim@heists@box_carry@", "idle", 3) then + TaskPlayAnim(PlayerPedId(), "anim@heists@box_carry@", "idle", 8.0, 8.0, -1, 50, 0, false, false, false) + end + + if not IsEntityAttachedToEntity(packageId, PlayerPedId()) then + Packaging = false + DeleteEntity(packageId) + else + local DeliverPosition = Config.PrisonWork["DeliverPackage"] + local PedPosition = GetEntityCoords(PlayerPedId()) + local DistanceCheck = GetDistanceBetweenCoords(PedPosition, DeliverPosition["x"], DeliverPosition["y"], DeliverPosition["z"], true) + + ESX.Game.Utils.DrawText3D(DeliverPosition, "[E] Leave Package", 0.4) + + if DistanceCheck <= 2.0 then + if IsControlJustPressed(0, 38) then + DeleteEntity(packageId) + ClearPedTasksImmediately(PlayerPedId()) + Packaging = false + + TriggerServerEvent("esx-qalle-jail:prisonWorkReward") + end + end + end + end end function OpenJailMenu() - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "jail_prison_menu", { - title = "Prison Menu", - align = "center", - elements = { - { label = "Jail Closest Person", value = "jail_closest_player" }, - { label = "Unjail Person", value = "unjail_player" }, - }, - }, function(data, menu) - local action = data.current.value - - if action == "jail_closest_player" then - menu.close() - - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "jail_choose_time_menu", { - title = "Jail Time (minutes)", - }, function(data2, menu2) - local jailTime = tonumber(data2.value) - if jailTime == nil then - ESX.ShowNotification(_U("time_minutes")) - else - menu2.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U("players_nearby")) - else - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "jail_choose_reason_menu", { - title = "Jail Reason", - }, function(data3, menu3) - local reason = data3.value - if reason == nil then - ESX.ShowNotification(_U("put_something")) - else - menu3.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U("players_nearby")) - else - TriggerServerEvent( - "esx-qalle-jail:jailPlayer", - GetPlayerServerId(closestPlayer), - jailTime, - reason - ) - end - end - end, function(_, menu3) - menu3.close() - end) - end - end - end, function(_, menu2) - menu2.close() - end) - elseif action == "unjail_player" then - local elements = {} - - ESX.TriggerServerCallback("esx-qalle-jail:retrieveJailedPlayers", function(playerArray) - if #playerArray == 0 then - ESX.ShowNotification(_U("jail_empty")) - return - end - - for i = 1, #playerArray, 1 do - table.insert( - elements, - { - label = "Prisoner: " - .. playerArray[i].name - .. " | Jail Time: " - .. playerArray[i].jailTime - .. " minutes", - value = playerArray[i].identifier, - } - ) - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "jail_unjail_menu", { - title = "Unjail Player", - align = "center", - elements = elements, - }, function(data2, menu2) - local action = data2.current.value - - TriggerServerEvent("esx-qalle-jail:unJailPlayer", action) - - menu2.close() - end, function(_, menu2) - menu2.close() - end) - end) - end - end, function(_, menu) - menu.close() - end) + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "jail_prison_menu", { + title = "Prison Menu", + align = "center", + elements = { + { label = "Jail Closest Person", value = "jail_closest_player" }, + { label = "Unjail Person", value = "unjail_player" }, + }, + }, function(data, menu) + local action = data.current.value + + if action == "jail_closest_player" then + menu.close() + + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "jail_choose_time_menu", { + title = "Jail Time (minutes)", + }, function(data2, menu2) + local jailTime = tonumber(data2.value) + if jailTime == nil then + ESX.ShowNotification(TranslateCap("time_minutes")) + else + menu2.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("players_nearby")) + else + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "jail_choose_reason_menu", { + title = "Jail Reason", + }, function(data3, menu3) + local reason = data3.value + if reason == nil then + ESX.ShowNotification(TranslateCap("put_something")) + else + menu3.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("players_nearby")) + else + TriggerServerEvent("esx-qalle-jail:jailPlayer", GetPlayerServerId(closestPlayer), jailTime, reason) + end + end + end, function(_, menu3) + menu3.close() + end) + end + end + end, function(_, menu2) + menu2.close() + end) + elseif action == "unjail_player" then + local elements = {} + + ESX.TriggerServerCallback("esx-qalle-jail:retrieveJailedPlayers", function(playerArray) + if #playerArray == 0 then + ESX.ShowNotification(TranslateCap("jail_empty")) + return + end + + for i = 1, #playerArray, 1 do + table.insert(elements, { + label = "Prisoner: " .. playerArray[i].name .. " | Jail Time: " .. playerArray[i].jailTime .. " minutes", + value = playerArray[i].identifier, + }) + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "jailTranslateCapnjail_menu", { + title = "Unjail Player", + align = "center", + elements = elements, + }, function(data2, menu2) + local action = data2.current.value + + TriggerServerEvent("esx-qalle-jail:unJailPlayer", action) + + menu2.close() + end, function(_, menu2) + menu2.close() + end) + end) + end + end, function(_, menu) + menu.close() + end) end diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/client/utils.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/client/utils.lua index a1e7e86ed..3c6992ffe 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/client/utils.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/client/utils.lua @@ -1,188 +1,176 @@ RegisterCommand("jailmenu", function() - if PlayerData.job.name == "police" then - OpenJailMenu() - else - ESX.ShowNotification(_U("not_officer")) - end + if PlayerData.job.name == "police" then + OpenJailMenu() + else + ESX.ShowNotification(TranslateCap("not_officer")) + end end) function LoadAnim(animDict) - RequestAnimDict(animDict) - while not HasAnimDictLoaded(animDict) do - Wait(10) - end + RequestAnimDict(animDict) + while not HasAnimDictLoaded(animDict) do + Wait(10) + end end function LoadModel(model) - RequestModel(model) - while not HasModelLoaded(model) do - Wait(10) - end + RequestModel(model) + while not HasModelLoaded(model) do + Wait(10) + end end function HideHUDThisFrame() - HideHelpTextThisFrame() - HideHudAndRadarThisFrame() - HideHudComponentThisFrame(1) - HideHudComponentThisFrame(2) - HideHudComponentThisFrame(3) - HideHudComponentThisFrame(4) - HideHudComponentThisFrame(6) - HideHudComponentThisFrame(7) - HideHudComponentThisFrame(8) - HideHudComponentThisFrame(9) - HideHudComponentThisFrame(13) - HideHudComponentThisFrame(11) - HideHudComponentThisFrame(12) - HideHudComponentThisFrame(15) - HideHudComponentThisFrame(18) - HideHudComponentThisFrame(19) + HideHelpTextThisFrame() + HideHudAndRadarThisFrame() + HideHudComponentThisFrame(1) + HideHudComponentThisFrame(2) + HideHudComponentThisFrame(3) + HideHudComponentThisFrame(4) + HideHudComponentThisFrame(6) + HideHudComponentThisFrame(7) + HideHudComponentThisFrame(8) + HideHudComponentThisFrame(9) + HideHudComponentThisFrame(13) + HideHudComponentThisFrame(11) + HideHudComponentThisFrame(12) + HideHudComponentThisFrame(15) + HideHudComponentThisFrame(18) + HideHudComponentThisFrame(19) end function Cutscene() - DoScreenFadeOut(100) - - Wait(250) - - local Male = GetHashKey("mp_m_freemode_01") - - TriggerEvent("skinchanger:getSkin", function(skin) - if GetHashKey(GetEntityModel(PlayerPedId())) == Male then - local clothesSkin = { - ["tshirt_1"] = 20, - ["tshirt_2"] = 15, - ["torso_1"] = 33, - ["torso_2"] = 0, - ["arms"] = 0, - ["pants_1"] = 7, - ["pants_2"] = 0, - ["shoes_1"] = 34, - ["shoes_2"] = 0, - } - TriggerEvent("skinchanger:loadClothes", skin, clothesSkin) - else - local clothesSkin = { - ["tshirt_1"] = 15, - ["tshirt_2"] = 0, - ["torso_1"] = 2, - ["torso_2"] = 6, - ["arms"] = 2, - ["pants_1"] = 2, - ["pants_2"] = 0, - ["shoes_1"] = 35, - ["shoes_2"] = 0, - } - TriggerEvent("skinchanger:loadClothes", skin, clothesSkin) - end - end) - - LoadModel(-1320879687) - - local PolicePosition = Config.Cutscene["PolicePosition"] - local Police = CreatePed( - 5, - -1320879687, - PolicePosition["x"], - PolicePosition["y"], - PolicePosition["z"], - PolicePosition["h"], - false - ) - TaskStartScenarioInPlace(Police, "WORLD_HUMAN_PAPARAZZI", 0, false) - - local PlayerPosition = Config.Cutscene["PhotoPosition"] - local PlayerPed = PlayerPedId() - SetEntityCoords(PlayerPed, PlayerPosition["x"], PlayerPosition["y"], PlayerPosition["z"] - 1) - SetEntityHeading(PlayerPed, PlayerPosition["h"]) - FreezeEntityPosition(PlayerPed, true) - - Cam() - Wait(1000) - DoScreenFadeIn(100) - Wait(10000) - DoScreenFadeOut(250) - - local JailPosition = Config.JailPositions["Cell"] - SetEntityCoords(PlayerPed, JailPosition["x"], JailPosition["y"], JailPosition["z"]) - DeleteEntity(Police) - SetModelAsNoLongerNeeded(-1320879687) - - Wait(1000) - DoScreenFadeIn(250) - TriggerServerEvent("InteractSound_SV:PlayOnSource", "cell", 0.3) - RenderScriptCams(false, false, 0, true, true) - FreezeEntityPosition(PlayerPed, false) - DestroyCam(Config.Cutscene["CameraPos"]["cameraId"]) - - InJail() + DoScreenFadeOut(100) + + Wait(250) + + local Male = GetHashKey("mp_m_freemode_01") + + TriggerEvent("skinchanger:getSkin", function(skin) + if GetHashKey(GetEntityModel(PlayerPedId())) == Male then + local clothesSkin = { + ["tshirt_1"] = 20, + ["tshirt_2"] = 15, + ["torso_1"] = 33, + ["torso_2"] = 0, + ["arms"] = 0, + ["pants_1"] = 7, + ["pants_2"] = 0, + ["shoes_1"] = 34, + ["shoes_2"] = 0, + } + TriggerEvent("skinchanger:loadClothes", skin, clothesSkin) + else + local clothesSkin = { + ["tshirt_1"] = 15, + ["tshirt_2"] = 0, + ["torso_1"] = 2, + ["torso_2"] = 6, + ["arms"] = 2, + ["pants_1"] = 2, + ["pants_2"] = 0, + ["shoes_1"] = 35, + ["shoes_2"] = 0, + } + TriggerEvent("skinchanger:loadClothes", skin, clothesSkin) + end + end) + + LoadModel(-1320879687) + + local PolicePosition = Config.Cutscene["PolicePosition"] + local Police = CreatePed(5, -1320879687, PolicePosition["x"], PolicePosition["y"], PolicePosition["z"], PolicePosition["h"], false) + TaskStartScenarioInPlace(Police, "WORLD_HUMAN_PAPARAZZI", 0, false) + + local PlayerPosition = Config.Cutscene["PhotoPosition"] + local PlayerPed = PlayerPedId() + SetEntityCoords(PlayerPed, PlayerPosition["x"], PlayerPosition["y"], PlayerPosition["z"] - 1) + SetEntityHeading(PlayerPed, PlayerPosition["h"]) + FreezeEntityPosition(PlayerPed, true) + + Cam() + Wait(1000) + DoScreenFadeIn(100) + Wait(10000) + DoScreenFadeOut(250) + + local JailPosition = Config.JailPositions["Cell"] + SetEntityCoords(PlayerPed, JailPosition["x"], JailPosition["y"], JailPosition["z"]) + DeleteEntity(Police) + SetModelAsNoLongerNeeded(-1320879687) + + Wait(1000) + DoScreenFadeIn(250) + TriggerServerEvent("InteractSound_SV:PlayOnSource", "cell", 0.3) + RenderScriptCams(false, false, 0, true, true) + FreezeEntityPosition(PlayerPed, false) + DestroyCam(Config.Cutscene["CameraPos"]["cameraId"]) + + InJail() end function Cam() - local CamOptions = Config.Cutscene["CameraPos"] + local CamOptions = Config.Cutscene["CameraPos"] - CamOptions["cameraId"] = CreateCam("DEFAULT_SCRIPTED_CAMERA", true) + CamOptions["cameraId"] = CreateCam("DEFAULT_SCRIPTED_CAMERA", true) - SetCamCoord(CamOptions["cameraId"], CamOptions["x"], CamOptions["y"], CamOptions["z"]) - SetCamRot(CamOptions["cameraId"], CamOptions["rotationX"], CamOptions["rotationY"], CamOptions["rotationZ"]) + SetCamCoord(CamOptions["cameraId"], CamOptions["x"], CamOptions["y"], CamOptions["z"]) + SetCamRot(CamOptions["cameraId"], CamOptions["rotationX"], CamOptions["rotationY"], CamOptions["rotationZ"]) - RenderScriptCams(true, false, 0, true, true) + RenderScriptCams(true, false, 0, true, true) end function TeleportPlayer(pos) - local Values = pos - - if #Values["goal"] > 1 then - local elements = {} - - for _, v in pairs(Values["goal"]) do - table.insert(elements, { label = v, value = v }) - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "teleport_jail", { - title = "Choose Position", - align = "center", - elements = elements, - }, function(data, menu) - local action = data.current.value - local position = Config.Teleports[action] - - if action == "Boiling Broke" or action == "Security" then - if PlayerData.job.name ~= "police" then - ESX.ShowNotification(_U("not_keys")) - return - end - end - menu.close() - DoScreenFadeOut(100) - Wait(250) - SetEntityCoords(PlayerPedId(), position["x"], position["y"], position["z"]) - Wait(250) - DoScreenFadeIn(100) - end, function(_, menu) - menu.close() - end) - else - local position = Config.Teleports[Values["goal"][1]] - DoScreenFadeOut(100) - Wait(250) - SetEntityCoords(PlayerPedId(), position["x"], position["y"], position["z"]) - Wait(250) - DoScreenFadeIn(100) - end + local Values = pos + + if #Values["goal"] > 1 then + local elements = {} + + for _, v in pairs(Values["goal"]) do + table.insert(elements, { label = v, value = v }) + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "teleport_jail", { + title = "Choose Position", + align = "center", + elements = elements, + }, function(data, menu) + local action = data.current.value + local position = Config.Teleports[action] + + if action == "Boiling Broke" or action == "Security" then + if PlayerData.job.name ~= "police" then + ESX.ShowNotification(TranslateCap("not_keys")) + return + end + end + menu.close() + DoScreenFadeOut(100) + Wait(250) + SetEntityCoords(PlayerPedId(), position["x"], position["y"], position["z"]) + Wait(250) + DoScreenFadeIn(100) + end, function(_, menu) + menu.close() + end) + else + local position = Config.Teleports[Values["goal"][1]] + DoScreenFadeOut(100) + Wait(250) + SetEntityCoords(PlayerPedId(), position["x"], position["y"], position["z"]) + Wait(250) + DoScreenFadeIn(100) + end end CreateThread(function() - local blip = AddBlipForCoord( - Config.Teleports["Boiling Broke"]["x"], - Config.Teleports["Boiling Broke"]["y"], - Config.Teleports["Boiling Broke"]["z"] - ) - SetBlipSprite(blip, 188) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 0.8) - SetBlipColour(blip, 49) - SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Boilingbroke Penitentiary") - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Teleports["Boiling Broke"]["x"], Config.Teleports["Boiling Broke"]["y"], Config.Teleports["Boiling Broke"]["z"]) + SetBlipSprite(blip, 188) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 0.8) + SetBlipColour(blip, 49) + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Boilingbroke Penitentiary") + EndTextCommandSetBlipName(blip) end) diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/config.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/config.lua index 0c4f84b2c..904bfe5ea 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/config.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/config.lua @@ -1,106 +1,106 @@ Config = {} Config.Locale = "it" Config.JailPositions = { - ["Cell"] = { ["x"] = 1799.8345947266, ["y"] = 2489.1350097656, ["z"] = -119.02998352051, ["h"] = 179.03021240234 }, + ["Cell"] = { ["x"] = 1799.8345947266, ["y"] = 2489.1350097656, ["z"] = -119.02998352051, ["h"] = 179.03021240234 }, } Config.Cutscene = { - ["PhotoPosition"] = { - ["x"] = 402.91567993164, - ["y"] = -996.75970458984, - ["z"] = -99.000259399414, - ["h"] = 186.22499084473, - }, - ["CameraPos"] = { - ["x"] = 402.88830566406, - ["y"] = -1003.8851318359, - ["z"] = -97.419647216797, - ["rotationX"] = -15.433070763946, - ["rotationY"] = 0.0, - ["rotationZ"] = -0.31496068835258, - ["cameraId"] = 0, - }, - ["PolicePosition"] = { - ["x"] = 402.91702270508, - ["y"] = -1000.6376953125, - ["z"] = -99.004028320313, - ["h"] = 356.88052368164, - }, + ["PhotoPosition"] = { + ["x"] = 402.91567993164, + ["y"] = -996.75970458984, + ["z"] = -99.000259399414, + ["h"] = 186.22499084473, + }, + ["CameraPos"] = { + ["x"] = 402.88830566406, + ["y"] = -1003.8851318359, + ["z"] = -97.419647216797, + ["rotationX"] = -15.433070763946, + ["rotationY"] = 0.0, + ["rotationZ"] = -0.31496068835258, + ["cameraId"] = 0, + }, + ["PolicePosition"] = { + ["x"] = 402.91702270508, + ["y"] = -1000.6376953125, + ["z"] = -99.004028320313, + ["h"] = 356.88052368164, + }, } Config.PrisonWork = { - ["DeliverPackage"] = { - ["x"] = 1027.2347412109, - ["y"] = -3101.419921875, - ["z"] = -38.999870300293, - ["h"] = 267.89135742188, - }, + ["DeliverPackage"] = { + ["x"] = 1027.2347412109, + ["y"] = -3101.419921875, + ["z"] = -38.999870300293, + ["h"] = 267.89135742188, + }, - ["Packages"] = { - [1] = { ["x"] = 1003.6661987305, ["y"] = -3108.4221191406, ["z"] = -38.999866485596, ["state"] = true }, - [2] = { ["x"] = 1006.0420532227, ["y"] = -3103.0024414063, ["z"] = -38.999866485596, ["state"] = true }, - [3] = { ["x"] = 1015.7958374023, ["y"] = -3102.8337402344, ["z"] = -38.99991607666, ["state"] = true }, - [4] = { ["x"] = 1012.8907470703, ["y"] = -3108.2907714844, ["z"] = -38.999912261963, ["state"] = true }, - [5] = { ["x"] = 1018.2017822266, ["y"] = -3109.1982421875, ["z"] = -38.999897003174, ["state"] = true }, - [6] = { ["x"] = 1018.0194091797, ["y"] = -3096.5700683594, ["z"] = -38.999897003174, ["state"] = true }, - [7] = { ["x"] = 1015.6422119141, ["y"] = -3091.7392578125, ["z"] = -38.999897003174, ["state"] = true }, - [8] = { ["x"] = 1010.7862548828, ["y"] = -3096.6135253906, ["z"] = -38.999897003174, ["state"] = true }, - [9] = { ["x"] = 1005.7819824219, ["y"] = -3096.8415527344, ["z"] = -38.999897003174, ["state"] = true }, - [10] = { ["x"] = 1003.4543457031, ["y"] = -3096.7048339844, ["z"] = -38.999897003174, ["state"] = true }, - }, + ["Packages"] = { + [1] = { ["x"] = 1003.6661987305, ["y"] = -3108.4221191406, ["z"] = -38.999866485596, ["state"] = true }, + [2] = { ["x"] = 1006.0420532227, ["y"] = -3103.0024414063, ["z"] = -38.999866485596, ["state"] = true }, + [3] = { ["x"] = 1015.7958374023, ["y"] = -3102.8337402344, ["z"] = -38.99991607666, ["state"] = true }, + [4] = { ["x"] = 1012.8907470703, ["y"] = -3108.2907714844, ["z"] = -38.999912261963, ["state"] = true }, + [5] = { ["x"] = 1018.2017822266, ["y"] = -3109.1982421875, ["z"] = -38.999897003174, ["state"] = true }, + [6] = { ["x"] = 1018.0194091797, ["y"] = -3096.5700683594, ["z"] = -38.999897003174, ["state"] = true }, + [7] = { ["x"] = 1015.6422119141, ["y"] = -3091.7392578125, ["z"] = -38.999897003174, ["state"] = true }, + [8] = { ["x"] = 1010.7862548828, ["y"] = -3096.6135253906, ["z"] = -38.999897003174, ["state"] = true }, + [9] = { ["x"] = 1005.7819824219, ["y"] = -3096.8415527344, ["z"] = -38.999897003174, ["state"] = true }, + [10] = { ["x"] = 1003.4543457031, ["y"] = -3096.7048339844, ["z"] = -38.999897003174, ["state"] = true }, + }, } Config.Teleports = { - ["Prison Work"] = { - ["x"] = 992.51770019531, - ["y"] = -3097.8413085938, - ["z"] = -38.995861053467, - ["h"] = 81.15771484375, - ["goal"] = { - "Jail", - }, - }, + ["Prison Work"] = { + ["x"] = 992.51770019531, + ["y"] = -3097.8413085938, + ["z"] = -38.995861053467, + ["h"] = 81.15771484375, + ["goal"] = { + "Jail", + }, + }, - ["Boiling Broke"] = { - ["x"] = 1845.6022949219, - ["y"] = 2585.8029785156, - ["z"] = 45.672061920166, - ["h"] = 92.469093322754, - ["goal"] = { - "Security", - }, - }, + ["Boiling Broke"] = { + ["x"] = 1845.6022949219, + ["y"] = 2585.8029785156, + ["z"] = 45.672061920166, + ["h"] = 92.469093322754, + ["goal"] = { + "Security", + }, + }, - ["Jail"] = { - ["x"] = 1800.6979980469, - ["y"] = 2483.0979003906, - ["z"] = -122.68814849854, - ["h"] = 271.75274658203, - ["goal"] = { - "Prison Work", - "Security", - "Visitor", - }, - }, + ["Jail"] = { + ["x"] = 1800.6979980469, + ["y"] = 2483.0979003906, + ["z"] = -122.68814849854, + ["h"] = 271.75274658203, + ["goal"] = { + "Prison Work", + "Security", + "Visitor", + }, + }, - ["Security"] = { - ["x"] = 1706.7625732422, - ["y"] = 2581.0793457031, - ["z"] = -69.407371520996, - ["h"] = 267.72802734375, - ["goal"] = { - "Jail", - "Boiling Broke", - }, - }, + ["Security"] = { + ["x"] = 1706.7625732422, + ["y"] = 2581.0793457031, + ["z"] = -69.407371520996, + ["h"] = 267.72802734375, + ["goal"] = { + "Jail", + "Boiling Broke", + }, + }, - ["Visitor"] = { - ["x"] = 1699.7196044922, - ["y"] = 2574.5314941406, - ["z"] = -69.403930664063, - ["h"] = 169.65020751953, - ["goal"] = { - "Jail", - }, - }, + ["Visitor"] = { + ["x"] = 1699.7196044922, + ["y"] = 2574.5314941406, + ["z"] = -69.403930664063, + ["h"] = 169.65020751953, + ["goal"] = { + "Jail", + }, + }, } diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/fxmanifest.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/fxmanifest.lua index d51bfdd37..04b57106e 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/fxmanifest.lua @@ -8,16 +8,16 @@ description("Jail Script With Working Job") shared_script("@es_extended/imports.lua") server_scripts({ - "@es_extended/locale.lua", - "@mysql-async/lib/MySQL.lua", - "config.lua", - "locales/*.lua", - "server/server.lua", + "@es_extended/locale.lua", + "@mysql-async/lib/MySQL.lua", + "config.lua", + "locales/*.lua", + "server/server.lua", }) client_scripts({ - "@es_extended/locale.lua", - "config.lua", - "client/*.lua", - "locales/*.lua", + "@es_extended/locale.lua", + "config.lua", + "client/*.lua", + "locales/*.lua", }) diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/locales/en.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/locales/en.lua index f7ff3f77a..b7c2b9d05 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/locales/en.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/locales/en.lua @@ -1,16 +1,16 @@ Locales["en"] = { - ["not_keys"] = "You don't have an key to go here!", - ["back_in_jail"] = "Last time you went to sleep you were imprisoned, so now you're here again!", - ["you_released"] = "You are released, keep calm outside! Good luck", - ["few_minutes"] = "You have minutes left in jail!", - ["package_taken"] = "You've already taken this package", - ["canceled"] = "Canceled", - ["time_minutes"] = "The time needs to be in minutes!", - ["players_nearb"] = "No players nearby!", - ["put_something"] = "You need to put something here!", - ["jail_empty"] = "Your jail is empty!", - ["not_officer"] = "You are not an officer!", - ["invalid_time"] = "This time is invalid", - ["id_not_online"] = "This ID is not online", - ["money_for_food"] = "Here you have som cash for food!", + ["not_keys"] = "You don't have an key to go here!", + ["back_in_jail"] = "Last time you went to sleep you were imprisoned, so now you're here again!", + ["you_released"] = "You are released, keep calm outside! Good luck", + ["few_minutes"] = "You have minutes left in jail!", + ["package_taken"] = "You've already taken this package", + ["canceled"] = "Canceled", + ["time_minutes"] = "The time needs to be in minutes!", + ["players_nearb"] = "No players nearby!", + ["put_something"] = "You need to put something here!", + ["jail_empty"] = "Your jail is empty!", + ["not_officer"] = "You are not an officer!", + ["invalid_time"] = "This time is invalid", + ["id_not_online"] = "This ID is not online", + ["money_for_food"] = "Here you have som cash for food!", } diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/locales/it.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/locales/it.lua index c6870b3f7..550d1d0c9 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/locales/it.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/locales/it.lua @@ -1,16 +1,16 @@ Locales["it"] = { - ["not_keys"] = "Non hai una chiave per andare qui!", - ["back_in_jail"] = "L'ultima volta che sei andato a dormire eri stato imprigionato, quindi ora sei di nuovo qui!", - ["you_released"] = "Sei libero, mantieni la calma li fuori! Buona fortuna", - ["few_minutes"] = "Ti restano pochi minuti di prigione!", - ["package_taken"] = "Hai già preso questo pacchetto", - ["canceled"] = "Annullata", - ["time_minutes"] = "Il tempo deve essere in minuti!", - ["players_nearb"] = "Nessun giocatore nelle vicinanze!", - ["put_something"] = "Devi mettere qualcosa qui!", - ["jail_empty"] = "La tua prigione è vuota!", - ["not_officer"] = "Non sei un ufficiale!", - ["invalid_time"] = "Questo tempo non è valido", - ["id_not_online"] = "Questo ID non è online", - ["money_for_food"] = "Eccoti un po' di soldi per il cibo!", + ["not_keys"] = "Non hai una chiave per andare qui!", + ["back_in_jail"] = "L'ultima volta che sei andato a dormire eri stato imprigionato, quindi ora sei di nuovo qui!", + ["you_released"] = "Sei libero, mantieni la calma li fuori! Buona fortuna", + ["few_minutes"] = "Ti restano pochi minuti di prigione!", + ["package_taken"] = "Hai già preso questo pacchetto", + ["canceled"] = "Annullata", + ["time_minutes"] = "Il tempo deve essere in minuti!", + ["players_nearb"] = "Nessun giocatore nelle vicinanze!", + ["put_something"] = "Devi mettere qualcosa qui!", + ["jail_empty"] = "La tua prigione è vuota!", + ["not_officer"] = "Non sei un ufficiale!", + ["invalid_time"] = "Questo tempo non è valido", + ["id_not_online"] = "Questo ID non è online", + ["money_for_food"] = "Eccoti un po' di soldi per il cibo!", } diff --git a/server-data/resources/[esx_addons]/esx-qalle-jail/server/server.lua b/server-data/resources/[esx_addons]/esx-qalle-jail/server/server.lua index 3fe5a2cc8..714ab5900 100644 --- a/server-data/resources/[esx_addons]/esx-qalle-jail/server/server.lua +++ b/server-data/resources/[esx_addons]/esx-qalle-jail/server/server.lua @@ -1,200 +1,169 @@ ESX = exports["es_extended"]:getSharedObject() RegisterCommand("jail", function(src, args) - local xPlayer = ESX.GetPlayerFromId(src) - - if xPlayer["job"]["name"] == "police" then - local jailPlayer = args[1] - local jailTime = tonumber(args[2]) - local jailReason = args[3] - - if GetPlayerName(jailPlayer) ~= nil then - if jailTime ~= nil then - JailPlayer(jailPlayer, jailTime) - - TriggerClientEvent( - "esx:showNotification", - src, - GetPlayerName(jailPlayer) .. " Jailed for " .. jailTime .. " minutes!" - ) - - if args[3] ~= nil then - GetRPName(jailPlayer, function(Firstname, Lastname) - TriggerClientEvent( - "chat:addMessage", - -1, - { - args = { - "JUDGE", - Firstname .. " " .. Lastname .. " Is now in jail for the reason: " .. args[3], - }, - color = { 249, 166, 0 }, - } - ) - end) - end - else - TriggerClientEvent("esx:showNotification", src, _U("invalid_time")) - end - else - TriggerClientEvent("esx:showNotification", src, _U("id_not_online")) - end - else - TriggerClientEvent("esx:showNotification", src, _U("not_officer")) - end + local xPlayer = ESX.GetPlayerFromId(src) + + if xPlayer["job"]["name"] == "police" then + local jailPlayer = args[1] + local jailTime = tonumber(args[2]) + local jailReason = args[3] + + if GetPlayerName(jailPlayer) ~= nil then + if jailTime ~= nil then + JailPlayer(jailPlayer, jailTime) + + TriggerClientEvent("esx:showNotification", src, GetPlayerName(jailPlayer) .. " Jailed for " .. jailTime .. " minutes!") + + if args[3] ~= nil then + GetRPName(jailPlayer, function(Firstname, Lastname) + TriggerClientEvent("chat:addMessage", -1, { + args = { + "JUDGE", + Firstname .. " " .. Lastname .. " Is now in jail for the reason: " .. args[3], + }, + color = { 249, 166, 0 }, + }) + end) + end + else + TriggerClientEvent("esx:showNotification", src, TranslateCap("invalid_time")) + end + else + TriggerClientEvent("esx:showNotification", src, TranslateCap("id_not_online")) + end + else + TriggerClientEvent("esx:showNotification", src, TranslateCap("not_officer")) + end end) RegisterCommand("unjail", function(src, args) - local xPlayer = ESX.GetPlayerFromId(src) - - if xPlayer["job"]["name"] == "police" then - local jailPlayer = args[1] - - if GetPlayerName(jailPlayer) ~= nil then - UnJail(jailPlayer) - else - TriggerClientEvent("esx:showNotification", src, _U("id_not_online")) - end - else - TriggerClientEvent("esx:showNotification", src, _U("not_officer")) - end + local xPlayer = ESX.GetPlayerFromId(src) + + if xPlayer["job"]["name"] == "police" then + local jailPlayer = args[1] + + if GetPlayerName(jailPlayer) ~= nil then + UnJail(jailPlayer) + else + TriggerClientEvent("esx:showNotification", src, TranslateCap("id_not_online")) + end + else + TriggerClientEvent("esx:showNotification", src, TranslateCap("not_officer")) + end end) RegisterServerEvent("esx-qalle-jail:jailPlayer") AddEventHandler("esx-qalle-jail:jailPlayer", function(targetSrc, jailTime, jailReason) - local src = source - local targetSrc = tonumber(targetSrc) - local xPlayer = ESX.GetPlayerFromId(src) - - if xPlayer.job.name == "police" then - JailPlayer(targetSrc, jailTime) - - GetRPName(targetSrc, function(Firstname, Lastname) - TriggerClientEvent( - "chat:addMessage", - -1, - { - args = { "JUDGE", Firstname .. " " .. Lastname .. " Is now in jail for the reason: " .. jailReason }, - color = { 249, 166, 0 }, - } - ) - end) - else - DropPlayer(src, "[esx-qalle-jail]: You have been kicked for trying to exploit a server event.") - end - - TriggerClientEvent( - "esx:showNotification", - src, - GetPlayerName(targetSrc) .. " Jailed for " .. jailTime .. " minutes!" - ) + local src = source + local targetSrc = tonumber(targetSrc) + local xPlayer = ESX.GetPlayerFromId(src) + + if xPlayer.job.name == "police" then + JailPlayer(targetSrc, jailTime) + + GetRPName(targetSrc, function(Firstname, Lastname) + TriggerClientEvent("chat:addMessage", -1, { + args = { "JUDGE", Firstname .. " " .. Lastname .. " Is now in jail for the reason: " .. jailReason }, + color = { 249, 166, 0 }, + }) + end) + else + DropPlayer(src, "[esx-qalle-jail]: You have been kicked for trying to exploit a server event.") + end + + TriggerClientEvent("esx:showNotification", src, GetPlayerName(targetSrc) .. " Jailed for " .. jailTime .. " minutes!") end) RegisterServerEvent("esx-qalle-jail:unJailPlayer") AddEventHandler("esx-qalle-jail:unJailPlayer", function(targetIdentifier) - local src = source - local xPlayer = ESX.GetPlayerFromIdentifier(targetIdentifier) - - if xPlayer ~= nil then - UnJail(xPlayer.source) - else - MySQL.Async.execute("UPDATE users SET jail = @newJailTime WHERE identifier = @identifier", { - ["@identifier"] = targetIdentifier, - ["@newJailTime"] = 0, - }) - end - - TriggerClientEvent("esx:showNotification", src, xPlayer.name .. " Unjailed!") + local src = source + local xPlayer = ESX.GetPlayerFromIdentifier(targetIdentifier) + + if xPlayer ~= nil then + UnJail(xPlayer.source) + else + MySQL.Async.execute("UPDATE users SET jail = @newJailTime WHERE identifier = @identifier", { + ["@identifier"] = targetIdentifier, + ["@newJailTime"] = 0, + }) + end + + TriggerClientEvent("esx:showNotification", src, xPlayer.name .. " Unjailed!") end) RegisterServerEvent("esx-qalle-jail:updateJailTime") AddEventHandler("esx-qalle-jail:updateJailTime", function(newJailTime) - local src = source + local src = source - EditJailTime(src, newJailTime) + EditJailTime(src, newJailTime) end) RegisterServerEvent("esx-qalle-jail:prisonWorkReward") AddEventHandler("esx-qalle-jail:prisonWorkReward", function() - local src = source - local xPlayer = ESX.GetPlayerFromId(src) - xPlayer.addMoney(math.random(13, 21)) - TriggerClientEvent("esx:showNotification", src, _U("money_for_food")) + local src = source + local xPlayer = ESX.GetPlayerFromId(src) + xPlayer.addMoney(math.random(13, 21)) + TriggerClientEvent("esx:showNotification", src, TranslateCap("money_for_food")) end) function JailPlayer(jailPlayer, jailTime) - TriggerClientEvent("esx-qalle-jail:jailPlayer", jailPlayer, jailTime) + TriggerClientEvent("esx-qalle-jail:jailPlayer", jailPlayer, jailTime) - EditJailTime(jailPlayer, jailTime) + EditJailTime(jailPlayer, jailTime) end function UnJail(jailPlayer) - TriggerClientEvent("esx-qalle-jail:unJailPlayer", jailPlayer) + TriggerClientEvent("esx-qalle-jail:unJailPlayer", jailPlayer) - EditJailTime(jailPlayer, 0) + EditJailTime(jailPlayer, 0) end function EditJailTime(source, jailTime) - local src = source - local xPlayer = ESX.GetPlayerFromId(src) - local Identifier = xPlayer.identifier - - MySQL.Async.execute("UPDATE users SET jail = @newJailTime WHERE identifier = @identifier", { - ["@identifier"] = Identifier, - ["@newJailTime"] = tonumber(jailTime), - }) + local src = source + local xPlayer = ESX.GetPlayerFromId(src) + local Identifier = xPlayer.identifier + + MySQL.Async.execute("UPDATE users SET jail = @newJailTime WHERE identifier = @identifier", { + ["@identifier"] = Identifier, + ["@newJailTime"] = tonumber(jailTime), + }) end function GetRPName(playerId, data) - local Identifier = ESX.GetPlayerFromId(playerId).identifier - - MySQL.Async.fetchAll( - "SELECT firstname, lastname FROM users WHERE identifier = @identifier", - { ["@identifier"] = Identifier }, - function(result) - data(result[1].firstname, result[1].lastname) - end - ) + local Identifier = ESX.GetPlayerFromId(playerId).identifier + + MySQL.Async.fetchAll("SELECT firstname, lastname FROM users WHERE identifier = @identifier", { ["@identifier"] = Identifier }, function(result) + data(result[1].firstname, result[1].lastname) + end) end ESX.RegisterServerCallback("esx-qalle-jail:retrieveJailedPlayers", function(_, cb) - local jailedPersons = {} - - MySQL.Async.fetchAll( - "SELECT firstname, lastname, jail, identifier FROM users WHERE jail > @jail", - { ["@jail"] = 0 }, - function(result) - for i = 1, #result, 1 do - table.insert( - jailedPersons, - { - name = result[i].firstname .. " " .. result[i].lastname, - jailTime = result[i].jail, - identifier = result[i].identifier, - } - ) - end - cb(jailedPersons) - end - ) + local jailedPersons = {} + + MySQL.Async.fetchAll("SELECT firstname, lastname, jail, identifier FROM users WHERE jail > @jail", { ["@jail"] = 0 }, function(result) + for i = 1, #result, 1 do + table.insert(jailedPersons, { + name = result[i].firstname .. " " .. result[i].lastname, + jailTime = result[i].jail, + identifier = result[i].identifier, + }) + end + cb(jailedPersons) + end) end) ESX.RegisterServerCallback("esx-qalle-jail:retrieveJailTime", function(source, cb) - local src = source - local xPlayer = ESX.GetPlayerFromId(src) - local Identifier = xPlayer.identifier - - MySQL.Async.fetchAll( - "SELECT jail FROM users WHERE identifier = @identifier", - { ["@identifier"] = Identifier }, - function(result) - local JailTime = tonumber(result[1].jail) - - if JailTime > 0 then - cb(true, JailTime) - else - cb(false, 0) - end - end - ) + local src = source + local xPlayer = ESX.GetPlayerFromId(src) + local Identifier = xPlayer.identifier + + MySQL.Async.fetchAll("SELECT jail FROM users WHERE identifier = @identifier", { ["@identifier"] = Identifier }, function(result) + local JailTime = tonumber(result[1].jail) + + if JailTime > 0 then + cb(true, JailTime) + else + cb(false, 0) + end + end) end) diff --git a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/client.lua b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/client.lua index e21e04bae..1def389af 100644 --- a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/client.lua +++ b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/client.lua @@ -1,464 +1,389 @@ -local pedInSameVehicleLast = false -local vehicle -local lastVehicle -local vehicleClass +local pedInSameVehicleLast, isBrakingForward, isBrakingReverse = false, false, false +local vehicle, lastVehicle, vehicleClass, tireBurstLuckyNumber local fCollisionDamageMult = 0.0 local fDeformationDamageMult = 0.0 local fEngineDamageMult = 0.0 local fBrakeForce = 1.0 -local isBrakingForward = false -local isBrakingReverse = false - local healthEngineLast = 1000.0 local healthEngineCurrent = 1000.0 local healthEngineNew = 1000.0 local healthEngineDelta = 0.0 local healthEngineDeltaScaled = 0.0 - local healthBodyLast = 1000.0 local healthBodyCurrent = 1000.0 local healthBodyNew = 1000.0 local healthBodyDelta = 0.0 local healthBodyDeltaScaled = 0.0 - local healthPetrolTankLast = 1000.0 local healthPetrolTankCurrent = 1000.0 local healthPetrolTankNew = 1000.0 local healthPetrolTankDelta = 0.0 local healthPetrolTankDeltaScaled = 0.0 -local tireBurstLuckyNumber + +ESX = exports["es_extended"]:getSharedObject() math.randomseed(GetGameTimer()) local tireBurstMaxNumber = cfg.randomTireBurstInterval * 1200 -- the tire burst lottery runs roughly 1200 times per minute if cfg.randomTireBurstInterval ~= 0 then - tireBurstLuckyNumber = math.random(tireBurstMaxNumber) + tireBurstLuckyNumber = math.random(tireBurstMaxNumber) end -- If we hit this number again randomly, a tire will burst. Citizen.CreateThread(function() - ESX = exports["es_extended"]:getSharedObject() - - while ESX.GetPlayerData().job == nil do - Citizen.Wait(10) - end - - PlayerData = ESX.GetPlayerData() + while ESX.GetPlayerData().job == nil do + Citizen.Wait(10) + end + PlayerData = ESX.GetPlayerData() end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - PlayerData.job = job + PlayerData.job = job end) -local function notification(msg) - SetNotificationTextEntry("STRING") - AddTextComponentString(msg) - DrawNotification(false, false) -end - local function isPedDrivingAVehicle() - local ped = GetPlayerPed(-1) - vehicle = GetVehiclePedIsIn(ped, false) - if IsPedInAnyVehicle(ped, false) then - -- Check if ped is in driver seat - if GetPedInVehicleSeat(vehicle, -1) == ped then - local class = GetVehicleClass(vehicle) - -- We don't want planes, helicopters, bicycles and trains - if class ~= 15 and class ~= 16 and class ~= 21 and class ~= 13 then - return true - end - end - end - return false + local ped = GetPlayerPed(-1) + vehicle = GetVehiclePedIsIn(ped, false) + if IsPedInAnyVehicle(ped, false) then + -- Check if ped is in driver seat + if GetPedInVehicleSeat(vehicle, -1) == ped then + local class = GetVehicleClass(vehicle) + -- We don't want planes, helicopters, bicycles and trains + if class ~= 15 and class ~= 16 and class ~= 21 and class ~= 13 then + return true + end + end + end + return false end local function fscale(inputValue, originalMin, originalMax, newBegin, newEnd, curve) - local OriginalRange = 0.0 - local NewRange = 0.0 - local zeroRefCurVal = 0.0 - local normalizedCurVal = 0.0 - local rangedValue = 0.0 - local invFlag = 0 - - if curve > 10.0 then - curve = 10.0 - end - if curve < -10.0 then - curve = -10.0 - end - - curve = (curve * -0.1) - curve = 10.0 ^ curve - - if inputValue < originalMin then - inputValue = originalMin - end - if inputValue > originalMax then - inputValue = originalMax - end - - OriginalRange = originalMax - originalMin - - if newEnd > newBegin then - NewRange = newEnd - newBegin - else - NewRange = newBegin - newEnd - invFlag = 1 - end - - zeroRefCurVal = inputValue - originalMin - normalizedCurVal = zeroRefCurVal / OriginalRange - - if originalMin > originalMax then - return 0 - end - - if invFlag == 0 then - rangedValue = ((normalizedCurVal ^ curve) * NewRange) + newBegin - else - rangedValue = newBegin - ((normalizedCurVal ^ curve) * NewRange) - end - - return rangedValue + local OriginalRange = 0.0 + local NewRange = 0.0 + local zeroRefCurVal = 0.0 + local normalizedCurVal = 0.0 + local rangedValue = 0.0 + local invFlag = 0 + + if curve > 10.0 then + curve = 10.0 + end + if curve < -10.0 then + curve = -10.0 + end + + curve = (curve * -0.1) + curve = 10.0 ^ curve + + if inputValue < originalMin then + inputValue = originalMin + end + if inputValue > originalMax then + inputValue = originalMax + end + + OriginalRange = originalMax - originalMin + + if newEnd > newBegin then + NewRange = newEnd - newBegin + else + NewRange = newBegin - newEnd + invFlag = 1 + end + + zeroRefCurVal = inputValue - originalMin + normalizedCurVal = zeroRefCurVal / OriginalRange + + if originalMin > originalMax then + return 0 + end + + if invFlag == 0 then + rangedValue = ((normalizedCurVal ^ curve) * NewRange) + newBegin + else + rangedValue = newBegin - ((normalizedCurVal ^ curve) * NewRange) + end + + return rangedValue end local function tireBurstLottery() - local tireBurstNumber = math.random(tireBurstMaxNumber) - if tireBurstNumber == tireBurstLuckyNumber then - -- We won the lottery, lets burst a tire. - if GetVehicleTyresCanBurst(vehicle) == false then - return - end - local numWheels = GetVehicleNumberOfWheels(vehicle) - local affectedTire - if numWheels == 2 then - affectedTire = (math.random(2) - 1) * 4 -- wheel 0 or 4 - elseif numWheels == 4 then - affectedTire = (math.random(4) - 1) - if affectedTire > 1 then - affectedTire = affectedTire + 2 - end -- 0, 1, 4, 5 - elseif numWheels == 6 then - affectedTire = (math.random(6) - 1) - else - affectedTire = 0 - end - SetVehicleTyreBurst(vehicle, affectedTire, false, 1000.0) - tireBurstLuckyNumber = math.random(tireBurstMaxNumber) -- Select a new number to hit, just in case some numbers occur more often than others - end + local tireBurstNumber = math.random(tireBurstMaxNumber) + if tireBurstNumber == tireBurstLuckyNumber then + -- We won the lottery, lets burst a tire. + if GetVehicleTyresCanBurst(vehicle) == false then + return + end + local numWheels = GetVehicleNumberOfWheels(vehicle) + local affectedTire + if numWheels == 2 then + affectedTire = (math.random(2) - 1) * 4 -- wheel 0 or 4 + elseif numWheels == 4 then + affectedTire = (math.random(4) - 1) + if affectedTire > 1 then + affectedTire = affectedTire + 2 + end -- 0, 1, 4, 5 + elseif numWheels == 6 then + affectedTire = (math.random(6) - 1) + else + affectedTire = 0 + end + SetVehicleTyreBurst(vehicle, affectedTire, false, 1000.0) + tireBurstLuckyNumber = math.random(tireBurstMaxNumber) -- Select a new number to hit, just in case some numbers occur more often than others + end end if cfg.torqueMultiplierEnabled or cfg.preventVehicleFlip or cfg.limpMode then - Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - if cfg.torqueMultiplierEnabled or cfg.sundayDriver or cfg.limpMode then - if pedInSameVehicleLast then - local factor = 1.0 - if cfg.torqueMultiplierEnabled and healthEngineNew < 900 then - factor = (healthEngineNew + 200.0) / 1100 - end - if cfg.sundayDriver and GetVehicleClass(vehicle) ~= 14 then -- Not for boats - local accelerator = GetControlValue(2, 71) - local brake = GetControlValue(2, 72) - local speed = GetEntitySpeedVector(vehicle, true)["y"] - -- Change Braking force - local brk = fBrakeForce - if speed >= 1.0 then - -- Going forward - if accelerator > 127 then - -- Forward and accelerating - local acc = fscale( - accelerator, - 127.0, - 254.0, - 0.1, - 1.0, - 10.0 - (cfg.sundayDriverAcceleratorCurve * 2.0) - ) - factor = factor * acc - end - if brake > 127 then - -- Forward and braking - isBrakingForward = true - brk = fscale( - brake, - 127.0, - 254.0, - 0.01, - fBrakeForce, - 10.0 - (cfg.sundayDriverBrakeCurve * 2.0) - ) - end - elseif speed <= -1.0 then - -- Going reverse - if brake > 127 then - -- Reversing and accelerating (using the brake) - local rev = fscale( - brake, - 127.0, - 254.0, - 0.1, - 1.0, - 10.0 - (cfg.sundayDriverAcceleratorCurve * 2.0) - ) - factor = factor * rev - end - if accelerator > 127 then - -- Reversing and braking (Using the accelerator) - isBrakingReverse = true - brk = fscale( - accelerator, - 127.0, - 254.0, - 0.01, - fBrakeForce, - 10.0 - (cfg.sundayDriverBrakeCurve * 2.0) - ) - end - else - -- Stopped or almost stopped or sliding sideways - local entitySpeed = GetEntitySpeed(vehicle) - if entitySpeed < 1 then - -- Not sliding sideways - if isBrakingForward == true then - --Stopped or going slightly forward while braking - DisableControlAction(2, 72, true) -- Disable Brake until user lets go of brake - SetVehicleForwardSpeed(vehicle, speed * 0.98) - SetVehicleBrakeLights(vehicle, true) - end - if isBrakingReverse == true then - --Stopped or going slightly in reverse while braking - DisableControlAction(2, 71, true) -- Disable reverse Brake until user lets go of reverse brake (Accelerator) - SetVehicleForwardSpeed(vehicle, speed * 0.98) - SetVehicleBrakeLights(vehicle, true) - end - if isBrakingForward == true and GetDisabledControlNormal(2, 72) == 0 then - -- We let go of the brake - isBrakingForward = false - end - if isBrakingReverse == true and GetDisabledControlNormal(2, 71) == 0 then - -- We let go of the reverse brake (Accelerator) - isBrakingReverse = false - end - end - end - if brk > fBrakeForce - 0.02 then - brk = fBrakeForce - end -- Make sure we can brake max. - SetVehicleHandlingFloat(vehicle, "CHandlingData", "fBrakeForce", brk) -- Set new Brake Force multiplier - end - if cfg.limpMode == true and healthEngineNew < cfg.engineSafeGuard + 5 then - factor = cfg.limpModeMultiplier - end - SetVehicleEngineTorqueMultiplier(vehicle, factor) - end - end - if cfg.preventVehicleFlip then - local roll = GetEntityRoll(vehicle) - if (roll > 75.0 or roll < -75.0) and GetEntitySpeed(vehicle) < 2 then - DisableControlAction(2, 59, true) -- Disable left/right - DisableControlAction(2, 60, true) -- Disable up/down - end - end - end - end) + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if cfg.torqueMultiplierEnabled or cfg.sundayDriver or cfg.limpMode then + if pedInSameVehicleLast then + local factor = 1.0 + if cfg.torqueMultiplierEnabled and healthEngineNew < 900 then + factor = (healthEngineNew + 200.0) / 1100 + end + if cfg.sundayDriver and GetVehicleClass(vehicle) ~= 14 then -- Not for boats + local accelerator = GetControlValue(2, 71) + local brake = GetControlValue(2, 72) + local speed = GetEntitySpeedVector(vehicle, true)["y"] + -- Change Braking force + local brk = fBrakeForce + if speed >= 1.0 then + -- Going forward + if accelerator > 127 then + -- Forward and accelerating + local acc = fscale(accelerator, 127.0, 254.0, 0.1, 1.0, 10.0 - (cfg.sundayDriverAcceleratorCurve * 2.0)) + factor = factor * acc + end + if brake > 127 then + -- Forward and braking + isBrakingForward = true + brk = fscale(brake, 127.0, 254.0, 0.01, fBrakeForce, 10.0 - (cfg.sundayDriverBrakeCurve * 2.0)) + end + elseif speed <= -1.0 then + -- Going reverse + if brake > 127 then + -- Reversing and accelerating (using the brake) + local rev = fscale(brake, 127.0, 254.0, 0.1, 1.0, 10.0 - (cfg.sundayDriverAcceleratorCurve * 2.0)) + factor = factor * rev + end + if accelerator > 127 then + -- Reversing and braking (Using the accelerator) + isBrakingReverse = true + brk = fscale(accelerator, 127.0, 254.0, 0.01, fBrakeForce, 10.0 - (cfg.sundayDriverBrakeCurve * 2.0)) + end + else + -- Stopped or almost stopped or sliding sideways + local entitySpeed = GetEntitySpeed(vehicle) + if entitySpeed < 1 then + -- Not sliding sideways + if isBrakingForward == true then + --Stopped or going slightly forward while braking + DisableControlAction(2, 72, true) -- Disable Brake until user lets go of brake + SetVehicleForwardSpeed(vehicle, speed * 0.98) + SetVehicleBrakeLights(vehicle, true) + end + if isBrakingReverse == true then + --Stopped or going slightly in reverse while braking + DisableControlAction(2, 71, true) -- Disable reverse Brake until user lets go of reverse brake (Accelerator) + SetVehicleForwardSpeed(vehicle, speed * 0.98) + SetVehicleBrakeLights(vehicle, true) + end + if isBrakingForward == true and GetDisabledControlNormal(2, 72) == 0 then + -- We let go of the brake + isBrakingForward = false + end + if isBrakingReverse == true and GetDisabledControlNormal(2, 71) == 0 then + -- We let go of the reverse brake (Accelerator) + isBrakingReverse = false + end + end + end + if brk > fBrakeForce - 0.02 then + brk = fBrakeForce + end -- Make sure we can brake max. + SetVehicleHandlingFloat(vehicle, "CHandlingData", "fBrakeForce", brk) -- Set new Brake Force multiplier + end + if cfg.limpMode == true and healthEngineNew < cfg.engineSafeGuard + 5 then + factor = cfg.limpModeMultiplier + end + SetVehicleEngineTorqueMultiplier(vehicle, factor) + end + end + if cfg.preventVehicleFlip then + local roll = GetEntityRoll(vehicle) + if (roll > 75.0 or roll < -75.0) and GetEntitySpeed(vehicle) < 2 then + DisableControlAction(2, 59, true) -- Disable left/right + DisableControlAction(2, 60, true) -- Disable up/down + end + end + end + end) end Citizen.CreateThread(function() - while true do - Citizen.Wait(50) - local ped = GetPlayerPed(-1) - if isPedDrivingAVehicle() then - vehicle = GetVehiclePedIsIn(ped, false) - vehicleClass = GetVehicleClass(vehicle) - healthEngineCurrent = GetVehicleEngineHealth(vehicle) - if healthEngineCurrent == 1000 then - healthEngineLast = 1000.0 - end - healthEngineNew = healthEngineCurrent - healthEngineDelta = healthEngineLast - healthEngineCurrent - healthEngineDeltaScaled = healthEngineDelta - * cfg.damageFactorEngine - * cfg.classDamageMultiplier[vehicleClass] - - healthBodyCurrent = GetVehicleBodyHealth(vehicle) - if healthBodyCurrent == 1000 then - healthBodyLast = 1000.0 - end - healthBodyNew = healthBodyCurrent - healthBodyDelta = healthBodyLast - healthBodyCurrent - healthBodyDeltaScaled = healthBodyDelta * cfg.damageFactorBody * cfg.classDamageMultiplier[vehicleClass] - - healthPetrolTankCurrent = GetVehiclePetrolTankHealth(vehicle) - if cfg.compatibilityMode and healthPetrolTankCurrent < 1 then - healthPetrolTankLast = healthPetrolTankCurrent - end - if healthPetrolTankCurrent == 1000 then - healthPetrolTankLast = 1000.0 - end - healthPetrolTankNew = healthPetrolTankCurrent - healthPetrolTankDelta = healthPetrolTankLast - healthPetrolTankCurrent - healthPetrolTankDeltaScaled = healthPetrolTankDelta - * cfg.damageFactorPetrolTank - * cfg.classDamageMultiplier[vehicleClass] - - if healthEngineCurrent > cfg.engineSafeGuard + 1 then - SetVehicleUndriveable(vehicle, false) - end - - if healthEngineCurrent <= cfg.engineSafeGuard + 1 and cfg.limpMode == false then - SetVehicleUndriveable(vehicle, true) - end - - -- If ped spawned a new vehicle while in a vehicle or teleported from one vehicle to another, handle as if we just entered the car - if vehicle ~= lastVehicle then - pedInSameVehicleLast = false - end - - if pedInSameVehicleLast == true then - -- Damage happened while in the car = can be multiplied - - -- Only do calculations if any damage is present on the car. Prevents weird behavior when fixing using trainer or other script - if - healthEngineCurrent ~= 1000.0 - or healthBodyCurrent ~= 1000.0 - or healthPetrolTankCurrent ~= 1000.0 - then - -- Combine the delta values (Get the largest of the three) - local healthEngineCombinedDelta = - math.max(healthEngineDeltaScaled, healthBodyDeltaScaled, healthPetrolTankDeltaScaled) - - -- If huge damage, scale back a bit - if healthEngineCombinedDelta > (healthEngineCurrent - cfg.engineSafeGuard) then - healthEngineCombinedDelta = healthEngineCombinedDelta * 0.7 - end - - -- If complete damage, but not catastrophic (ie. explosion territory) pull back a bit, to give a couple of seconds og engine runtime before dying - if healthEngineCombinedDelta > healthEngineCurrent then - healthEngineCombinedDelta = healthEngineCurrent - (cfg.cascadingFailureThreshold / 5) - end - - ------- Calculate new value - healthEngineNew = healthEngineLast - healthEngineCombinedDelta - - ------- Sanity Check on new values and further manipulations - - -- If somewhat damaged, slowly degrade until slightly before cascading failure sets in, then stop - - if - healthEngineNew > (cfg.cascadingFailureThreshold + 5) - and healthEngineNew < cfg.degradingFailureThreshold - then - healthEngineNew = healthEngineNew - (0.038 * cfg.degradingHealthSpeedFactor) - end - - -- If Damage is near catastrophic, cascade the failure - if healthEngineNew < cfg.cascadingFailureThreshold then - healthEngineNew = healthEngineNew - (0.1 * cfg.cascadingFailureSpeedFactor) - end - - -- Prevent Engine going to or below zero. Ensures you can reenter a damaged car. - if healthEngineNew < cfg.engineSafeGuard then - healthEngineNew = cfg.engineSafeGuard - end - - -- Prevent Explosions - if cfg.compatibilityMode == false and healthPetrolTankCurrent < 750 then - healthPetrolTankNew = 750.0 - end - - -- Prevent negative body damage. - if healthBodyNew < 0 then - healthBodyNew = 0.0 - end - end - else - -- Just got in the vehicle. Damage can not be multiplied this round - -- Set vehicle handling data - fDeformationDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fDeformationDamageMult") - fBrakeForce = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fBrakeForce") - local newFDeformationDamageMult = fDeformationDamageMult ^ cfg.deformationExponent -- Pull the handling file value closer to 1 - if cfg.deformationMultiplier ~= -1 then - SetVehicleHandlingFloat( - vehicle, - "CHandlingData", - "fDeformationDamageMult", - newFDeformationDamageMult * cfg.deformationMultiplier - ) - end -- Multiply by our factor - if cfg.weaponsDamageMultiplier ~= -1 then - SetVehicleHandlingFloat( - vehicle, - "CHandlingData", - "fWeaponDamageMult", - cfg.weaponsDamageMultiplier / cfg.damageFactorBody - ) - end -- Set weaponsDamageMultiplier and compensate for damageFactorBody - - --Get the CollisionDamageMultiplier - fCollisionDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fCollisionDamageMult") - --Modify it by pulling all number a towards 1.0 - local newFCollisionDamageMultiplier = fCollisionDamageMult ^ cfg.collisionDamageExponent -- Pull the handling file value closer to 1 - SetVehicleHandlingFloat(vehicle, "CHandlingData", "fCollisionDamageMult", newFCollisionDamageMultiplier) - - --Get the EngineDamageMultiplier - fEngineDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fEngineDamageMult") - --Modify it by pulling all number a towards 1.0 - local newFEngineDamageMult = fEngineDamageMult ^ cfg.engineDamageExponent -- Pull the handling file value closer to 1 - SetVehicleHandlingFloat(vehicle, "CHandlingData", "fEngineDamageMult", newFEngineDamageMult) - - -- If body damage catastrophic, reset somewhat so we can get new damage to multiply - if healthBodyCurrent < cfg.cascadingFailureThreshold then - healthBodyNew = cfg.cascadingFailureThreshold - end - pedInSameVehicleLast = true - end - - -- set the actual new values - if healthEngineNew ~= healthEngineCurrent then - SetVehicleEngineHealth(vehicle, healthEngineNew) - end - if healthBodyNew ~= healthBodyCurrent then - SetVehicleBodyHealth(vehicle, healthBodyNew) - end - if healthPetrolTankNew ~= healthPetrolTankCurrent then - SetVehiclePetrolTankHealth(vehicle, healthPetrolTankNew) - end - - -- Store current values, so we can calculate delta next time around - healthEngineLast = healthEngineNew - healthBodyLast = healthBodyNew - healthPetrolTankLast = healthPetrolTankNew - lastVehicle = vehicle - if cfg.randomTireBurstInterval ~= 0 and GetEntitySpeed(vehicle) > 10 then - tireBurstLottery() - end - else - if pedInSameVehicleLast == true then - -- We just got out of the vehicle - lastVehicle = GetVehiclePedIsIn(ped, true) - if cfg.deformationMultiplier ~= -1 then - SetVehicleHandlingFloat( - lastVehicle, - "CHandlingData", - "fDeformationDamageMult", - fDeformationDamageMult - ) - end -- Restore deformation multiplier - SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fBrakeForce", fBrakeForce) -- Restore Brake Force multiplier - if cfg.weaponsDamageMultiplier ~= -1 then - SetVehicleHandlingFloat( - lastVehicle, - "CHandlingData", - "fWeaponDamageMult", - cfg.weaponsDamageMultiplier - ) - end -- Since we are out of the vehicle, we should no longer compensate for bodyDamageFactor - SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fCollisionDamageMult", fCollisionDamageMult) -- Restore the original CollisionDamageMultiplier - SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fEngineDamageMult", fEngineDamageMult) -- Restore the original EngineDamageMultiplier - end - pedInSameVehicleLast = false - end - end + while true do + Citizen.Wait(50) + local ped = GetPlayerPed(-1) + if isPedDrivingAVehicle() then + vehicle = GetVehiclePedIsIn(ped, false) + vehicleClass = GetVehicleClass(vehicle) + healthEngineCurrent = GetVehicleEngineHealth(vehicle) + if healthEngineCurrent == 1000 then + healthEngineLast = 1000.0 + end + healthEngineNew = healthEngineCurrent + healthEngineDelta = healthEngineLast - healthEngineCurrent + healthEngineDeltaScaled = healthEngineDelta * cfg.damageFactorEngine * cfg.classDamageMultiplier[vehicleClass] + + healthBodyCurrent = GetVehicleBodyHealth(vehicle) + if healthBodyCurrent == 1000 then + healthBodyLast = 1000.0 + end + healthBodyNew = healthBodyCurrent + healthBodyDelta = healthBodyLast - healthBodyCurrent + healthBodyDeltaScaled = healthBodyDelta * cfg.damageFactorBody * cfg.classDamageMultiplier[vehicleClass] + + healthPetrolTankCurrent = GetVehiclePetrolTankHealth(vehicle) + if cfg.compatibilityMode and healthPetrolTankCurrent < 1 then + healthPetrolTankLast = healthPetrolTankCurrent + end + if healthPetrolTankCurrent == 1000 then + healthPetrolTankLast = 1000.0 + end + healthPetrolTankNew = healthPetrolTankCurrent + healthPetrolTankDelta = healthPetrolTankLast - healthPetrolTankCurrent + healthPetrolTankDeltaScaled = healthPetrolTankDelta * cfg.damageFactorPetrolTank * cfg.classDamageMultiplier[vehicleClass] + + if healthEngineCurrent > cfg.engineSafeGuard + 1 then + SetVehicleUndriveable(vehicle, false) + end + + if healthEngineCurrent <= cfg.engineSafeGuard + 1 and cfg.limpMode == false then + SetVehicleUndriveable(vehicle, true) + end + + -- If ped spawned a new vehicle while in a vehicle or teleported from one vehicle to another, handle as if we just entered the car + if vehicle ~= lastVehicle then + pedInSameVehicleLast = false + end + + if pedInSameVehicleLast == true then + -- Damage happened while in the car = can be multiplied + + -- Only do calculations if any damage is present on the car. Prevents weird behavior when fixing using trainer or other script + if healthEngineCurrent ~= 1000.0 or healthBodyCurrent ~= 1000.0 or healthPetrolTankCurrent ~= 1000.0 then + -- Combine the delta values (Get the largest of the three) + local healthEngineCombinedDelta = math.max(healthEngineDeltaScaled, healthBodyDeltaScaled, healthPetrolTankDeltaScaled) + + -- If huge damage, scale back a bit + if healthEngineCombinedDelta > (healthEngineCurrent - cfg.engineSafeGuard) then + healthEngineCombinedDelta = healthEngineCombinedDelta * 0.7 + end + + -- If complete damage, but not catastrophic (ie. explosion territory) pull back a bit, to give a couple of seconds og engine runtime before dying + if healthEngineCombinedDelta > healthEngineCurrent then + healthEngineCombinedDelta = healthEngineCurrent - (cfg.cascadingFailureThreshold / 5) + end + + ------- Calculate new value + healthEngineNew = healthEngineLast - healthEngineCombinedDelta + + ------- Sanity Check on new values and further manipulations + + -- If somewhat damaged, slowly degrade until slightly before cascading failure sets in, then stop + + if healthEngineNew > (cfg.cascadingFailureThreshold + 5) and healthEngineNew < cfg.degradingFailureThreshold then + healthEngineNew = healthEngineNew - (0.038 * cfg.degradingHealthSpeedFactor) + end + + -- If Damage is near catastrophic, cascade the failure + if healthEngineNew < cfg.cascadingFailureThreshold then + healthEngineNew = healthEngineNew - (0.1 * cfg.cascadingFailureSpeedFactor) + end + + -- Prevent Engine going to or below zero. Ensures you can reenter a damaged car. + if healthEngineNew < cfg.engineSafeGuard then + healthEngineNew = cfg.engineSafeGuard + end + + -- Prevent Explosions + if cfg.compatibilityMode == false and healthPetrolTankCurrent < 750 then + healthPetrolTankNew = 750.0 + end + + -- Prevent negative body damage. + if healthBodyNew < 0 then + healthBodyNew = 0.0 + end + end + else + -- Just got in the vehicle. Damage can not be multiplied this round + -- Set vehicle handling data + fDeformationDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fDeformationDamageMult") + fBrakeForce = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fBrakeForce") + local newFDeformationDamageMult = fDeformationDamageMult ^ cfg.deformationExponent -- Pull the handling file value closer to 1 + if cfg.deformationMultiplier ~= -1 then + SetVehicleHandlingFloat(vehicle, "CHandlingData", "fDeformationDamageMult", newFDeformationDamageMult * cfg.deformationMultiplier) + end -- Multiply by our factor + if cfg.weaponsDamageMultiplier ~= -1 then + SetVehicleHandlingFloat(vehicle, "CHandlingData", "fWeaponDamageMult", cfg.weaponsDamageMultiplier / cfg.damageFactorBody) + end -- Set weaponsDamageMultiplier and compensate for damageFactorBody + + --Get the CollisionDamageMultiplier + fCollisionDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fCollisionDamageMult") + --Modify it by pulling all number a towards 1.0 + local newFCollisionDamageMultiplier = fCollisionDamageMult ^ cfg.collisionDamageExponent -- Pull the handling file value closer to 1 + SetVehicleHandlingFloat(vehicle, "CHandlingData", "fCollisionDamageMult", newFCollisionDamageMultiplier) + + --Get the EngineDamageMultiplier + fEngineDamageMult = GetVehicleHandlingFloat(vehicle, "CHandlingData", "fEngineDamageMult") + --Modify it by pulling all number a towards 1.0 + local newFEngineDamageMult = fEngineDamageMult ^ cfg.engineDamageExponent -- Pull the handling file value closer to 1 + SetVehicleHandlingFloat(vehicle, "CHandlingData", "fEngineDamageMult", newFEngineDamageMult) + + -- If body damage catastrophic, reset somewhat so we can get new damage to multiply + if healthBodyCurrent < cfg.cascadingFailureThreshold then + healthBodyNew = cfg.cascadingFailureThreshold + end + pedInSameVehicleLast = true + end + + -- set the actual new values + if healthEngineNew ~= healthEngineCurrent then + SetVehicleEngineHealth(vehicle, healthEngineNew) + end + if healthBodyNew ~= healthBodyCurrent then + SetVehicleBodyHealth(vehicle, healthBodyNew) + end + if healthPetrolTankNew ~= healthPetrolTankCurrent then + SetVehiclePetrolTankHealth(vehicle, healthPetrolTankNew) + end + + -- Store current values, so we can calculate delta next time around + healthEngineLast = healthEngineNew + healthBodyLast = healthBodyNew + healthPetrolTankLast = healthPetrolTankNew + lastVehicle = vehicle + if cfg.randomTireBurstInterval ~= 0 and GetEntitySpeed(vehicle) > 10 then + tireBurstLottery() + end + else + if pedInSameVehicleLast == true then + -- We just got out of the vehicle + lastVehicle = GetVehiclePedIsIn(ped, true) + if cfg.deformationMultiplier ~= -1 then + SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fDeformationDamageMult", fDeformationDamageMult) + end -- Restore deformation multiplier + SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fBrakeForce", fBrakeForce) -- Restore Brake Force multiplier + if cfg.weaponsDamageMultiplier ~= -1 then + SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fWeaponDamageMult", cfg.weaponsDamageMultiplier) + end -- Since we are out of the vehicle, we should no longer compensate for bodyDamageFactor + SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fCollisionDamageMult", fCollisionDamageMult) -- Restore the original CollisionDamageMultiplier + SetVehicleHandlingFloat(lastVehicle, "CHandlingData", "fEngineDamageMult", fEngineDamageMult) -- Restore the original EngineDamageMultiplier + end + pedInSameVehicleLast = false + end + end end) diff --git a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/config.lua b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/config.lua index 1c056115a..54a29367c 100644 --- a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/config.lua +++ b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/config.lua @@ -2,69 +2,69 @@ -- IMPORTANT: Some of these values MUST be defined as a floating point number. ie. 10.0 instead of 10 cfg = { - deformationMultiplier = -1, -- How much should the vehicle visually deform from a collision. Range 0.0 to 10.0 Where 0.0 is no deformation and 10.0 is 10x deformation. -1 = Don't touch. Visual damage does not sync well to other players. - deformationExponent = 0.7, -- How much should the handling file deformation setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. - collisionDamageExponent = 0.6, -- How much should the handling file deformation setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. + deformationMultiplier = -1, -- How much should the vehicle visually deform from a collision. Range 0.0 to 10.0 Where 0.0 is no deformation and 10.0 is 10x deformation. -1 = Don't touch. Visual damage does not sync well to other players. + deformationExponent = 0.7, -- How much should the handling file deformation setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. + collisionDamageExponent = 0.6, -- How much should the handling file deformation setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. - damageFactorEngine = 10.0, -- Sane values are 1 to 100. Higher values means more damage to vehicle. A good starting point is 10 - damageFactorBody = 10.0, -- Sane values are 1 to 100. Higher values means more damage to vehicle. A good starting point is 10 - damageFactorPetrolTank = 64.0, -- Sane values are 1 to 200. Higher values means more damage to vehicle. A good starting point is 64 - engineDamageExponent = 0.6, -- How much should the handling file engine damage setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. - weaponsDamageMultiplier = 0.10, -- How much damage should the vehicle get from weapons fire. Range 0.0 to 10.0, where 0.0 is no damage and 10.0 is 10x damage. -1 = don't touch - degradingHealthSpeedFactor = 10, -- Speed of slowly degrading health, but not failure. Value of 10 means that it will take about 0.25 second per health point, so degradation from 800 to 305 will take about 2 minutes of clean driving. Higher values means faster degradation - cascadingFailureSpeedFactor = 15.0, -- Sane values are 1 to 100. When vehicle health drops below a certain point, cascading failure sets in, and the health drops rapidly until the vehicle dies. Higher values means faster failure. A good starting point is 8 + damageFactorEngine = 10.0, -- Sane values are 1 to 100. Higher values means more damage to vehicle. A good starting point is 10 + damageFactorBody = 10.0, -- Sane values are 1 to 100. Higher values means more damage to vehicle. A good starting point is 10 + damageFactorPetrolTank = 64.0, -- Sane values are 1 to 200. Higher values means more damage to vehicle. A good starting point is 64 + engineDamageExponent = 0.6, -- How much should the handling file engine damage setting be compressed toward 1.0. (Make cars more similar). A value of 1=no change. Lower values will compress more, values above 1 it will expand. Dont set to zero or negative. + weaponsDamageMultiplier = 0.10, -- How much damage should the vehicle get from weapons fire. Range 0.0 to 10.0, where 0.0 is no damage and 10.0 is 10x damage. -1 = don't touch + degradingHealthSpeedFactor = 10, -- Speed of slowly degrading health, but not failure. Value of 10 means that it will take about 0.25 second per health point, so degradation from 800 to 305 will take about 2 minutes of clean driving. Higher values means faster degradation + cascadingFailureSpeedFactor = 15.0, -- Sane values are 1 to 100. When vehicle health drops below a certain point, cascading failure sets in, and the health drops rapidly until the vehicle dies. Higher values means faster failure. A good starting point is 8 - degradingFailureThreshold = 800.0, -- Below this value, slow health degradation will set in - cascadingFailureThreshold = 360.0, -- Below this value, health cascading failure will set in - engineSafeGuard = 150.0, -- Final failure value. Set it too high, and the vehicle won't smoke when disabled. Set too low, and the car will catch fire from a single bullet to the engine. At health 100 a typical car can take 3-4 bullets to the engine before catching fire. + degradingFailureThreshold = 800.0, -- Below this value, slow health degradation will set in + cascadingFailureThreshold = 360.0, -- Below this value, health cascading failure will set in + engineSafeGuard = 150.0, -- Final failure value. Set it too high, and the vehicle won't smoke when disabled. Set too low, and the car will catch fire from a single bullet to the engine. At health 100 a typical car can take 3-4 bullets to the engine before catching fire. - torqueMultiplierEnabled = true, -- Decrease engine torque as engine gets more and more damaged + torqueMultiplierEnabled = true, -- Decrease engine torque as engine gets more and more damaged - limpMode = false, -- If true, the engine never fails completely, so you will always be able to get to a mechanic unless you flip your vehicle and preventVehicleFlip is set to true - limpModeMultiplier = 0.20, -- The torque multiplier to use when vehicle is limping. Sane values are 0.05 to 0.25 + limpMode = false, -- If true, the engine never fails completely, so you will always be able to get to a mechanic unless you flip your vehicle and preventVehicleFlip is set to true + limpModeMultiplier = 0.20, -- The torque multiplier to use when vehicle is limping. Sane values are 0.05 to 0.25 - preventVehicleFlip = true, -- If true, you can't turn over an upside down vehicle + preventVehicleFlip = true, -- If true, you can't turn over an upside down vehicle - sundayDriver = true, -- If true, the accelerator response is scaled to enable easy slow driving. Will not prevent full throttle. Does not work with binary accelerators like a keyboard. Set to false to disable. The included stop-without-reversing and brake-light-hold feature does also work for keyboards. - sundayDriverAcceleratorCurve = 7.5, -- The response curve to apply to the accelerator. Range 0.0 to 10.0. Higher values enables easier slow driving, meaning more pressure on the throttle is required to accelerate forward. Does nothing for keyboard drivers - sundayDriverBrakeCurve = 5.0, -- The response curve to apply to the Brake. Range 0.0 to 10.0. Higher values enables easier braking, meaning more pressure on the throttle is required to brake hard. Does nothing for keyboard drivers + sundayDriver = true, -- If true, the accelerator response is scaled to enable easy slow driving. Will not prevent full throttle. Does not work with binary accelerators like a keyboard. Set to false to disable. The included stop-without-reversing and brake-light-hold feature does also work for keyboards. + sundayDriverAcceleratorCurve = 7.5, -- The response curve to apply to the accelerator. Range 0.0 to 10.0. Higher values enables easier slow driving, meaning more pressure on the throttle is required to accelerate forward. Does nothing for keyboard drivers + sundayDriverBrakeCurve = 5.0, -- The response curve to apply to the Brake. Range 0.0 to 10.0. Higher values enables easier braking, meaning more pressure on the throttle is required to brake hard. Does nothing for keyboard drivers - displayBlips = true, -- Show blips for mechanics locations + displayBlips = true, -- Show blips for mechanics locations - compatibilityMode = false, -- prevents other scripts from modifying the fuel tank health to avoid random engine failure with BVA 2.01 (Downside is it disabled explosion prevention) + compatibilityMode = false, -- prevents other scripts from modifying the fuel tank health to avoid random engine failure with BVA 2.01 (Downside is it disabled explosion prevention) - randomTireBurstInterval = 0, -- Number of minutes (statistically, not precisely) to drive above 22 mph before you get a tire puncture. 0=feature is disabled + randomTireBurstInterval = 0, -- Number of minutes (statistically, not precisely) to drive above 22 mph before you get a tire puncture. 0=feature is disabled - chargeForRepairs = false, -- if true fixing vehicle cost money - price = 100.0, -- you may edit this to your liking. if "chargeForRepairs = false" ignore this one - DamageMultiplier = 5.0, -- you may edit this to your liking. if "chargeForRepairs = false" ignore this one + chargeForRepairs = false, -- if true fixing vehicle cost money + price = 100.0, -- you may edit this to your liking. if "chargeForRepairs = false" ignore this one + DamageMultiplier = 5.0, -- you may edit this to your liking. if "chargeForRepairs = false" ignore this one - -- Class Damagefactor Multiplier - -- The damageFactor for engine, body and Petroltank will be multiplied by this value, depending on vehicle class - -- Use it to increase or decrease damage for each class + -- Class Damagefactor Multiplier + -- The damageFactor for engine, body and Petroltank will be multiplied by this value, depending on vehicle class + -- Use it to increase or decrease damage for each class - classDamageMultiplier = { - [0] = 1.0, -- 0: Compacts - 1.0, -- 1: Sedans - 1.0, -- 2: SUVs - 1.0, -- 3: Coupes - 1.0, -- 4: Muscle - 1.0, -- 5: Sports Classics - 1.3, -- 6: Sports - 1.3, -- 7: Super - 0.25, -- 8: Motorcycles - 0.7, -- 9: Off-road - 0.25, -- 10: Industrial - 1.0, -- 11: Utility - 1.0, -- 12: Vans - 1.0, -- 13: Cycles - 10.5, -- 14: Boats - 1.0, -- 15: Helicopters - 1.0, -- 16: Planes - 1.0, -- 17: Service - 0.75, -- 18: Emergency - 0.75, -- 19: Military - 1.0, -- 20: Commercial - 1.0, -- 21: Trains - }, + classDamageMultiplier = { + [0] = 1.0, -- 0: Compacts + 1.0, -- 1: Sedans + 1.0, -- 2: SUVs + 1.0, -- 3: Coupes + 1.0, -- 4: Muscle + 1.0, -- 5: Sports Classics + 1.3, -- 6: Sports + 1.3, -- 7: Super + 0.25, -- 8: Motorcycles + 0.7, -- 9: Off-road + 0.25, -- 10: Industrial + 1.0, -- 11: Utility + 1.0, -- 12: Vans + 1.0, -- 13: Cycles + 10.5, -- 14: Boats + 1.0, -- 15: Helicopters + 1.0, -- 16: Planes + 1.0, -- 17: Service + 0.75, -- 18: Emergency + 0.75, -- 19: Military + 1.0, -- 20: Commercial + 1.0, -- 21: Trains + }, } diff --git a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/fxmanifest.lua index fb6df5227..b83118092 100644 --- a/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_RealisticVehicleFailure/fxmanifest.lua @@ -3,15 +3,15 @@ game("gta5") description("esx_realisticvehicle") lua54("yes") -version("1.0.0") +version("1.0.1") shared_script("@es_extended/imports.lua") client_scripts({ - "config.lua", - "client.lua", + "config.lua", + "client.lua", }) server_scripts({ - "config.lua", + "config.lua", }) diff --git a/server-data/resources/[esx_addons]/esx_joblisting/README.md b/server-data/resources/[esx_addons]/esx_joblisting/README.md index 623cca3a9..2a5e6fc33 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/README.md +++ b/server-data/resources/[esx_addons]/esx_joblisting/README.md @@ -1,3 +1,5 @@ +

[ESX] Job Listing

Discord - Documentation + This Simple resource lets you finally contribute to Society and make a difference in the Word! How? it adds an amazing Menu where you can pick what you want to be in life - want to be a police officier? No-problem! Or maybe you want to stalk people and be a creepy reporter? We got you covered! ## Legal diff --git a/server-data/resources/[esx_addons]/esx_joblisting/client/main.lua b/server-data/resources/[esx_addons]/esx_joblisting/client/main.lua index 5e958e133..de37b63a9 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/client/main.lua @@ -1,81 +1,80 @@ local menuIsShowed, TextUIdrawing = false, false function ShowJobListingMenu() - menuIsShowed = true - ESX.TriggerServerCallback('esx_joblisting:getJobsList', function(jobs) - local elements = {{unselectable = "true", title = _U('job_center'), icon = "fas fa-briefcase"}} + menuIsShowed = true + ESX.TriggerServerCallback("esx_joblisting:getJobsList", function(jobs) + local elements = { { unselectable = "true", title = TranslateCap("job_center"), icon = "fas fa-briefcase" } } - for i = 1, #(jobs) do - elements[#elements + 1] = {title = jobs[i].label, name = jobs[i].name} - end + for i = 1, #jobs do + elements[#elements + 1] = { title = jobs[i].label, name = jobs[i].name } + end - ESX.OpenContext("right", elements, function(menu, SelectJob) - TriggerServerEvent('esx_joblisting:setJob', SelectJob.name) - ESX.CloseContext() - ESX.ShowNotification(_U('new_job', SelectJob.title), "success") - menuIsShowed = false - TextUIdrawing = false - end, function() - menuIsShowed = false - TextUIdrawing = false + ESX.OpenContext("right", elements, function(menu, SelectJob) + TriggerServerEvent("esx_joblisting:setJob", SelectJob.name) + ESX.CloseContext() + ESX.ShowNotification(TranslateCap("new_job", SelectJob.title), "success") + menuIsShowed = false + TextUIdrawing = false + end, function() + menuIsShowed = false + TextUIdrawing = false + end) end) - end) end -- Activate menu when player is inside marker, and draw markers CreateThread(function() - while true do - local Sleep = 1500 + while true do + local Sleep = 1500 - local coords = GetEntityCoords(ESX.PlayerData.ped) - local isInMarker = false + local coords = GetEntityCoords(ESX.PlayerData.ped) + local isInMarker = false - for i = 1, #Config.Zones, 1 do - local distance = #(coords - Config.Zones[i]) + for i = 1, #Config.Zones, 1 do + local distance = #(coords - Config.Zones[i]) - if distance < Config.DrawDistance then - Sleep = 0 - DrawMarker(Config.MarkerType, Config.Zones[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, - Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) - end + if distance < Config.DrawDistance then + Sleep = 0 + DrawMarker(Config.MarkerType, Config.Zones[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, Config.ZoneSize.x, Config.ZoneSize.y, Config.ZoneSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false) + end - if distance < (Config.ZoneSize.x / 2) then - isInMarker = true - if not TextUIdrawing then - ESX.TextUI(_U("access_job_center")) - TextUIdrawing = true + if distance < (Config.ZoneSize.x / 2) then + isInMarker = true + if not TextUIdrawing then + ESX.TextUI(TranslateCap("access_job_center")) + TextUIdrawing = true + end + if IsControlJustReleased(0, 38) and not menuIsShowed then + ShowJobListingMenu() + ESX.HideUI() + end + end end - if IsControlJustReleased(0, 38) and not menuIsShowed then - ShowJobListingMenu() - ESX.HideUI() + + if not isInMarker and TextUIdrawing then + ESX.HideUI() + TextUIdrawing = false end - end - end - if not isInMarker and TextUIdrawing then - ESX.HideUI() - TextUIdrawing = false + Wait(Sleep) end - - Wait(Sleep) - end end) -- Create blips if Config.Blip.Enabled then - CreateThread(function() - for i = 1, #Config.Zones, 1 do - local blip = AddBlipForCoord(Config.Zones[i]) + CreateThread(function() + for i = 1, #Config.Zones, 1 do + local blip = AddBlipForCoord(Config.Zones[i]) - SetBlipSprite(blip, Config.Blip.Sprite) - SetBlipDisplay(blip, Config.Blip.Display) - SetBlipScale(blip, Config.Blip.Scale) - SetBlipColour(blip, Config.Blip.Colour) - SetBlipAsShortRange(blip, Config.Blip.ShortRange) + SetBlipSprite(blip, Config.Blip.Sprite) + SetBlipDisplay(blip, Config.Blip.Display) + SetBlipScale(blip, Config.Blip.Scale) + SetBlipColour(blip, Config.Blip.Colour) + SetBlipAsShortRange(blip, Config.Blip.ShortRange) - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(_U('blip_text')) - EndTextCommandSetBlipName(blip) - end - end) -end \ No newline at end of file + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_text")) + EndTextCommandSetBlipName(blip) + end + end) +end diff --git a/server-data/resources/[esx_addons]/esx_joblisting/config.lua b/server-data/resources/[esx_addons]/esx_joblisting/config.lua index 6da00a446..dd2b7fb25 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/config.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/config.lua @@ -1,22 +1,22 @@ Config = {} Config.DrawDistance = 15.0 -Config.ZoneSize = {x = 2.7, y = 2.7, z = 0.5} -Config.MarkerColor = {r = 100, g = 200, b = 104} +Config.ZoneSize = { x = 2.7, y = 2.7, z = 0.5 } +Config.MarkerColor = { r = 100, g = 200, b = 104 } Config.MarkerType = 27 Config.Debug = ESX.GetConfig().EnableDebug -Config.Locale = 'en' +Config.Locale = GetConvar("esx:locale", "it") Config.Zones = { - vector3(-265.08, -964.1, 30.3) + vector3(-265.08, -964.1, 30.3), } Config.Blip = { - Enabled = true, - Sprite = 407, - Display = 4, - Scale = 0.8, - Colour = 27, - ShortRange = true -} \ No newline at end of file + Enabled = true, + Sprite = 407, + Display = 4, + Scale = 0.8, + Colour = 27, + ShortRange = true, +} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_joblisting/fxmanifest.lua index 0eff08bf1..4923ba92e 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/fxmanifest.lua @@ -1,19 +1,20 @@ -fx_version 'bodacious' -game 'gta5' +fx_version("bodacious") +game("gta5") -description 'ESX Job Listing' -lua54 'yes' -version '1.0.0' +description("Provides a way for players to select a job") +lua54("yes") +version("1.0") +legacyversion("1.9.1") -shared_scripts { - '@es_extended/imports.lua', - '@es_extended/locale.lua', - 'locales/*.lua', - 'config.lua' -} +shared_scripts({ + "@es_extended/imports.lua", + "@es_extended/locale.lua", + "locales/*.lua", + "config.lua", +}) -server_script 'server/main.lua' +server_script("server/main.lua") -client_script 'client/main.lua' +client_script("client/main.lua") -dependency 'es_extended' +dependency("es_extended") diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/cs.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/cs.lua deleted file mode 100644 index 8c9341768..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/cs.lua +++ /dev/null @@ -1,5 +0,0 @@ -Locales['cs'] = { - ['new_job'] = 'mate novou praci!', - ['access_job_center'] = 'stiskni ~INPUT_PICKUP~ pro pristup na Urad prace.', - ['job_center'] = 'Urad prace', -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/de.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/de.lua deleted file mode 100644 index 9de572907..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/de.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['de'] = { - ['new_job'] = 'Neuer Job: ~b~%s~s~ !', - ['access_job_center'] = 'Drücke ~b~[E]~s~ um die Jobauswahl zu öffnen!', - ['job_center'] = 'Wähle einen Job aus.', - ["blip_text"] = "Arbeitsamt" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/en.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/en.lua index 901e076f9..beda0b8ed 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/en.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/locales/en.lua @@ -1,6 +1,6 @@ -Locales['en'] = { - ['new_job'] = 'New Job: ~b~%s~s~ !', - ['access_job_center'] = 'Press ~b~[E]~s~ To Open Job Selector.', - ['job_center'] = 'Select A Job.', - ["blip_text"] = "Job Centre" +Locales["en"] = { + ["new_job"] = "New Job: ~b~%s~s~ !", + ["access_job_center"] = "Press ~b~[E]~s~ To Open Job Selector.", + ["job_center"] = "Select A Job.", + ["blip_text"] = "Job Centre", } diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/es.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/es.lua deleted file mode 100644 index 119c90cfe..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/es.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['es'] = { - ['new_job'] = '¡Tienes un trabajo nuevo!', - ['access_job_center'] = 'Pulsa ~INPUT_PICKUP~ para entrar a la Oficina de Empleo.', - ['job_center'] = 'Oficina de Empleo', - ["blip_text"] = "Oficina de Empleo" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/fi.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/fi.lua deleted file mode 100644 index 8cd2cd514..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/fi.lua +++ /dev/null @@ -1,5 +0,0 @@ -Locales['fi'] = { - ['new_job'] = 'Sinulla on nyt uusi työ!', - ['access_job_center'] = 'Paina ~INPUT_PICKUP~ vaihtaaksesi työtä.', - ['job_center'] = 'Työkeskus', -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/fr.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/fr.lua deleted file mode 100644 index f989e05c8..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/fr.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['fr'] = { - ['new_job'] = 'Vous avez un nouveau métier: ~b~%s~s~ !', - ['access_job_center'] = 'Appuyez sur ~b~[E]~s~ pour ouvrir le sélécteur de métiers.', - ['job_center'] = 'Séléctionnez un métier.', - ["blip_text"] = "Pôle emploi" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/hu.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/hu.lua deleted file mode 100644 index 36cb83656..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/hu.lua +++ /dev/null @@ -1,5 +0,0 @@ -Locales['hu'] = { - ['new_job'] = 'Felvetted a munkát!', - ['access_job_center'] = 'Nyomj ~b~[E]~s~ hogy megnézd a munkákat', - ['job_center'] = 'Munkaügyi központ', -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/it.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/it.lua index fdbb54444..991ba82d4 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/it.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/locales/it.lua @@ -1,6 +1,6 @@ -Locales['it'] = { - ['new_job'] = 'Nuovo lavoro: ~b~%s~s~ !', - ['access_job_center'] = 'Premi ~b~[E]~s~ per aprire la scelta dei lavori.', - ['job_center'] = 'Seleziona un lavoro.', - ["blip_text"] = "Centro impieghi" +Locales["it"] = { + ["new_job"] = "Nuovo lavoro: ~b~%s~s~ !", + ["access_job_center"] = "Premi ~b~[E]~s~ per aprire la scelta dei lavori.", + ["job_center"] = "Seleziona un lavoro.", + ["blip_text"] = "Centro impieghi", } diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/nl.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/nl.lua deleted file mode 100644 index 7152f0266..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/nl.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['nl'] = { - ['new_job'] = 'Nieuwe baan: ~b~%s~s~ !', - ['access_job_center'] = 'Klik op ~b~[E]~s~ om het uitzendbureau te openen.', - ['job_center'] = 'Selecteer een baan.', - ["blip_text"] = "Uitzendbureau" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/pl.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/pl.lua deleted file mode 100644 index 9f22e657a..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/pl.lua +++ /dev/null @@ -1,5 +0,0 @@ -Locales['pl'] = { - ['new_job'] = 'masz nową pracę!', - ['access_job_center'] = 'wciśnij ~INPUT_PICKUP~ aby otworzyć urząd pracy.', - ['job_center'] = 'urząd Pracy', -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/sl.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/sl.lua deleted file mode 100644 index 4e909d2fe..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/sl.lua +++ /dev/null @@ -1,8 +0,0 @@ -Locales['sl'] = { - ['new_job'] = 'imaš novo službo!', - ['access_job_center'] = 'pritisnite ~INPUT_PICKUP~ za dostop do job center.', - ['job_center'] = 'center za delovna mesta', - ['new_job'] = 'Imate novo Službo!', - ['access_job_center'] = 'Pritisni ~INPUT_PICKUP~ za dostop do Borze.', - ['job_center'] = 'Center za Zaposlovanje', -} \ No newline at end of file diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/sr.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/sr.lua deleted file mode 100644 index bdc5869bf..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/sr.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['sr'] = { - ['new_job'] = 'Novi Posao: ~b~%s~s~ !', - ['access_job_center'] = 'Pritisnite ~b~[E]~s~ da biste otvorili centar za zapošljavanje.', - ['job_center'] = 'Izaberite posao.', - ["blip_text"] = "Centar za Zapošljavanje" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/locales/zh-cn.lua b/server-data/resources/[esx_addons]/esx_joblisting/locales/zh-cn.lua deleted file mode 100644 index cf9657c9f..000000000 --- a/server-data/resources/[esx_addons]/esx_joblisting/locales/zh-cn.lua +++ /dev/null @@ -1,6 +0,0 @@ -Locales['zh-cn'] = { - ['new_job'] = '新工作: ~b~%s~s~ !', - ['access_job_center'] = '摁下 ~b~[E]~s~ 打开就业中心.', - ['job_center'] = '选择工作.', - ["blip_text"] = "就业中心" -} diff --git a/server-data/resources/[esx_addons]/esx_joblisting/server/main.lua b/server-data/resources/[esx_addons]/esx_joblisting/server/main.lua index 181e02f93..b4822750f 100644 --- a/server-data/resources/[esx_addons]/esx_joblisting/server/main.lua +++ b/server-data/resources/[esx_addons]/esx_joblisting/server/main.lua @@ -1,55 +1,55 @@ function getJobs() - local jobs = ESX.GetJobs() - local availableJobs = {} - for k, v in pairs(jobs) do - if v.whitelisted == false then - availableJobs[#availableJobs + 1] = {label = v.label, name = k} + local jobs = ESX.GetJobs() + local availableJobs = {} + for k, v in pairs(jobs) do + if v.whitelisted == false then + availableJobs[#availableJobs + 1] = { label = v.label, name = k } + end end - end - return availableJobs + return availableJobs end -ESX.RegisterServerCallback('esx_joblisting:getJobsList', function(source, cb) - local jobs = getJobs() - cb(jobs) +ESX.RegisterServerCallback("esx_joblisting:getJobsList", function(source, cb) + local jobs = getJobs() + cb(jobs) end) function IsJobAvailable(job) - local jobs = ESX.GetJobs() - local JobToCheck = jobs[job] - return not JobToCheck.whitelisted + local jobs = ESX.GetJobs() + local JobToCheck = jobs[job] + return not JobToCheck.whitelisted end function IsNearCentre(player) - local Ped = GetPlayerPed(player) - local PedCoords = GetEntityCoords(Ped) - local Zones = Config.Zones - local Close = false + local Ped = GetPlayerPed(player) + local PedCoords = GetEntityCoords(Ped) + local Zones = Config.Zones + local Close = false - for i = 1, #Config.Zones, 1 do - local distance = #(PedCoords - Config.Zones[i]) + for i = 1, #Config.Zones, 1 do + local distance = #(PedCoords - Config.Zones[i]) - if distance < Config.DrawDistance then - Close = true + if distance < Config.DrawDistance then + Close = true + end end - end - return Close + return Close end -RegisterServerEvent('esx_joblisting:setJob') -AddEventHandler('esx_joblisting:setJob', function(job) - local source = source - local xPlayer = ESX.GetPlayerFromId(source) - local jobs = getJobs() - - if xPlayer and IsNearCentre(source) and IsJobAvailable(job) then - if ESX.DoesJobExist(job, 0) then - xPlayer.setJob(job, 0) +RegisterServerEvent("esx_joblisting:setJob") +AddEventHandler("esx_joblisting:setJob", function(job) + local source = source + local xPlayer = ESX.GetPlayerFromId(source) + local jobs = getJobs() + + if xPlayer and IsNearCentre(source) and IsJobAvailable(job) then + if ESX.DoesJobExist(job, 0) then + xPlayer.setJob(job, 0) + else + print("[^1ERROR^7] Tried Setting User ^5" .. source .. "^7 To Invalid Job - ^5" .. job .. "^7!") + end else - print("[^1ERROR^7] Tried Setting User ^5".. source .. "^7 To Invalid Job - ^5"..job .."^7!") + print("[^3WARNING^7] User ^5" .. source .. "^7 Attempted to Exploit ^5`esx_joblisting:setJob`^7!") end - else - print("[^3WARNING^7] User ^5".. source .. "^7 Attempted to Exploit ^5`esx_joblisting:setJob`^7!") - end -end) \ No newline at end of file +end) diff --git a/server-data/resources/[esx_addons]/esx_property/LICENSE b/server-data/resources/[esx_addons]/esx_property/LICENSE index 5c0cc6276..6559572bf 100644 --- a/server-data/resources/[esx_addons]/esx_property/LICENSE +++ b/server-data/resources/[esx_addons]/esx_property/LICENSE @@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. ESX Property - Properties Made Right! - Copyright (C) 2022 ESX-Framework + Copyright (C) 2024 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 @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - esx-legacy Copyright (C) 2015-2022 Jérémie N'gadi + esx-legacy Copyright (C) 2015-2024 Jérémie N'gadi This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. diff --git a/server-data/resources/[esx_addons]/esx_property/README.md b/server-data/resources/[esx_addons]/esx_property/README.md index b66fde362..dfdc00201 100644 --- a/server-data/resources/[esx_addons]/esx_property/README.md +++ b/server-data/resources/[esx_addons]/esx_property/README.md @@ -1,4 +1,4 @@ -

[ESX] Property

Discord - Website - Documentation +

[ESX] Property

Discord - Documentation ## Features @@ -40,16 +40,23 @@ * ESX Progressbar *for Raiding* * * ESX Datastore *for wardrobe* * * ESX Clotheshop *for wardrobe* * +* [k4mb1 Starter Shells](https://www.k4mb1maps.com/package/5015840) *only for shell use* * * [bob74_ipl](https://github.com/Bob74/bob74_ipl) *only for IPL use* * > `*` = Optional ## Create A Property + +* [Menu Preview](https://prnt.sc/Xczb5Fs9xW-t) * Use the command `property:create` while an admin * Set Street Number * Set Price of Property * Select an Interior + > Note: To Use the Default Shells, you **NEED** [this Shell Pack](https://www.k4mb1maps.com/package/5015840) + > [Catagory Selection](https://prnt.sc/3RGaIEVTL6zw) + + > [Interior Selection](https://prnt.sc/za9aOSsuqkce) * Set The Entrance Position > Note: Uses Player`s Current Coordinates @@ -65,11 +72,13 @@ * From There, you can select A property * You Can then either `Manage`, `Teleport To Entrance` or `Delete` * Allows you to edit all options and evict users +* [Menu Preview](https://prnt.sc/Jpxox2ZcKn9G) +* [Menu Preview 2](https://prnt.sc/IbP-ynHgYSMA) # Copyright ESX Property - Properties Made Right! - Copyright (C) 2022 ESX-Framework + Copyright (C) 2024 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 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 29bd718cb..9a3003396 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/cctv.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/cctv.lua @@ -1,299 +1,260 @@ 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 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) + ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(1, Config.CCTV.Controls.Screenshot, true)) + InstructionButtonMessage(TranslateCap("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) + 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) - 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) + 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) - 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) + 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) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.NightVision, true)) - InstructionButtonMessage(_U("night_vision")) - 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) - N_0xe83a3e3557a56640(GetControlInstructionalButton(1, Config.CCTV.Controls.Exit, true)) - InstructionButtonMessage(_U("exit")) - 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, "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 + 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(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) + 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(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 + 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 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 9e9a22abc..fa3e9baf4 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/furniture.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/furniture.lua @@ -1,502 +1,428 @@ ---[[ - ESX Property - Properties Made Right! - Copyright (C) 2022 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 . -]] 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) - 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 = _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 - - 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" }, - } - - 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 - - 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 = _U("store_title", Store), 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 - - 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 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(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 = _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 - - 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 - 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 - - 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) + 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 = TranslateCap("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 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 f6ca8ea6e..b5c363c52 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,30 +1,27 @@ - + + + \ 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 567e53fab..b22abf589 100644 --- a/server-data/resources/[esx_addons]/esx_property/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_property/client/main.lua @@ -20,2184 +20,1486 @@ 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) - 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 + 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.7) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString(_U("office_blip", PM.joblabel)) - EndTextCommandSetBlipName(Blip) - Blips[#Blips + 1] = Blip - 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(TranslateCap("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 - 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) - end - end - RefreshBlips() + 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 + 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 + 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() + 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 - end - 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 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 = TranslateCap("nearby"), icon = "fas fa-user-plus" }, { title = TranslateCap("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(TranslateCap("gave_key", element.title), "success") + ESX.CloseContext() + else + ESX.ShowNotification(TranslateCap("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 = TranslateCap("remove_title"), icon = "fas fa-user-plus" }, { title = TranslateCap("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(TranslateCap("key_revoke_success", element.title), "success") + ESX.CloseContext() + else + ESX.ShowNotification(TranslateCap("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 = TranslateCap("key_management"), icon = "fas fa-key" }, + { title = TranslateCap("back"), icon = "fas fa-arrow-left", value = "go_back" }, + { title = TranslateCap("give_keys"), icon = "fas fa-plus", value = "give_keys" }, + { title = TranslateCap("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 = TranslateCap("name_edit"), icon = "fa-solid fa-signature" }, + { icon = "", title = TranslateCap("name"), input = true, inputType = "text", inputValue = Name, inputPlaceholder = Properties[Property].Name, name = "setName" }, + { icon = "fa-solid fa-check", title = TranslateCap("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") - end - end, Property, menu.eles[2].inputValue) - end - end) + ESX.OpenContext("right", Elements, function(menu, element) + if element.name == "confirm" then + ESX.TriggerServerCallback("esx_property:SetPropertyName", function(Set) + if Set then + ESX.ShowNotification(TranslateCap("name_edit_success", menu.eles[2].inputValue), "success") + ESX.CloseContext() + else + ESX.ShowNotification(TranslateCap("name_edit_error", menu.eles[2].inputValue), "error") + end + end, Property, menu.eles[2].inputValue) + 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", - } - ) - 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" }) - end - end + 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 = TranslateCap("door_locked"), icon = "fas fa-lock", value = "property_unlock" }) + else + table.insert(elements, { title = TranslateCap("door_unlocked"), icon = "fas fa-unlock", value = "property_lock" }) + end + if ESX.PlayerData.identifier == Property.Owner then + table.insert(elements, { title = TranslateCap("name_manage"), description = TranslateCap("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 = TranslateCap("key_management"), description = TranslateCap("key_management_desc"), icon = "fas fa-key", value = "property_keys" }) + table.insert(elements, { title = TranslateCap("sell_title"), description = TranslateCap("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 = TranslateCap("raid_title"), description = TranslateCap("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 = TranslateCap("cctv_title"), description = TranslateCap("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 = TranslateCap("inventory_title"), description = TranslateCap("inventory_desc"), icon = "fa-solid fa-up-down-left-right", value = "property_inventory" }) + end + table.insert(elements, { title = TranslateCap("wardrobe_title"), description = TranslateCap("wardrobe_desc"), icon = "fa-solid fa-up-down-left-right", value = "property_wardrobe" }) + end + table.insert(elements, { title = TranslateCap("furniture_title"), description = TranslateCap("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 = TranslateCap("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 = TranslateCap("knock_title"), icon = "fa-solid fa-hand-sparkles", value = "property_knock" }) + end + else + if not PM.Enabled then + table.insert(elements, { title = TranslateCap("buy_title"), description = TranslateCap("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 = TranslateCap("sellplayer_title"), description = TranslateCap("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 = TranslateCap("view_title"), icon = "fas fa-door-open", value = "property_enter" }) + 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 = TranslateCap("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(TranslateCap("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") - 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") - 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") - 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") - 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") - 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") - 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 == "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(TranslateCap("unlock_error"), "error") + 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(TranslateCap("lock_error"), "error") + 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(TranslateCap("prep_raid"), 15000, { + FreezePlayer = true, + animation = Config.Raiding.Animation, + onFinish = function() + ESX.ShowNotification(TranslateCap("raiding"), "success") + AttemptHouseEntry(PropertyId) + end, + onCancel = function() + ESX.ShowNotification(TranslateCap("cancel_raiding"), "error") + end, + }) + else + ESX.ShowNotification(TranslateCap("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(TranslateCap("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(TranslateCap("storage_pos_success"), "success") + else + ESX.ShowNotification(TranslateCap("storage_pos_error"), "error") + 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(TranslateCap("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(TranslateCap("wardrobe_pos_success"), "success") + else + ESX.ShowNotification(TranslateCap("wardrobe_pos_error"), "error") + 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(TranslateCap("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(TranslateCap("cannot_afford"), "error") + end + end, PropertyId) + end + if element.value == "property_sell_re" then + local Elements = { { unselectable = true, title = TranslateCap("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 - 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 - 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) + 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(TranslateCap("cannot_sell"), "error") + end + end, PropertyId, element.value) + end + end) + end + end, PropertyId) + end + if element.value == "property_knock" then + ESX.ShowNotification(TranslateCap("knock_on_door"), "success") + ESX.TriggerServerCallback("esx_property:KnockOnDoor", function(HasKnocked) + if not HasKnocked then + ESX.ShowNotification(TranslateCap("nobody_home"), "error") + 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(TranslateCap("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) - end - SpawnedFurniture = {} - end - Wait(1500) - FreezeEntityPosition(ESX.PlayerData.ped, false) - DoScreenFadeIn(1500) + ESX.ShowNotification(TranslateCap("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) + 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) - 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 + local Property = Properties[PropertyId] + local Interior = GetInteriorValues(Property.Interior) + if Interior.type == "shell" and not Config.Shells then + ESX.ShowNotification(TranslateCap("shell_disabled"), "error") + return + end + ESX.ShowNotification(TranslateCap("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) + 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 + 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(TranslateCap("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 - 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 + ESX.TextUI(TranslateCap("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(TranslateCap("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 - end - end - end - end - end - end - Wait(Sleep) - end - 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(TranslateCap("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 + Wait(Sleep) + 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(TranslateCap("store_success"), "success") + return + else + ESX.ShowNotification(TranslateCap("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 - end - end) - else - ESX.ShowNotification(_U("cannot_access"), "error") - return - end - end, PropertyId) + ESX.TriggerServerCallback("esx_property:AccessGarage", function(Vehicles) + if Vehicles then + local elements = { { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("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(TranslateCap("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(TranslateCap("cannot_access"), "error") + return + end + 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) - 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 - if not nearby and CurrentDrawing.Showing and SettingValue == "" then - ESX.HideUI() - CurrentDrawing.Showing = false - ESX.CloseContext() - end - end - Wait(Sleep) - end + 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(TranslateCap("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(TranslateCap("store_textui", DisplayName)) + end + else + if not CurrentDrawing.Showing or CurrentDrawing.Name ~= "Garage" then + CurrentDrawing.Name = "Garage" + CurrentDrawing.Showing = true + ESX.TextUI(TranslateCap("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 + if not nearby and CurrentDrawing.Showing and SettingValue == "" then + ESX.HideUI() + CurrentDrawing.Showing = false + ESX.CloseContext() + end + 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(TranslateCap("enter_office"), "success") + else + ESX.ShowNotification(TranslateCap("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(TranslateCap("exit_office"), "success") + else + ESX.ShowNotification(TranslateCap("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 = TranslateCap("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 - 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 + if ESX.PlayerData.job.name == PM.job then + if ESX.PlayerData.job.grade >= PM.Permissions.CreateProperty then + elements[#elements + 1] = { title = TranslateCap("property_create"), value = "CreateProperty" } + end + if ESX.PlayerData.job.grade >= PM.Permissions.ManagePropertiesFromQuickActions then + elements[#elements + 1] = { title = TranslateCap("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 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.RegisterInput(TranslateCap("realestate_command"), TranslateCap("realestate_command_desc"), "keyboard", "F5", function() + ESX.TriggerServerCallback("esx_property:CanAccessRealEstateMenu", function(Access) + if Access then + OpenPMQuickMenu("ActionsMenu") + end + end) end) 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() - end - end - end - end - end - Wait(Sleep) - end + 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(TranslateCap("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 + 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) + 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 = TranslateCap("menu_title") }, + { + value = 0, + title = TranslateCap("element_title1"), + icon = "fas fa-list-ol", + description = TranslateCap("element_description1"), + input = true, + inputType = "number", + inputPlaceholder = "Number...", + inputValue = nil, + inputMin = 1, + inputMax = 90000, + index = "hnumber", + }, + { + title = TranslateCap("element_title2"), + icon = "fas fa-dollar-sign", + input = true, + inputType = "number", + description = TranslateCap("element_description2"), + inputPlaceholder = "Price...", + inputValue = SuggestedPrice, + inputMin = 1, + inputMax = 900000000, + index = "price", + }, + { title = TranslateCap("element_title3"), description = TranslateCap("element_description3"), icon = "fas fa-home", index = "interior" }, + { title = TranslateCap("element_title4"), description = TranslateCap("element_description4"), icon = "fas fa-warehouse", value = { enabled = false }, index = "garage", disabled = not Config.Garage.Enabled }, + { + title = TranslateCap("element_title5"), + description = TranslateCap("element_description5"), + icon = "fas fa-video", + value = { enabled = false, rot = GetGameplayCamRot(2), maxleft = 80, maxright = -20 }, + index = "cctv", + disabled = not Config.CCTV.Enabled, + }, + { title = TranslateCap("element_title6"), description = TranslateCap("element_description6"), icon = "fas fa-map-marker-alt", index = "entrance" }, + { title = TranslateCap("element_create_title"), icon = "fas fa-check", description = TranslateCap("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 == TranslateCap("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 == TranslateCap("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 = TranslateCap("entrance_set_title") + Property[7].description = TranslateCap("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 = TranslateCap("interior_set_title") + Property[4].description = TranslateCap("interior_set_description", element.title) + OpenCreate() + end + if element.index == "IPL" then + local ints = { { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("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 = TranslateCap("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 = TranslateCap("types_title") }, { title = TranslateCap("ipl_title"), description = TranslateCap("ipl_description"), index = "IPL" } } + if Config.Shells then + catsa[3] = { title = TranslateCap("shell_title"), description = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-video", title = TranslateCap("cctv_settings") }, + { title = TranslateCap("toggle_title"), icon = status == TranslateCap("enabled") and "fas fa-eye" or "fas fa-eye-slash", description = TranslateCap("toggle_description", status), index = "ToggleCCTV" }, + { title = TranslateCap("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, description = TranslateCap("cctv_set_description"), index = "SetCCTVangle" }, + { title = TranslateCap("back"), icon = "fas fa-arrow-left", description = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-video", title = TranslateCap("cctv_settings") }, + { title = TranslateCap("toggle_title"), icon = status == TranslateCap("enabled") and "fas fa-eye" or "fas fa-eye-slash", description = TranslateCap("toggle_description", status), index = "ToggleCCTV" }, + { title = TranslateCap("cctv_set_title"), icon = "fas fa-rotate", disabled = not Property[6].value.enabled, description = TranslateCap("cctv_set_description"), index = "SetCCTVangle" }, + { title = TranslateCap("back"), icon = "fas fa-arrow-left", description = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("garage_settings") }, + { title = TranslateCap("toggle_title"), icon = status == TranslateCap("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = TranslateCap("toggle_description", status), index = "ToggleGarage" }, + } + if Property[5].value.enabled then + opos[#opos + 1] = { title = TranslateCap("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, description = TranslateCap("garage_set_description"), index = "SetGaragePos" } + if Property[5].value.pos then + opos[#opos + 1] = { title = TranslateCap("back"), icon = "fas fa-arrow-left", description = TranslateCap("back_description"), index = "return" } + end + else + opos[#opos + 1] = { title = TranslateCap("back"), icon = "fas fa-arrow-left", description = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("garage_settings") }, + { title = TranslateCap("toggle_title"), icon = status == TranslateCap("enabled") and "fa-solid fa-toggle-on" or "fa-solid fa-toggle-off", description = TranslateCap("toggle_description", status), index = "ToggleGarage" }, + } + if Property[5].value.enabled then + opos[#opos + 1] = { title = TranslateCap("garage_set_title"), icon = "fas fa-map-marker-alt", disabled = not Property[5].value.enabled, description = TranslateCap("garage_set_description"), index = "SetGaragePos" } + else + opos[#opos + 1] = { title = TranslateCap("back"), icon = "fas fa-arrow-left", description = TranslateCap("back_description"), index = "return" } + end + exports["esx_context"]:Refresh(opos, "right") + end + if element.index == "SetGaragePos" then + ESX.CloseContext() + ESX.TextUI(TranslateCap("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(TranslateCap("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(TranslateCap("cctv_textui_2")) + stage = "maxright" + elseif stage == "maxright" then + Property[6].value.maxright = GetGameplayCamRot(2).z + ESX.TextUI(TranslateCap("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(TranslateCap("create_success"), "success") + ESX.CloseContext() + HouseData = {} + else + ESX.ShowNotification(TranslateCap("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") - 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) - end + 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 = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("garage_settings") }, + { title = "Toggle Usage", icon = status == TranslateCap("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 = TranslateCap("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("cctv_settings") }, + { title = "Toggle Usage", icon = status == TranslateCap("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 = TranslateCap("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("garage_settings") }, + { title = "Toggle Usage", icon = status == TranslateCap("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 = TranslateCap("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = TranslateCap("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 TranslateCap("enabled") or TranslateCap("disabled") + opos = { + { unselectable = true, icon = "fas fa-warehouse", title = TranslateCap("cctv_settings") }, + { title = "Toggle Usage", icon = status == TranslateCap("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 = TranslateCap("back"), icon = "fas fa-arrow-left", description = "return to Property Management.", value = "return" } + end + else + opos[#opos + 1] = { title = TranslateCap("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) + 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 = TranslateCap("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 - end - ESX.OpenContext("right", elements, function(menu, element) - if element.value then - ESX.CloseContext() - AdminOptions(element.value) - 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 + 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 1ee37c3ea..7327158b1 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 = GetConvar("esx:locale", "it") 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 @@ -18,642 +18,632 @@ 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" } } +Config.WardrobeInteraction = function(PropertyId, Interaction) + 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(menu, 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) - end) - end) + TriggerEvent("skinchanger:getSkin", function(skin) + TriggerServerEvent("esx_skin:save", skin) + end) + end, element.value) + 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, - }, - { - grade = 1, - name = "agent", - label = "Experienced Agent", - salary = 30, - }, - { - grade = 2, - name = "boss", - label = "Chief Agent", - salary = 45, - }, - }, - 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) - }, + 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, + }, + }, + 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" }, - }, + { + 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), - }, - { - 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), - }, - }, - 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), - }, - }, + 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), + }, + }, + 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" }, - }, - - 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" }, - }, - - 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" }, - }, - - 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" }, - }, + 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 = 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" }, + }, + 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" }, + }, + 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 - end - 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 diff --git a/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua index 2dc35dd33..c14ef4d39 100644 --- a/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_property/fxmanifest.lua @@ -4,26 +4,26 @@ game("gta5") lua54("yes") author("ESX-Framework") -description("Official ESX-Legacy Property System") -version("1.0.0") +description("Allows players to buy/sell houses, aswell as furnish them") +version("1.0.1") shared_scripts({ "@es_extended/imports.lua", "@es_extended/locale.lua", "locales/*.lua" }) file("client/html/copy.html") ui_page("client/html/copy.html") server_scripts({ - "@oxmysql/lib/MySQL.lua", - "config.lua", - "server/*.lua", + "@oxmysql/lib/MySQL.lua", + "config.lua", + "server/*.lua", }) client_scripts({ - "config.lua", - "client/cctv.lua", - "client/main.lua", - "client/furniture.lua", + "config.lua", + "client/cctv.lua", + "client/main.lua", + "client/furniture.lua", }) dependencies({ - "es_extended", + "es_extended", }) 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 16d4a8bfc..cf2e728d5 100644 --- a/server-data/resources/[esx_addons]/esx_property/locales/en.lua +++ b/server-data/resources/[esx_addons]/esx_property/locales/en.lua @@ -1,215 +1,208 @@ 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", + --- 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 ff457b3b3..6194ca88d 100644 --- a/server-data/resources/[esx_addons]/esx_property/locales/it.lua +++ b/server-data/resources/[esx_addons]/esx_property/locales/it.lua @@ -1,215 +1,208 @@ 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", + --- CCTV Strings ------ + ["take_picture"] = "Scatta foto", + ["rot_left_right"] = "Sinistra/Destra", + ["rot_up_down"] = "Su/Giù", + ["zoom"] = "Zoom avanti/indietro", + ["zoom_level"] = "Livello zoom: %s %%", + ["night_vision"] = "Attiva/disattiva visione notturna", + ["clipboard"] = "Link copiato negli ~b~Appunti", + ["picture_taken"] = "Immagine scattata!", + ["please_wait"] = "Attendere prima di scattare un'altra ~b~immagine", + ["exit"] = "Esci", + + --- Furniture Strings ------ + ["height"] = "altezza", + ["rotate"] = "Rotazione", + ["place"] = "Posiziona mobili", + ["delete_furni"] = "Elimina", + ["confirm_buy"] = "Vuoi acquistare %s ?", + ["price"] = "Prezzo: $%s", + ["yes"] = "Sì", + ["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"] = "~r~Non puoi~s~ comprare questo!", + ["cannot_edit"] = "~r~Non puoi~s~ modificare questo!", + ["store_title"] = "Negozio - %s", + ["back"] = "Ritorno", + ["edit_title"] = "Modifica - %s", + ["move_title"] = "Sposta", + ["deleted_confirm"] = "Eliminazione di ~b~%s~s~!", + ["deleted_error"] = "Impossibile eliminare ~b~%s~s~!", + ["owned_furni"] = "Mobili di proprietà", + ["menu_stores"] = "Negozi di mobili", + ["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 elementi di arredo", + ["furni_command"] = "mobili", + ["furni_command_desc"] = "(Proprietà ESX) Apri menu Arredamento", + ["furni_command_permission"] = "~r~Impossibile~s~ accedere a questo menu!", + ["furni_reset_success"] = "Reimposta mobili!", + ["furni_cannot_afford"] = "Non puoi permetterti di farlo!", + ["furni_reset_error"] = "~r~Impossibile~s~ reimpostare questa proprietà!", + ["furni_management"] = "Gestisci mobili", + + --------- Key Strings --------------- + ["you_granted"] = "Ti sono state concesse le chiavi per ~b~%s~s~.", + ["already_has"] = "Questo giocatore ha già le chiavi!", + ["do_not_own"] = "~r~non~s~ possiedi questa proprietà.", + ["key_revoked"] = "La tua chiave di accesso a ~b~%s~s~. È stato ~r~Revocato~s~", + ["no_keys"] = "Questo giocatore non ha le chiavi!", + ["nearby"] = "Giocatori nelle vicinanze", + ["gave_key"] = "Consegna chiavi a %s!", + ["key_cannot_give"] = "Non puoi dare a questo giocatore una ~r~chiave", + ["remove_title"] = "Rimuovi chiavi dal lettore", + ["key_revoke_success"] = "Revoca chiavi da ~b~%s~s~.", + ["key_revoke_error"] = "Non puoi ~b~rimuovere~s~ una ~r~chiave~s~ da questa persona", + ["key_management"] = "Gestione chiavi", + ["key_management_desc"] = "Controllo accesso proprietà.", + ["give_keys"] = "Dai le chiavi", + ["remove_keys"] = "Rimuovi chiavi", + + --------- Real Estate Strings --------------- + ["office_blip"] = "%s Ufficio", + ["actions"] = "Azioni immobiliari", + ["property_create"] = "Crea proprietà", + ["property_manage"] = "Gestisci proprietà", + ["realestate_command"] = "realestatequickmenu", + ["realestate_command_desc"] = "(Proprietà ESX) Apri Azioni rapide immobiliari", + ["enter_office"] = "~b~Entrando in~s~ Ufficio.", + ["enter_office_error"] = "~r~Non puoi~s~ entrare in ufficio!", + ["exit_office"] = "~b~Esco~s~ dall'ufficio.", + ["exit_office_error"] = "~r~Non puoi~s~ uscire dall'ufficio!", + ["realestate_textui"] = "Premi ~b~[E]~s~ per accedere a ~b~%s", + + ------------Command Strings----------------------- + ["refresh_name"] = "proprietà:refresh", + ["refresh_desc"] = "Aggiorna allo stato di avvio del server", + ["save_name"] = "proprietà:salva", + ["save_desc"] = "Forza il salvataggio delle proprietà", + ["create_name"] = "proprietà:crea", + ["create_desc"] = "Crea una nuova proprietà", + ["admin_name"] = "proprietà:amministratore", + ["admin_desc"] = "Gestisci/visualizza tutte le proprietà", + + ---------- Property Actions Menu ------------------------- + ["knocking"] = "Qualcuno sta ~b~bussando~s~ alla porta.", + ["name_edit"] = "Modifica nome proprietà", + ["name"] = "Nome", + ["confirm"] = "Conferma", + ["name_edit_success"] = "Hai impostato il nome della proprietà su ~b~%s~s~.", + ["name_edit_error"] = "Non puoi impostare il nome della proprietà su ~r~%s~s~.", + ["door_locked"] = "Porta: chiusa", + ["door_unlocked"] = "Porta: Sbloccata", + ["name_manage"] = "Gestisci nome", + ["name_manage_desc"] = "Imposta il nome della proprietà.", + ["sell_title"] = "Vendi", + ["sell_desc"] = "Vendi questa proprietà per $%s", + ["raid_title"] = "Assalto", + ["raid_desc"] = "Forza l'accesso alla proprietà.", + ["cctv_title"] = "TVCC", + ["cctv_desc"] = "Controlla la telecamera CCTV.", + ["inventory_title"] = "Inventario", + ["inventory_desc"] = "Cambia posizione di archiviazione proprietà.", + ["wardrobe_title"] = "Armadio", + ["wardrobe_desc"] = "Cambia posizione del guardaroba della proprietà.", + ["furniture_title"] = "Mobili", + ["furniture_desc"] = "Cambia posizione dell'arredamento della proprietà.", + ["enter_title"] = "Invio", + ["knock_title"] = "Bussa alla porta", + ["buy_title"] = "Acquista", + ["buy_desc"] = "Compra questa proprietà per $%s", + ["sellplayer_title"] = "Vendi al giocatore", + ["sellplayer_desc"] = "Vendi questa proprietà per $%s", + ["view_title"] = "Anteprima interni", + ["exit_title"] = "Esci", + ["property_editing_error"] = "Stai attualmente modificando la proprietà.", + ["unlock_error"] = "Non puoi ~b~sbloccare~s~ questa proprietà", + ["lock_error"] = "Non puoi ~b~Bloccare~s~ questa proprietà", + ["prep_raid"] = "~b~Preparazione~s~ Raid!", + ["raiding"] = "Raiding...", + ["cancel_raiding"] = "~r~Raid~s~ annullato!", + ["cannot_raid"] = "Non puoi ~b~razziare~s~ questa proprietà.", + ["storage_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione di archiviazione", + ["storage_pos_success"] = "~b~Storage~s~ Posizione impostata.", + ["storage_pos_error"] = "~r~Impossibile~s~ impostare la posizione ~b~Memoria~s~.", + ["wardrobe_pos_textui"] = "Premi ~b~[G]~s~ per impostare la posizione dell'armadio", + ["wardrobe_pos_success"] = "~b~Wardrobe~s~ Posizione impostata.", + ["wardrobe_pos_error"] = "~r~Impossibile~s~ impostare la ~b~posizione dell'armadio~s~.", + ["please_finish"] = "Completa l'impostazione della ~b~%s~s~ posizione", + ["cannot_afford"] = "Non puoi acquistare questa proprietà!", + ["select_player"] = "Seleziona giocatore", + ["cannot_sell"] = "Impossibile vendere a questo giocatore!", + ["knock_on_door"] = "Bussano alla porta...", + ["nobody_home"] = "Sembra che non ci sia nessuno in casa...", + + ---------- General Strings ---------------- + ["enabled"] = "Abilitato", + ["disabled"] = "Disabilitato", + ["exiting"] = "Esci dalla proprietà...", + ["entering"] = "Inserimento proprietà...", + ["shell_disabled"] = "Questo interno utilizza uno shell, che è disabilitato!", + ["access_textui"] = "Premi ~b~[E]~s~ per accedere a ~b~%s", + ["raid_notify_error"] = "Hai bisogno di ~b~ %sx %s~s~ per poter invadere la casa!", + ["raid_notify_success"] = "La tua proprietà sta venendo ~b~invasa!", + + --------------- Garage Strings -------------- + ["store_success"] = "Veicolo ~b~Memorizzato!", + ["store_error"] = "Non puoi memorizzare questo veicolo!", + ["property_garage"] = "Garage di proprietà", + ["retriving_notify"] = "Recupero ~b~%s~s~ ...", + ["cannot_access"] = "Non puoi accedere a questo garage!", + ["store_textui"] = "Premi ~b~[E]~s~ per memorizzare ~b~%s", + ["garage_not_enabled"] = "Garage non abilitato su questa proprietà.", + ["cannot_access_property"] = "~r~Impossibile~s~ accedere a questa proprietà.", + + ----------------- Creation Menu Strings ---------------- + ["menu_title"] = "Creazione proprietà", + ["element_title1"] = "Numero civico", + ["element_description1"] = "Imposta il numero civico della proprietà.", + ["element_title2"] = "Prezzo", + ["element_description2"] = "Imposta il prezzo della proprietà.", + ["element_title3"] = "Interno", + ["element_description3"] = "Seleziona un interno per la proprietà", + ["element_title4"] = "Rimessa", + ["element_description4"] = "(Facoltativo) Gestisci impostazioni Garage", + ["element_title5"] = "CCTV", + ["element_description5"] = "(Facoltativo) Gestisci impostazioni TVCC", + ["element_title6"] = "Ingresso", + ["element_description6"] = "Imposta la posizione dell'ingresso della proprietà.", + ["element_create_title"] = "Crea proprietà", + ["element_create_desc_1"] = "Si prega di compilare tutti gli input obbligatori!", + ["entrance_set_title"] = "Ingresso impostato.", + ["entrance_set_description"] = "Ingresso: %s, %s, %s", + ["interior_set_title"] = "Interno selezionato.", + ["interior_set_description"] = "Selezionato: %s", + ["ipl_title"] = "Interni IPL", + ["types_title"] = "Tipi interni", + ["ipl_description"] = "Interni nativi di GTA, realizzati da R*", + ["shell_title"] = "Interni personalizzati", + ["shell_description"] = "Interni personalizzati, realizzati da te", + ["cctv_settings"] = "Impostazioni CCTV", + ["garage_settings"] = "Impostazioni garage", + ["toggle_title"] = "Attiva/disattiva utilizzo", + ["toggle_description"] = "Stato attuale: %s", + ["cctv_set_title"] = "Imposta angolo TVCC", + ["cctv_set_description"] = "Imposta l'angolazione della telecamera sulla direzione della telecamera", + ["back_description"] = "ritorna alla creazione della proprietà.", + ["garage_set_title"] = "Imposta posizione garage", + ["garage_set_description"] = "Imposta la posizione del garage della proprietà.", + ["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 massima rotazione a destra", + ["cctv_textui_3"] = "Premi ~b~[E]~s~ per impostare la rotazione sinistra massima", + ["create_success"] = "Proprietà creata!", + ["missing_data"] = "Si prega di compilare tutti gli input obbligatori!", + + -- Saving Translations + ["server_restart"] = "Riavvio del server", + ["server_shutdown"] = "Arresto del server", + ["manual_save"] = "Salvataggio manuale (richiesto da %s)", + ["resource_stop"] = "Arresto risorsa", + ["force_save"] = "Forza salvataggio (richiesto da %s)", + ["interval_saving"] = "Salvataggio a intervalli", } 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 989bcffcf..3cf92bef4 100644 --- a/server-data/resources/[esx_addons]/esx_property/server/main.lua +++ b/server-data/resources/[esx_addons]/esx_property/server/main.lua @@ -1,1588 +1,1175 @@ 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(err, text, headers) + 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 - ) - 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")) - end - else - Properties = {} - print("[^1ERROR^7]: ^5Properties.json^7 Not Found!") - end + 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 + 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 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 - end - end + for i = 1, #Config.AllowedGroups do + if xPlayer.group == Config.AllowedGroups[i] then + return true + 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 - 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 + end + end - return false + return false end CreateThread(function() - Wait(3000) + 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") + if result?.affectedRows > 0 then + print("[^2INFO^7] Added ^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") + + -- Check if datastore table exists before to insert values. + if MySQL.scalar.await("SELECT EXISTS (SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_TYPE LIKE 'BASE TABLE' AND TABLE_NAME = 'datastore')") > 0 then + MySQL.insert("INSERT IGNORE INTO `datastore` (name, label, shared) VALUES ('property', 'Property' , 1)", function(affectedRows) + if affectedRows > 0 then + print("[^2INFO^7] Added ^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) + MySQL.insert("INSERT IGNORE INTO `datastore_data` (name, owner, data) VALUES ('property', NULL, '{}')", function(affectedRows) + if affectedRows > 0 then + print("[^2INFO^7] Added ^5Property^7 into ^5datastore_data^7 table") end - end - ) + 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 - 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") + if MySQL.scalar.await("SELECT EXISTS (SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_TYPE LIKE 'BASE TABLE' AND TABLE_NAME = 'datastore')") > 0 then + MySQL.insert("INSERT IGNORE INTO `addon_account` (name, label, shared) VALUES (?, ? , 1)", {PM.society, PM.joblabel}, function(affectedRows) + if affectedRows > 0 then + print("[^2INFO^7] Added ^5" .. PM.society .. " - " .. PM.joblabel .. "^7 into ^5addon_account^7 table") + end + end) + end + if not ESX.DoesJobExist(PM.job, 0) then + MySQL.insert("INSERT INTO `jobs` SET name = ?, label = ?, whitelisted = 1", {PM.job, PM.joblabel}, function(affectedRows) + if affectedRows > 0 then + print("[^2INFO^7] Inserted ^5" .. PM.job .. " - " .. PM.joblabel .. "^7 into ^5jobs^7 table") end end) end + + local QUERIES = {} 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 - ) + if not ESX.DoesJobExist(PM.job, PM.jobRanks[i].grade) then + QUERIES[i] = { + query = "INSERT INTO `job_grades` SET job_name = ?, grade = ?, name = ?, label = ?, salary = ?, skin_male = '{}', skin_female = '{}'", + parameters = { PM.job, PM.jobRanks[i].grade, PM.jobRanks[i].name, PM.jobRanks[i].label, PM.jobRanks[i].salary } + } end end + MySQL.transaction(QUERIES) + Wait(10) ESX.RefreshJobs() - TriggerEvent( - "esx_society:registerSociety", - "realestateagent", - "realestateagent", - "society_realestateagent", - "society_realestateagent", - "society_realestateagent", - { type = "private" } - ) + exports["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") }) +ESX.RegisterCommand(_("refresh_name"), Config.AllowedGroups, function(xPlayer) + PropertiesRefresh() +end, false, {help = TranslateCap("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") }) +ESX.RegisterCommand(_("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 = TranslateCap("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 = TranslateCap("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 - ) - end - end - cb(xPlayer.getAccount("bank").money >= Price) + 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 + 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("bpt_addonaccount:getSharedAccount", PM.society, function(account) - account.addMoney(SocietyPrice) - end) - xPlayer.addAccountMoney("bank", PlayerPrice, "Sold Property") - end - end - cb(xPlayer.getAccount("bank").money >= Price) + 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 + 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) - else - cb(false) - ESX.ShowNotification(_U("furni_cannot_afford")) - 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) - end -) +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) + else + cb(false) + ESX.ShowNotification(TranslateCap("furni_cannot_afford")) + 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) +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) - end - end - cb(xPlayer.identifier == Owner) + 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 + 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) - 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]) - ) + 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 + 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 - ) - end - end - cb( - (xPlayer.identifier == Owner or IsPlayerAdmin(source, "SetPropertyName")) - and name - and #name <= Config.MaxNameLength - ) + 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 + 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 - end - cb(false) - else - cb(false) - end +ESX.RegisterServerCallback("esx_property:KnockOnDoor", function(source, cb, PropertyId, name) + 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(TranslateCap("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 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 +ESX.RegisterServerCallback("esx_property:RemoveCustomName", function(source, cb, PropertyId, name) + 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) - end - end - cb(IsPlayerAdmin(source, "DeleteProperty")) + 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 + 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 - 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")) + 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 + 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 - 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]) - ) + 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 + 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 - ) - 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]) - ) + 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 + 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 - end - end - 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 + 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 + 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) - 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")) +ESX.RegisterServerCallback("esx_property:evictOwner", function(source, cb, PropertyId, Interior) + 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 + 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" - ) - 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") - end - Wait(15000) - Properties[PropertyId].Locked = false - TriggerClientEvent("esx_property:syncProperties", -1, Properties) - end +ESX.RegisterServerCallback("esx_property:CanRaid", function(source, cb, PropertyId, Interior) + 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(TranslateCap("raid_notify_error", Config.Raiding.ItemRequired.ItemCount, Config.Raiding.ItemRequired.name), "error") + end + else + Can = true + end + end + end + cb(Can) + if Can then + local xOwner = ESX.GetPlayerFromIdentifier(Properties[PropertyId].Owner) + if xOwner then + xOwner.showNotification(TranslateCap("raid_notify_success"), "error") + 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 - 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 + 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.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]) - ) + 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("bpt_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 - - 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 - cb(Players) +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 k, 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 + 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) - 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 - end - cb(Players) +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 k, 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 + 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(source, cb, property) + 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, property) + 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] - - 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) - else - xPlayer.showNotification(_U("already_has"), "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) +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 + + local id = xTarget.identifier + if not Properties[property].Keys[id] then + Property.Keys[id] = {name = xTarget.getName(), identifier = id} + xTarget.showNotification(TranslateCap("you_granted", Property.Name), 'success') + xTarget.triggerEvent("esx_property:giveKeyAccess") + cb(true) + else + xPlayer.showNotification(TranslateCap("already_has"), 'error') + cb(false) + end + else + xPlayer.showNotification(TranslateCap("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) 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) - else - cb(false) - end - else - 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 - else - xPlayer.showNotification(_U("garage_not_enabled"), "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) +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 + 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 + else + xPlayer.showNotification(TranslateCap("garage_not_enabled"), 'error') + cb(false) + end + else + xPlayer.showNotification(TranslateCap("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) end) -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) - else - xPlayer.showNotification(_U("garage_not_enabled"), "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) +ESX.RegisterServerCallback('esx_property:AccessGarage', 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 + cb(Property.garage.StoredVehicles) + else + xPlayer.showNotification(TranslateCap("garage_not_enabled"), 'error') + cb(false) + end + else + xPlayer.showNotification(TranslateCap("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] - - 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 - xPlayer.showNotification(_U("do_not_own"), "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(TranslateCap("key_revoked", Property.Name), 'error') + xTarget.triggerEvent("esx_property:RemoveKeyAccess", property) + cb(true) + else + xPlayer.showNotification(TranslateCap("no_keys"), 'error') + cb(false) + end + else + cb(false) + end + else + xPlayer.showNotification(TranslateCap("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("bpt_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: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) + 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) + + 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 - ) +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: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 - ) +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 +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 - end - 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) -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 - end - end + if xPlayer then + if IsPlayerAdmin(source, "CreateProperty") then + Re = true + 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(TranslateCap("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(TranslateCap("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(TranslateCap("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(TranslateCap("interval_saving")) + end end) ESX.RegisterCommand(_("save_name"), Config.AllowedGroups, function(xPlayer) - PropertySave(_U("manual_save", GetPlayerName(xPlayer.source))) -end, false, { help = _U("save_desc") }) + PropertySave(TranslateCap("manual_save", GetPlayerName(xPlayer.source))) +end, false,{help = TranslateCap("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] - end - end - return OwnedProperties + local OwnedProperties = {} + for i=1, #Properties do + if Properties[i].Owned then + OwnedProperties[#OwnedProperties + 1] = Properties[i] + end + end + return OwnedProperties end) exports("GetNonOwnedProperties", function() - local NonOwnedProperties = {} - for i = 1, #Properties do - if not Properties[i].Owned then - NonOwnedProperties[#NonOwnedProperties + 1] = Properties[i] - end - end - return NonOwnedProperties + local NonOwnedProperties = {} + for i=1, #Properties do + if not Properties[i].Owned then + NonOwnedProperties[#NonOwnedProperties + 1] = Properties[i] + end + end + 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] - end - end - return PlayerProperties + local PlayerProperties = {} + for i=1, #Properties do + if Properties[i].Owned and Properties[i].Owner == identifier then + PlayerProperties[#PlayerProperties + 1] = Properties[i] + end + end + 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)) + local ExecutingResource = GetInvokingResource() + PropertySave(TranslateCap("forced_save", ExecutingResource)) end) diff --git a/server-data/resources/[esx_addons]/esx_scoreboard/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_scoreboard/fxmanifest.lua index 970dd09c1..6b9f08625 100644 --- a/server-data/resources/[esx_addons]/esx_scoreboard/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_scoreboard/fxmanifest.lua @@ -4,15 +4,15 @@ games({ "gta5" }) ui_page("html/scoreboard.html") files({ - "html/*", + "html/*", }) shared_script("@es_extended/imports.lua") client_scripts({ - "client/main.lua", + "client/main.lua", }) server_scripts({ - "server/main.lua", + "server/main.lua", }) diff --git a/server-data/resources/[esx_addons]/esx_scoreboard/html/listener.js b/server-data/resources/[esx_addons]/esx_scoreboard/html/listener.js index ecb688db5..373e92d97 100644 --- a/server-data/resources/[esx_addons]/esx_scoreboard/html/listener.js +++ b/server-data/resources/[esx_addons]/esx_scoreboard/html/listener.js @@ -53,7 +53,7 @@ $(function () { break; default: console.log('esx_scoreboard: unknown action!'); - break; + break; } }, false); }); diff --git a/server-data/resources/[esx_addons]/esx_scoreboard/html/scoreboard.html b/server-data/resources/[esx_addons]/esx_scoreboard/html/scoreboard.html index 5a1094559..b8541526a 100644 --- a/server-data/resources/[esx_addons]/esx_scoreboard/html/scoreboard.html +++ b/server-data/resources/[esx_addons]/esx_scoreboard/html/scoreboard.html @@ -10,15 +10,6 @@