mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-31 10:18:54 +00:00
Major improvements, added slider
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
|
||||
|
||||
description 'ESX Shops'
|
||||
|
||||
version '1.1.0'
|
||||
version '1.2.0'
|
||||
|
||||
client_scripts {
|
||||
'@es_extended/locale.lua',
|
||||
|
||||
+43
-24
@@ -4,15 +4,17 @@ local LastZone = nil
|
||||
local CurrentAction = nil
|
||||
local CurrentActionMsg = ''
|
||||
local CurrentActionData = {}
|
||||
local PlayerData = {}
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
while ESX == nil do
|
||||
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
|
||||
Citizen.Wait(5000)
|
||||
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
|
||||
ESX.TriggerServerCallback('esx_shops:requestDBItems', function(ShopItems)
|
||||
for k,v in pairs(ShopItems) do
|
||||
Config.Zones[k].Items = v
|
||||
@@ -20,38 +22,55 @@ Citizen.CreateThread(function()
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
function OpenShopMenu(zone)
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
|
||||
local elements = {}
|
||||
for i=1, #Config.Zones[zone].Items, 1 do
|
||||
|
||||
local item = Config.Zones[zone].Items[i]
|
||||
|
||||
table.insert(elements, {
|
||||
label = item.label .. ' - <span style="color: green;">$' .. item.price .. '</span>',
|
||||
realLabel = item.label,
|
||||
value = item.name,
|
||||
price = item.price
|
||||
label = item.label .. ' - <span style="color: green;">$' .. item.price .. '</span>',
|
||||
label_real = item.label,
|
||||
item = item.item,
|
||||
price = item.price,
|
||||
|
||||
-- menu properties
|
||||
value = 1,
|
||||
type = 'slider',
|
||||
min = 1,
|
||||
max = item.limit
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.CloseAll()
|
||||
ESX.UI.Menu.Open(
|
||||
'default', GetCurrentResourceName(), 'shop',
|
||||
{
|
||||
title = _U('shop'),
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop', {
|
||||
title = _U('shop'),
|
||||
align = 'bottom-right',
|
||||
elements = elements
|
||||
}, function(data, menu)
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop_confirm', {
|
||||
title = _U('shop_confirm', data.current.value, data.current.label_real, data.current.price * data.current.value),
|
||||
align = 'bottom-right',
|
||||
elements = elements
|
||||
},
|
||||
function(data, menu)
|
||||
TriggerServerEvent('esx_shops:buyItem', data.current.value, data.current.price)
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
CurrentAction = 'shop_menu'
|
||||
CurrentActionMsg = _U('press_menu')
|
||||
CurrentActionData = {zone = zone}
|
||||
end
|
||||
)
|
||||
elements = {
|
||||
{label = _U('no'), value = 'no'},
|
||||
{label = _U('yes'), value = 'yes'}
|
||||
}
|
||||
}, function(data2, menu2)
|
||||
if data2.current.value == 'yes' then
|
||||
TriggerServerEvent('esx_shops:buyItem', data.current.item, data.current.value, zone)
|
||||
end
|
||||
|
||||
menu2.close()
|
||||
end, function(data2, menu2)
|
||||
menu2.close()
|
||||
end)
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
CurrentAction = 'shop_menu'
|
||||
CurrentActionMsg = _U('press_menu')
|
||||
CurrentActionData = {zone = zone}
|
||||
end)
|
||||
end
|
||||
|
||||
AddEventHandler('esx_shops:hasEnteredMarker', function(zone)
|
||||
|
||||
+7
-8
@@ -1,16 +1,15 @@
|
||||
USE `essentialmode`;
|
||||
|
||||
CREATE TABLE `shops` (
|
||||
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`item` varchar(255) NOT NULL,
|
||||
`price` int(11) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`store` varchar(100) NOT NULL,
|
||||
`item` varchar(100) NOT NULL,
|
||||
`price` int(11) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
INSERT INTO `shops` (name, item, price) VALUES
|
||||
INSERT INTO `shops` (store, item, price) VALUES
|
||||
('TwentyFourSeven','bread',30),
|
||||
('TwentyFourSeven','water',15),
|
||||
('RobsLiquor','bread',30),
|
||||
|
||||
+9
-6
@@ -1,8 +1,11 @@
|
||||
Locales['br'] = {
|
||||
['shop'] = 'Comprar',
|
||||
['shops'] = 'Lojas',
|
||||
['press_menu'] = 'Pressione ~INPUT_CONTEXT~ para acessar a loja.',
|
||||
['bought'] = 'você comprou ~b~1x ',
|
||||
['not_enough'] = 'você não tem ~r~dinheiro suficiente~s~.',
|
||||
['player_cannot_hold'] = 'Você ~r~não~s~ tem bastante ~y~espaço livre~s~ no seu inventário!',
|
||||
['shop'] = 'comprar',
|
||||
['shops'] = 'lojas',
|
||||
['press_menu'] = 'pressione ~INPUT_CONTEXT~ para acessar a loja.',
|
||||
['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['not_enough'] = 'você não tem ~r~dinheiro suficiente~s~: %s',
|
||||
['player_cannot_hold'] = 'você ~r~não~s~ tem bastante ~y~espaço livre~s~ no seu inventário!',
|
||||
['shop_confirm'] = 'buy %sx %s for $%s?',
|
||||
['no'] = 'no',
|
||||
['yes'] = 'yes',
|
||||
}
|
||||
|
||||
+9
-7
@@ -1,9 +1,11 @@
|
||||
Locales['de'] = {
|
||||
|
||||
['shop'] = 'Geschäft',
|
||||
['shops'] = 'Geschäfte',
|
||||
['press_menu'] = 'Drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.',
|
||||
['bought'] = 'du kaufst ~b~1x ',
|
||||
['not_enough'] = 'du ~r~hast nicht~s~ genug Geld.'
|
||||
|
||||
['shop'] = 'geschäft',
|
||||
['shops'] = 'geschäfte',
|
||||
['press_menu'] = 'drücke ~INPUT_CONTEXT~ um auf das Geschäft zuzugreifen.',
|
||||
['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['not_enough'] = 'du ~r~hast nicht~s~ genug geld: %s',
|
||||
['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!',
|
||||
['shop_confirm'] = 'buy %sx %s for $%s?',
|
||||
['no'] = 'no',
|
||||
['yes'] = 'yes',
|
||||
}
|
||||
|
||||
+4
-1
@@ -2,7 +2,10 @@ Locales['en'] = {
|
||||
['shop'] = 'shop',
|
||||
['shops'] = 'shops',
|
||||
['press_menu'] = 'press ~INPUT_CONTEXT~ to access the ~y~store~s~.',
|
||||
['bought'] = 'you just bought ~y~1x~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['not_enough'] = 'you do not have ~r~enough~s~ money, you\'re ~y~missing~s~ ~r~$%s~s~!',
|
||||
['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!',
|
||||
['shop_confirm'] = 'buy %sx %s for $%s?',
|
||||
['no'] = 'no',
|
||||
['yes'] = 'yes',
|
||||
}
|
||||
+9
-7
@@ -1,9 +1,11 @@
|
||||
Locales['es'] = {
|
||||
|
||||
['shop'] = 'Tienda',
|
||||
['shops'] = 'Tiendas',
|
||||
['press_menu'] = 'Presiona ~INPUT_CONTEXT~ para acceder a la tienda.',
|
||||
['bought'] = 'Has comprado ~b~1 ',
|
||||
['not_enough'] = 'No tienes ~r~suficiente ~s~ dinero.',
|
||||
|
||||
['shop'] = 'tienda',
|
||||
['shops'] = 'tiendas',
|
||||
['press_menu'] = 'presiona ~INPUT_CONTEXT~ para acceder a la tienda.',
|
||||
['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['not_enough'] = 'no tienes ~r~suficiente ~s~ dinero: %s',
|
||||
['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!',
|
||||
['shop_confirm'] = 'buy %sx %s for $%s?',
|
||||
['no'] = 'no',
|
||||
['yes'] = 'yes',
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,9 +1,11 @@
|
||||
Locales['fr'] = {
|
||||
|
||||
['shop'] = 'magasin',
|
||||
['shops'] = 'magasins',
|
||||
['press_menu'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder au magasin.',
|
||||
['bought'] = 'vous avez acheté ~b~1x ',
|
||||
['not_enough'] = 'vous n\'avez ~r~pas assez~s~ d\'argent.',
|
||||
|
||||
['bought'] = 'you just bought ~y~%sx~s~ ~b~%s~s~ for ~r~$%s~s~',
|
||||
['not_enough'] = 'vous n\'avez ~r~pas assez~s~ d\'argent: %s',
|
||||
['player_cannot_hold'] = 'you do ~r~not~s~ have enough ~y~free space~s~ in your inventory!',
|
||||
['shop_confirm'] = 'buy %sx %s for $%s?',
|
||||
['no'] = 'no',
|
||||
['yes'] = 'yes',
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,8 +1,11 @@
|
||||
Locales['sv'] = {
|
||||
['shop'] = 'affär',
|
||||
['shops'] = 'affärer',
|
||||
['press_menu'] = 'tryck ~INPUT_CONTEXT~ för att ~y~handla prylar~w~.',
|
||||
['bought'] = 'du har köpt ~y~1x~w~ ~b~%s~w~ för ~r~$%s~w~',
|
||||
['not_enough'] = 'du har inte ~r~tillräckligt~s~ med pengar, det ~y~saknas~w~ ~r~$%s~w~!',
|
||||
['player_cannot_hold'] = 'du har ~r~inte~w~ tillräckligt med ~y~utrymme~w~ för att hålla det!',
|
||||
['press_menu'] = 'tryck ~INPUT_CONTEXT~ för att ~y~handla prylar~s~.',
|
||||
['bought'] = 'du har köpt ~y~%sx~s~ ~b~%s~s~ för ~r~$%s~s~',
|
||||
['not_enough'] = 'du har inte ~r~tillräckligt~s~ med pengar, det ~y~saknas~s~ ~r~$%s~s~!',
|
||||
['player_cannot_hold'] = 'du har ~r~inte~s~ tillräckligt med ~y~utrymme~s~ för att hålla det!',
|
||||
['shop_confirm'] = 'köpa %sx %s för $%s?',
|
||||
['no'] = 'nej',
|
||||
['yes'] = 'ja',
|
||||
}
|
||||
+69
-42
@@ -1,70 +1,97 @@
|
||||
ESX = nil
|
||||
local ItemsLabels = {}
|
||||
ESX = nil
|
||||
local ShopItems = {}
|
||||
local hasSqlRun = false
|
||||
|
||||
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
||||
|
||||
-- Load item labels
|
||||
Citizen.CreateThread(function()
|
||||
Citizen.Wait(5000)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM items',
|
||||
{},
|
||||
function(result)
|
||||
for i=1, #result, 1 do
|
||||
ItemsLabels[result[i].name] = result[i].label
|
||||
end
|
||||
end)
|
||||
-- Load items
|
||||
AddEventHandler('onMySQLReady', function()
|
||||
hasSqlRun = true
|
||||
LoadShop()
|
||||
end)
|
||||
|
||||
ESX.RegisterServerCallback('esx_shops:requestDBItems', function(source, cb)
|
||||
-- extremely useful when restarting script mid-game
|
||||
Citizen.CreateThread(function()
|
||||
Citizen.Wait(20000) -- hopefully enough for connection to the SQL server
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM shops',
|
||||
{},
|
||||
function(result)
|
||||
local shopItems = {}
|
||||
for i=1, #result, 1 do
|
||||
if shopItems[result[i].name] == nil then
|
||||
shopItems[result[i].name] = {}
|
||||
end
|
||||
|
||||
table.insert(shopItems[result[i].name], {
|
||||
name = result[i].item,
|
||||
price = result[i].price,
|
||||
label = ItemsLabels[result[i].item]
|
||||
})
|
||||
if not hasSqlRun then
|
||||
LoadShop()
|
||||
hasSqlRun = true
|
||||
end
|
||||
end)
|
||||
|
||||
function LoadShop()
|
||||
local itemResult = MySQL.Sync.fetchAll('SELECT * FROM items')
|
||||
local shopResult = MySQL.Sync.fetchAll('SELECT * FROM shops')
|
||||
|
||||
local itemInformation = {}
|
||||
for i=1, #itemResult, 1 do
|
||||
if itemInformation[itemResult[i].name] == nil then
|
||||
itemInformation[itemResult[i].name] = {}
|
||||
end
|
||||
cb(shopItems)
|
||||
end)
|
||||
|
||||
itemInformation[itemResult[i].name].label = itemResult[i].label
|
||||
itemInformation[itemResult[i].name].limit = itemResult[i].limit
|
||||
end
|
||||
|
||||
for i=1, #shopResult, 1 do
|
||||
if ShopItems[shopResult[i].store] == nil then
|
||||
ShopItems[shopResult[i].store] = {}
|
||||
end
|
||||
|
||||
table.insert(ShopItems[shopResult[i].store], {
|
||||
label = itemInformation[shopResult[i].item].label,
|
||||
item = shopResult[i].item,
|
||||
price = shopResult[i].price,
|
||||
limit = itemInformation[shopResult[i].item].limit
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
ESX.RegisterServerCallback('esx_shops:requestDBItems', function(source, cb)
|
||||
if not hasSqlRun then
|
||||
TriggerClientEvent('esx:showNotification', source, 'The shop database has not been loaded yet, try again in a few moments.')
|
||||
end
|
||||
|
||||
cb(ShopItems)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx_shops:buyItem')
|
||||
AddEventHandler('esx_shops:buyItem', function(itemName, price)
|
||||
AddEventHandler('esx_shops:buyItem', function(itemName, amount, zone)
|
||||
local _source = source
|
||||
local xPlayer = ESX.GetPlayerFromId(_source)
|
||||
local sourceItem = xPlayer.getInventoryItem(itemName)
|
||||
|
||||
-- is the player trying to cheat?
|
||||
if price < 0 then
|
||||
print('esx_shops: ' .. xPlayer.identifier .. ' attempted to cheat money!')
|
||||
|
||||
-- is the player trying to exploit?
|
||||
if amount < 0 then
|
||||
print('esx_shops: ' .. xPlayer.identifier .. ' attempted to exploit the shop!')
|
||||
return
|
||||
end
|
||||
|
||||
-- get price
|
||||
local price = 0
|
||||
local itemLabel = ''
|
||||
for i=1, #ShopItems[zone], 1 do
|
||||
if ShopItems[zone][i].item == itemName then
|
||||
price = ShopItems[zone][i].price
|
||||
itemLabel = ShopItems[zone][i].label
|
||||
break
|
||||
end
|
||||
end
|
||||
price = price * amount
|
||||
|
||||
-- can the player afford this item?
|
||||
if xPlayer.getMoney() >= price then
|
||||
|
||||
-- can the player carry the said amount of x item?
|
||||
if sourceItem.limit ~= -1 and (sourceItem.count + 1) > sourceItem.limit then
|
||||
if sourceItem.limit ~= -1 and (sourceItem.count + amount) > sourceItem.limit then
|
||||
TriggerClientEvent('esx:showNotification', _source, _U('player_cannot_hold'))
|
||||
else
|
||||
xPlayer.removeMoney(price)
|
||||
xPlayer.addInventoryItem(itemName, 1)
|
||||
TriggerClientEvent('esx:showNotification', _source, _U('bought', ItemsLabels[itemName], price))
|
||||
xPlayer.addInventoryItem(itemName, amount)
|
||||
TriggerClientEvent('esx:showNotification', _source, _U('bought', amount, itemLabel, price))
|
||||
end
|
||||
else
|
||||
local missingMoney = price - xPlayer.getMoney()
|
||||
TriggerClientEvent('esx:showNotification', _source, _U('not_enough', missingMoney))
|
||||
end
|
||||
|
||||
end)
|
||||
Reference in New Issue
Block a user