Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 92 additions & 107 deletions [esx_addons]/esx_shops/client/main.lua
Original file line number Diff line number Diff line change
@@ -1,121 +1,106 @@
local hasAlreadyEnteredMarker, lastZone
local currentAction, currentActionMsg, currentActionData = nil, nil, {}

local function openShopMenu(zone)
local elements = {
{unselectable = true, icon = "fas fa-shopping-basket", title = TranslateCap('shop') }
}

for i=1, #Config.Zones[zone].Items, 1 do
local item = Config.Zones[zone].Items[i]

elements[#elements+1] = {
icon = "fas fa-shopping-basket",
title = ('%s - <span style="color:green;">%s</span>'):format(item.label, TranslateCap('shop_item', ESX.Math.GroupDigits(item.price))),
itemLabel = item.label,
item = item.name,
price = item.price
}
end

ESX.OpenContext("right", elements, function(menu,element)
local elements2 = {
{unselectable = true, icon = "fas fa-shopping-basket", title = element.title},
{icon = "fas fa-shopping-basket", title = TranslateCap('amount'), input = true, inputType = "number", inputPlaceholder = TranslateCap('amount_placeholder'), inputMin = 1, inputMax = 25},
{icon = "fas fa-check-double", title = TranslateCap('confirm'), val = "confirm"}
}

ESX.OpenContext("right", elements2, function(menu2,element2)
local amount = menu2.eles[2].inputValue
ESX.CloseContext()
TriggerServerEvent('esx_shops:buyItem', element.item, amount, zone)
end, function(menu)
currentAction = 'shop_menu'
currentActionMsg = TranslateCap('press_menu', ESX.GetInteractKey())
currentActionData = {zone = zone}
end)
end, function(menu)
currentAction = 'shop_menu'
currentActionMsg = TranslateCap('press_menu', ESX.GetInteractKey())
currentActionData = {zone = zone}
end)
---@diagnostic disable: undefined-global
local ESX = exports['es_extended']:getSharedObject()
local isShopUiOpen = false

local function setShopUiVisible(visible)
isShopUiOpen = visible
SetNuiFocus(visible, visible)
SendNUIMessage({ action = visible and 'show' or 'hide' })
end

local function hasEnteredMarker(zone)
currentAction = 'shop_menu'
currentActionMsg = TranslateCap('press_menu', ESX.GetInteractKey())
currentActionData = {zone = zone}
local function openShopUi()
if isShopUiOpen then return end
setShopUiVisible(true)
end

local function hasExitedMarker(zone)
currentAction = nil
ESX.CloseContext()
local function closeShopUi()
if not isShopUiOpen then return end
setShopUiVisible(false)
end

