mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-31 10:18:54 +00:00
312 lines
14 KiB
Lua
312 lines
14 KiB
Lua
local hasAlreadyEnteredMarker, CurrentActionData = false, {}
|
|
local CurrentAction, CurrentActionMsg, LastZone
|
|
ESX = nil
|
|
|
|
Citizen.CreateThread(function()
|
|
while ESX == nil do
|
|
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
|
Citizen.Wait(0)
|
|
end
|
|
|
|
while ESX.GetPlayerData().job == nil do
|
|
Citizen.Wait(100)
|
|
end
|
|
|
|
ESX.PlayerData = ESX.GetPlayerData()
|
|
|
|
if ESX.PlayerData.job.name == 'realestateagent' then
|
|
Config.Zones.OfficeActions.Type = 1
|
|
else
|
|
Config.Zones.OfficeActions.Type = -1
|
|
end
|
|
end)
|
|
|
|
function OpenRealestateAgentMenu()
|
|
local elements = {
|
|
{label = _U('properties'), value = 'properties'},
|
|
{label = _U('clients'), value = 'customers'},
|
|
}
|
|
|
|
if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'realestateagent' and ESX.PlayerData.job.grade_name == 'boss' then
|
|
table.insert(elements, {
|
|
label = _U('boss_action'),
|
|
value = 'boss_actions'
|
|
})
|
|
end
|
|
|
|
ESX.UI.Menu.CloseAll()
|
|
|
|
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'realestateagent', {
|
|
title = _U('realtor'),
|
|
align = 'top-left',
|
|
elements = elements
|
|
}, function(data, menu)
|
|
if data.current.value == 'properties' then
|
|
OpenPropertyMenu()
|
|
elseif data.current.value == 'customers' then
|
|
OpenCustomersMenu()
|
|
elseif data.current.value == 'boss_actions' then
|
|
TriggerEvent('esx_society:openBossMenu', 'realestateagent', function(data, menu)
|
|
menu.close()
|
|
end)
|
|
end
|
|
end, function(data, menu)
|
|
menu.close()
|
|
|
|
CurrentAction = 'realestateagent_menu'
|
|
CurrentActionMsg = _U('press_to_access')
|
|
CurrentActionData = {}
|
|
end)
|
|
end
|
|
|
|
function OpenPropertyMenu()
|
|
TriggerEvent('esx_property:getProperties', function(properties)
|
|
|
|
local elements = {
|
|
head = {_U('property_name'), _U('property_actions')},
|
|
rows = {}
|
|
}
|
|
|
|
for i=1, #properties, 1 do
|
|
table.insert(elements.rows, {
|
|
data = properties[i],
|
|
cols = {
|
|
properties[i].label,
|
|
_U('property_actionbuttons')
|
|
}
|
|
})
|
|
end
|
|
|
|
ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'properties', elements, function(data, menu)
|
|
if data.value == 'sell' then
|
|
menu.close()
|
|
|
|
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'sell_property_amount', {
|
|
title = _U('amount')
|
|
}, function(data2, menu2)
|
|
local amount = tonumber(data2.value)
|
|
|
|
if amount == nil then
|
|
ESX.ShowNotification(_U('invalid_amount'))
|
|
else
|
|
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
|
|
if closestPlayer == -1 or closestDistance > 3.0 then
|
|
ESX.ShowNotification(_U('no_play_near'))
|
|
menu2.close()
|
|
else
|
|
TriggerServerEvent('esx_realestateagentjob:sell', GetPlayerServerId(closestPlayer), data.data.name, amount)
|
|
menu2.close()
|
|
end
|
|
|
|
OpenPropertyMenu()
|
|
end
|
|
end, function(data2, menu2)
|
|
menu2.close()
|
|
end)
|
|
elseif data.value == 'rent' then
|
|
menu.close()
|
|
|
|
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'rent_property_amount', {
|
|
title = _U('amount')
|
|
}, function(data2, menu2)
|
|
local amount = tonumber(data2.value)
|
|
|
|
if amount == nil then
|
|
ESX.ShowNotification(_U('invalid_amount'))
|
|
else
|
|
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
|
|
if closestPlayer == -1 or closestDistance > 3.0 then
|
|
ESX.ShowNotification(_U('no_play_near'))
|
|
menu2.close()
|
|
else
|
|
TriggerServerEvent('esx_realestateagentjob:rent', GetPlayerServerId(closestPlayer), data.data.name, amount)
|
|
menu2.close()
|
|
end
|
|
|
|
OpenPropertyMenu()
|
|
end
|
|
end, function(data2, menu2)
|
|
menu2.close()
|
|
end)
|
|
elseif data.value == 'gps' then
|
|
TriggerEvent('esx_property:getProperty', data.data.name, function(property)
|
|
if property.isSingle then
|
|
SetNewWaypoint(property.entering.x, property.entering.y)
|
|
else
|
|
TriggerEvent('esx_property:getGateway', property, function(gateway)
|
|
SetNewWaypoint(gateway.entering.x, gateway.entering.y)
|
|
end)
|
|
end
|
|
end)
|
|
end
|
|
end, function(data, menu)
|
|
menu.close()
|
|
end)
|
|
end)
|
|
end
|
|
|
|
function OpenCustomersMenu()
|
|
ESX.TriggerServerCallback('esx_realestateagentjob:getCustomers', function(customers)
|
|
local elements = {
|
|
head = {_U('customer_client'), _U('customer_property'), _U('customer_agreement'), _U('customer_actions')},
|
|
rows = {}
|
|
}
|
|
|
|
for i=1, #customers, 1 do
|
|
table.insert(elements.rows, {
|
|
data = customers[i],
|
|
cols = {
|
|
customers[i].name,
|
|
customers[i].propertyLabel,
|
|
(customers[i].propertyRented and _U('customer_rent') or _U('customer_sell')),
|
|
_U('customer_contractbuttons')
|
|
}
|
|
})
|
|
end
|
|
|
|
ESX.UI.Menu.Open('list', GetCurrentResourceName(), 'customers', elements, function(data, menu)
|
|
if data.value == 'revoke' then
|
|
TriggerServerEvent('esx_realestateagentjob:revoke', data.data.propertyName, data.data.propertyOwner)
|
|
OpenCustomersMenu()
|
|
elseif data.value == 'gps' then
|
|
TriggerEvent('esx_property:getProperty', data.data.propertyName, function(property)
|
|
if property.isSingle then
|
|
SetNewWaypoint(property.entering.x, property.entering.y)
|
|
else
|
|
TriggerEvent('esx_property:getGateway', property, function(gateway)
|
|
SetNewWaypoint(gateway.entering.x, gateway.entering.y)
|
|
end)
|
|
end
|
|
end)
|
|
end
|
|
end, function(data, menu)
|
|
menu.close()
|
|
end)
|
|
end)
|
|
end
|
|
|
|
RegisterNetEvent('esx:setJob')
|
|
AddEventHandler('esx:setJob', function(job)
|
|
ESX.PlayerData.job = job
|
|
|
|
if ESX.PlayerData.job.name == 'realestateagent' then
|
|
Config.Zones.OfficeActions.Type = 1
|
|
else
|
|
Config.Zones.OfficeActions.Type = -1
|
|
end
|
|
end)
|
|
|
|
AddEventHandler('esx_realestateagentjob:hasEnteredMarker', function(zone)
|
|
if zone == 'OfficeEnter' then
|
|
local playerPed = PlayerPedId()
|
|
SetEntityCoords(playerPed, Config.Zones.OfficeInside.Pos.x, Config.Zones.OfficeInside.Pos.y, Config.Zones.OfficeInside.Pos.z)
|
|
elseif zone == 'OfficeExit' then
|
|
local playerPed = PlayerPedId()
|
|
SetEntityCoords(playerPed, Config.Zones.OfficeOutside.Pos.x, Config.Zones.OfficeOutside.Pos.y, Config.Zones.OfficeOutside.Pos.z)
|
|
elseif zone == 'OfficeActions' and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'realestateagent' then
|
|
CurrentAction = 'realestateagent_menu'
|
|
CurrentActionMsg = _U('press_to_access')
|
|
CurrentActionData = {}
|
|
end
|
|
end)
|
|
|
|
AddEventHandler('esx_realestateagentjob:hasExitedMarker', function(zone)
|
|
ESX.UI.Menu.CloseAll()
|
|
CurrentAction = nil
|
|
end)
|
|
|
|
-- Create Blips
|
|
Citizen.CreateThread(function()
|
|
local blip = AddBlipForCoord(Config.Zones.OfficeEnter.Pos.x, Config.Zones.OfficeEnter.Pos.y, Config.Zones.OfficeEnter.Pos.z)
|
|
|
|
SetBlipSprite (blip, 357)
|
|
SetBlipDisplay(blip, 4)
|
|
SetBlipScale (blip, 1.0)
|
|
SetBlipColour (blip, 59)
|
|
SetBlipAsShortRange(blip, true)
|
|
|
|
BeginTextCommandSetBlipName('STRING')
|
|
AddTextComponentSubstringPlayerName(_U('realtors'))
|
|
EndTextCommandSetBlipName(blip)
|
|
end)
|
|
|
|
-- Display markers
|
|
Citizen.CreateThread(function()
|
|
while true do
|
|
Citizen.Wait(0)
|
|
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
|
|
for k,v in pairs(Config.Zones) do
|
|
if(v.Type ~= -1 and GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < Config.DrawDistance) then
|
|
DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, false, false, false)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Enter / Exit marker events
|
|
Citizen.CreateThread(function()
|
|
while true do
|
|
Citizen.Wait(0)
|
|
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
local isInMarker = false
|
|
local currentZone = nil
|
|
|
|
for k,v in pairs(Config.Zones) do
|
|
if GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) < v.Size.x then
|
|
isInMarker = true
|
|
currentZone = k
|
|
end
|
|
end
|
|
|
|
if (isInMarker and not hasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then
|
|
hasAlreadyEnteredMarker = true
|
|
LastZone = currentZone
|
|
TriggerEvent('esx_realestateagentjob:hasEnteredMarker', currentZone)
|
|
end
|
|
|
|
if not isInMarker and hasAlreadyEnteredMarker then
|
|
hasAlreadyEnteredMarker = false
|
|
TriggerEvent('esx_realestateagentjob:hasExitedMarker', LastZone)
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Key controls
|
|
Citizen.CreateThread(function()
|
|
while true do
|
|
Citizen.Wait(0)
|
|
|
|
if CurrentAction then
|
|
ESX.ShowHelpNotification(CurrentActionMsg)
|
|
|
|
if IsControlJustReleased(0, 38) then
|
|
if CurrentAction == 'realestateagent_menu' then
|
|
OpenRealestateAgentMenu()
|
|
end
|
|
|
|
CurrentAction = nil
|
|
end
|
|
else
|
|
Citizen.Wait(500)
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Load IPLS
|
|
Citizen.CreateThread(function()
|
|
RequestIpl('ex_dt1_02_office_02c')
|
|
end)
|
|
|
|
RegisterNetEvent('esx_phone:loaded')
|
|
AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts)
|
|
local specialContact = {
|
|
name = _U('realtor'),
|
|
number = 'realestateagent',
|
|
base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAkuhgkvhwowhgowhwwxhwowiAwxiAwyiA0yiQ4zig80iQ40ihA0iRA0ihA1ixE2ixI3jBM4ixM4jBQ4jBQ4jRY6jRY6jhg7jhg7jxg8jRk8jhk8jxo+jxo+kBw/kB1AkB1AkR9Bkh9CkR9CkiBDkSBCkiFEkyNElCNGlCVGlCZIlSdIlihJlipKlilKlytMlyxLlyxNlytMmCxMmC5OmS9PmjBPmTBPmjFQmTBQmjNSmzNSnDRTnDVUmzVUnDdVnjZWnTdWnjhXnjpYnjxZnj1bnztaoD1aoD5coT9dokBdoUBdokFeokNgo0NgpERgo0RhpEVipEZipUdkpUdkpkhkpEhkpkpmpUpmpkpmp0xnpk5qp0xoqE5pqU5qqVBrqFBrqVFrqlJsqVJsqlJuqlNuq1RuqlRurFZwrFdyrVhxrllyrVhyrlt0r1x1r112r1x1sF12sF94sWF5sGB4sWF5smJ6smR8s2V9tGZ+tGd/tWl/tWh/tmmAtWmAtmuCtmqCt2yDt2yDuG6EuG+GuXGGuXGGunGIunSJunSJu3WKvHeMvXiNvHmOvnuQvnyQvn6SwICTwYCUwICUwYKWwoSWw4SYw4WYxIeaxIiaxIqcxoydx4yex46fyI+gyJGiyZGiypOkypSky5amzJeozZinzZmozZmpzpqqzpysz5+u0KCu0KGw0aKw0qWz06a01Ki11Ki21aq31qu41qy41q2616+72LC82LG+2bK+2rS/27XA2rbB3LfC3LjD3LrE3brF3rvG3rzG3r7I37/I4MHK4MPM4cTN4sXO4sbP5MfQ48fQ5MjQ5MnS5cvT5szT5s3U5s7W587W6NDX6NHY6NPa6dPa6tTa6tXc6tfd7Nnf7drg7dvg7tzh7t3i7t/k7+Dl8OLm8OPo8ePo8uTo8eTo8ubq8ufr9Ons9Oru9ezu9ezv9u3w9u/y9+/x+PDy+PL0+PP1+vP2+fT1+fX2+vb4+/f4/Pj5+/j5/Pn6/Pv8/fz8/fz8/v7+/gAAACSdcMIAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAC4iAAAuIgGq4t2SAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAKNUlEQVRoQ92af1hV5R3Ax/HuXI5eb9fimguQUEN3CbFEW1i51l2PVCJg6qTYapGhm1iaYm6r3O7UciQWmOkonWyOpWJkTh3TJobilIbKlETvvNvAS9zG3YTlxcvp/fE9v3/cK3uePXv2+eue97zn++Gc9/2+P87hS/x/gf89SfmKp+fm5eTMLFiwEkqiI1rJy9nJnJWRsFiHps1dBScjEY1k6fgRHMRWYrHH3/cKVDIjsuThL0NIA+IWQUVjIkieSJQ/IwOGpC6F6gaYSuY6IEwkYhJfhEt0MZE8HwchoiHG9QZcpoOhpOw2C1wfJdztcKUWI8mT16nA3FgKF6vRl6y/NQYuvC4sd8P1KnQlK/TTIgqSIIISPUkuXDEQLMshiBwdyZ0DaA6J2MchjAytZDzUNiFhlEkCxTwDgSQ0krFQ1xjn8hMtjXs3PPd110g7FCkYNBtCiaglke7DEpdzqLcfEe7r9Z+t31m28H7XyGEcy8J5zKAHIZiASnIn1DPCUVDTjRUi4VBve9Nvq17/UWFWRqJoegrCAUpJboQ2H7X70zBEVxLqCfq9LfWV30sh9WKVaamQrCA1jGAnec5BTCP+UjWJuRknmQMiUuSS9aY5mLyuLQSxDAhszbTZv7snGdceBTEJcsmtJJgc1soKD5B9dNuRCx2f9Yb1n1d/f7Aux2bP3hv8K+mfMfIuJpM8qR6vrPeXbVxdnHdvCsfYbmZZK3dTxqPLXnunpv6MrwciiwQPzI+zZVf5+/vbaRLEroGwCElSpm70wWsvhfo+vxLwtVZzWcfqN88fi3sPaxuWMG6Se+GW43KRryiBZSo68F2ChImF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'
|
|
}
|
|
|
|
TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon)
|
|
end) |