-- Create Blips
CreateThread(function()
for k,v in pairs(Config.Zones) do
for i = 1, #v.Pos, 1 do
if not v.ShowBlip then return end

local blip = AddBlipForCoord(v.Pos[i])

SetBlipSprite (blip, v.Type)
SetBlipScale (blip, v.Size)
SetBlipColour (blip, v.Color)
SetBlipAsShortRange(blip, true)

BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(TranslateCap('shops'))
EndTextCommandSetBlipName(blip)
end
end
RegisterNUICallback('close', function(_, cb)
closeShopUi()
if cb then cb({}) end
end)

-- Enter / Exit marker events
CreateThread(function()
while true do
local sleep = 1500
AddEventHandler('onResourceStop', function(resourceName)
if GetCurrentResourceName() ~= resourceName then return end
SetNuiFocus(false, false)
end)

local playerCoords = GetEntityCoords(ESX.PlayerData.ped)
local isInMarker, currentZone = false, nil

for k,v in pairs(Config.Zones) do
for i = 1, #v.Pos, 1 do
local distance = #(playerCoords - v.Pos[i])
RegisterNUICallback('getShopData', function(_, cb)
cb({
categories = Config.Categories or {},
items = Config.Items or {}
})
end)

if distance < Config.DrawDistance then
sleep = 0
if v.ShowMarker then
DrawMarker(Config.MarkerType, v.Pos[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.MarkerSize.x, Config.MarkerSize.y, Config.MarkerSize.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false)
end
if distance < 2.0 then
isInMarker = true
currentZone = k
lastZone = k
end
end
end
end
RegisterNUICallback('purchase', function(data, cb)
local payload = data or {}
ESX.TriggerServerCallback('esx_shops:purchase', function(success, message)
cb({ success = success, message = message })
if success then
ESX.ShowNotification(message)
else
ESX.ShowNotification(message)
end
end, payload)
end)

if isInMarker and not hasAlreadyEnteredMarker then
hasAlreadyEnteredMarker = true
hasEnteredMarker(currentZone)
ESX.TextUI(currentActionMsg)
end
---@param label any
local function showHelpText(label)
BeginTextCommandDisplayHelp('STRING')
AddTextComponentSubstringPlayerName(label)
EndTextCommandDisplayHelp(0, false, true, 1)
end

if not isInMarker and hasAlreadyEnteredMarker then
hasAlreadyEnteredMarker = false
ESX.HideUI()
hasExitedMarker(lastZone)
end

Wait(sleep)
end
CreateThread(function()
while true do
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local nearby = false
local inInteractRange = false

for _, loc in ipairs(Config.Locations or {}) do
local coords = loc.coords
local distance = #(playerCoords - coords)
if distance < 20.0 then
nearby = true
if loc.marker ~= false then
DrawMarker(
2,
coords.x, coords.y, coords.z,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.2, 0.2, 0.2,
204, 153, 0, 200,
false, true, 2, true, nil, nil, false
)
end
if distance < 1.8 then
inInteractRange = true
if not isShopUiOpen then
local helpText = 'Press ~INPUT_CONTEXT~ to open shop'
if type(_U) == 'function' then
local translated = _U('open_shop_help')
if type(translated) == 'string' and translated ~= '' then
helpText = translated
end
end
showHelpText(helpText)
end
if IsControlJustPressed(0, 38) then -- INPUT_PICKUP (E)
openShopUi()
end
end
end
end

if nearby then
Wait(0)
else
Wait(500)
end
end
end)

ESX.RegisterInteraction("shop_menu", function()
openShopMenu(currentActionData.zone)
end, function()
return currentAction and currentAction == 'shop_menu'
end)
112 changes: 21 additions & 91 deletions [esx_addons]/esx_shops/config.lua
Original file line number Diff line number Diff line change
@@ -1,98 +1,28 @@
Config = {}
Config.DrawDistance = 7.5
Config.MarkerSize = {x = 1.1, y = 0.7, z = 1.1}
Config.MarkerType = 29
Config.MarkerColor = {r = 50, g = 200, b = 50, a = 200}
Config.Locale = GetConvar('esx:locale', 'en')

Config.Zones = {

TwentyFourSeven = {
Items = {
{
name = "bread",
label = TranslateCap('bread'),
price = 100
},
{
name = "water",
label = TranslateCap('water'),
price = 100
}
},
Pos = {
vector3(373.8, 325.8, 103.5),
vector3(2557.4, 382.2, 108.6),
vector3(-3038.9, 585.9, 7.9),
vector3(-3241.9, 1001.4, 12.8),
vector3(547.4, 2671.7, 42.1),
vector3(1961.4, 3740.6, 32.3),
vector3(2678.9, 3280.6, 55.2),
vector3(1729.2, 6414.1, 35.0)
},
Size = 0.8,
Type = 59,
Color = 25,
ShowBlip = true,
ShowMarker = true
},
Config.Locale = GetConvar('esx:locale', 'en')

RobsLiquor = {
Items = {
{
name = "bread",
label = TranslateCap('bread'),
price = 100
},
{
name = "water",
label = TranslateCap('water'),
price = 100
}
},
Pos = {
vector3(1135.8, -982.2, 46.4),
vector3(-1222.9, -906.9, 12.3),
vector3(-1487.5, -379.1, 40.1),
vector3(-2968.2, 390.9, 15.0),
vector3(1166.0, 2708.9, 38.1),
vector3(1392.5, 3604.6, 34.9),
vector3(127.8, -1284.7, 29.2), --StripClub
vector3(-1393.4, -606.6, 30.3), --Tequila la
vector3(-559.9, 287.0, 82.1) --Bahamamas
},
Size = 0.8,
Type = 59,
Color = 25,
ShowBlip = true,
ShowMarker = true
},
Config.ItemMaxQuantity = 100

LTDgasoline = {
Items = {
{
name = "bread",
label = TranslateCap('bread'),
price = 100
},
{
name = "water",
label = TranslateCap('water'),
price = 100
}
},
Pos = {
vector3(-48.5, -1757.5, 29.4),
vector3(1163.3, -323.8, 69.2),
vector3(-707.5, -914.2, 19.2),
vector3(-1820.5, 792.5, 138.1),
vector3(1698.3, 4924.4, 42.0)
},
Size = 0.8,
Type = 59,
Color = 25,
ShowBlip = true,
ShowMarker = true
Config.Categories = {
{ id = 'drinks', label = 'Drinks' },
{ id = 'food', label = 'Food' },
{ id = 'essentials', label = 'Essentials' },
{ id = 'others', label = 'Others' }
}

Config.Items = {
{ name = 'water', label = 'Water', price = 200, category = 'drinks', amount = 1, image = 'https://r2.fivemanage.com/R92pivz8ZlXwjJjTvi3Oq/water.png' },
{ name = 'sandwich', label = 'Sandwich', price = 500, category = 'drinks', amount = 1, image = 'https://r2.fivemanage.com/R92pivz8ZlXwjJjTvi3Oq/sprunk.png' },
{ name = 'donut', label = 'Donut', price = 50, category = 'food', amount = 1, image = 'https://r2.fivemanage.com/R92pivz8ZlXwjJjTvi3Oq/donut.png' },
{ name = 'pizza', label = 'Pizza', price = 9900, category = 'food', amount = 1, image = 'https://r2.fivemanage.com/R92pivz8ZlXwjJjTvi3Oq/pizza_ham_slice.png' },
{ name = 'lockpick', label = 'Lockpick', price = 2500, category = 'essentials', amount = 1, image = 'https://r2.fivemanage.com/R92pivz8ZlXwjJjTvi3Oq/lockpick.png' }
}

-- Shop locations. Add as many as you want.
-- Each entry: { coords = vector3(x, y, z), marker = true/false, text = 'Display name' }
Config.Locations = {
{ coords = vector3(25.740662, -1347.652710, 29.482056), marker = true, text = 'Shop' },
{ coords = vector3(25.767035, -1345.173584, 29.482056), marker = true, text = 'Shop' },
-- you can add more locations as you want
}
11 changes: 10 additions & 1 deletion [esx_addons]/esx_shops/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ game 'gta5'
description 'A shop system for ESX Legacy, to allow players to buy items'
lua54 'yes'
version '1.2'
legacyversion '1.13.4'

shared_script '@es_extended/imports.lua'

Expand All @@ -25,3 +24,13 @@ server_scripts {
}

dependency 'es_extended'

ui_page {
'html/index.html',
}

files {
'html/index.html',
'html/app.js',
'html/style.css',
}
Loading
Loading