Turfwar/server/gang_shops.lua

246 lines
8.0 KiB
Lua

-- server/gang_shops.lua
print("^2[turfwar]^7 gang_shops.lua loaded (server)")
Config = Config or {}
Config.Shops = Config.Shops or {}
-- IMPORTANT:
-- This assumes you already have:
-- - player gang stored server-side somewhere, OR a callback/event to fetch it.
--
-- Below uses a simple server cache:
local playerGang = {} -- [src] = gangId
-- You likely already broadcast this elsewhere.
-- Hook into your existing gang set event if you have one.
RegisterNetEvent("turfwar:myGang:set", function(gangId)
local src = source
playerGang[src] = tonumber(gangId) or 0
end)
AddEventHandler("playerDropped", function()
local src = source
playerGang[src] = nil
end)
local function getGangId(src)
return tonumber(playerGang[src]) or 0
end
-- =========================
-- DB helpers (gang bank)
-- =========================
local function dbFetchBalance(gangId, cb)
exports.oxmysql:query("SELECT balance FROM turfwar_gang_accounts WHERE gang_id = ? LIMIT 1", { gangId }, function(rows)
local bal = 0
if rows and rows[1] and rows[1].balance then bal = tonumber(rows[1].balance) or 0 end
cb(bal)
end)
end
local function dbEnsureRow(gangId, cb)
exports.oxmysql:query("INSERT IGNORE INTO turfwar_gang_accounts (gang_id, balance) VALUES (?, 0)", { gangId }, function()
cb()
end)
end
local function dbDeduct(gangId, amount, cb)
amount = tonumber(amount) or 0
if amount <= 0 then cb(false, "bad_amount") return end
dbEnsureRow(gangId, function()
exports.oxmysql:query("UPDATE turfwar_gang_accounts SET balance = balance - ? WHERE gang_id = ? AND balance >= ?", {
amount, gangId, amount
}, function(result)
-- oxmysql UPDATE result varies by version; handle common cases:
local changed = 0
if type(result) == "table" and result.affectedRows then changed = result.affectedRows end
if type(result) == "number" then changed = result end
cb(changed and changed > 0, changed and changed > 0 and nil or "insufficient")
end)
end)
end
-- =========================
-- Lookup helpers
-- =========================
local function findWeaponItem(itemId)
if not Config.Shops or not Config.Shops.WeaponList then return nil end
for _, it in ipairs(Config.Shops.WeaponList) do
if it.id == itemId then return it end
end
return nil
end
local function findAmmoItem(itemId)
if not Config.Shops or not Config.Shops.AmmoList then return nil end
for _, it in ipairs(Config.Shops.AmmoList) do
if it.id == itemId then return it end
end
return nil
end
local function findVehicleItem(itemId)
if not Config.Shops or not Config.Shops.VehicleList then return nil end
for _, it in ipairs(Config.Shops.VehicleList) do
if it.id == itemId then return it end
end
return nil
end
-- =========================
-- Purchase: weapons
-- =========================
RegisterNetEvent("turfwar:shop:buyWeapon", function(itemId)
local src = source
local gangId = getGangId(src)
if not (Config.Shops.AllowedGang and Config.Shops.AllowedGang(gangId)) then
TriggerClientEvent("turfwar:shop:notify", src, "~r~You can't use the gang shop.")
return
end
local item = findWeaponItem(itemId)
if not item then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Invalid item.")
return
end
local price = tonumber(item.price) or 0
if price < 0 then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Bad price config.")
return
end
dbDeduct(gangId, price, function(ok, reason)
if not ok then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Not enough gang cash.")
return
end
-- Grant on client (server-authoritative purchase)
TriggerClientEvent("turfwar:shop:grantWeapon", src, item, gangId)
TriggerClientEvent("turfwar:shop:notify", src, ("~g~Purchased: ~s~%s"):format(item.label or item.id))
TriggerClientEvent("turfwar:gangbank:requestRefresh", src) -- optional hook
end)
end)
RegisterNetEvent("turfwar:shop:buyAmmo", function(itemId)
local src = source
local gangId = getGangId(src)
if not (Config.Shops.AllowedGang and Config.Shops.AllowedGang(gangId)) then
TriggerClientEvent("turfwar:shop:notify", src, "~r~You can't use the gang shop.")
return
end
local item = findAmmoItem(itemId)
if not item then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Invalid ammo item.")
return
end
local price = tonumber(item.price) or 0
if price <= 0 then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Bad price config.")
return
end
dbDeduct(gangId, price, function(ok)
if not ok then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Not enough gang cash.")
return
end
TriggerClientEvent("turfwar:shop:grantAmmo", src, item)
TriggerClientEvent("turfwar:shop:notify", src, ("~g~Purchased: ~s~%s"):format(item.label or item.id))
TriggerClientEvent("turfwar:gangbank:requestRefresh", src)
end)
end)
-- =========================
-- Purchase: vehicles
-- =========================
RegisterNetEvent("turfwar:shop:buyVehicle", function(itemId)
local src = source
local gangId = getGangId(src)
if not (Config.Shops.AllowedGang and Config.Shops.AllowedGang(gangId)) then
TriggerClientEvent("turfwar:shop:notify", src, "~r~You can't use the gang shop.")
return
end
local item = findVehicleItem(itemId)
if not item then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Invalid vehicle.")
return
end
local price = tonumber(item.price)
if price == nil then price = 0 end
-- Allow FREE vehicles (price = 0). Only reject negative.
if price < 0 then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Bad price config.")
return
end
local function afterPaid()
-- Use your existing spawn-pad system
if not VehicleSpawner or not VehicleSpawner.SpawnModelFor then
TriggerClientEvent("turfwar:shop:notify", src, "~r~VehicleSpawner not available.")
return
end
-- Support special model alias for "gang default"
local model = item.model
if model == "__GANG_DEFAULT__" then
model = (Config.Vehicles and Config.Vehicles.gangModels and Config.Vehicles.gangModels[gangId])
end
if type(model) ~= "string" or model == "" then
TriggerClientEvent("turfwar:shop:notify", src, "~r~No vehicle configured for your gang.")
return
end
local ok2, reason = VehicleSpawner.SpawnModelFor(src, model, { platePrefix = "G" })
if not ok2 then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Vehicle spawn failed.")
return
end
TriggerClientEvent("turfwar:shop:notify", src, ("~g~Purchased: ~s~%s"):format(item.label or item.id))
TriggerClientEvent("turfwar:gangbank:requestRefresh", src)
end
-- If free, don't touch the gang bank
if price == 0 then
afterPaid()
return
end
-- Deduct first (server authority)
dbDeduct(gangId, price, function(ok)
if not ok then
TriggerClientEvent("turfwar:shop:notify", src, "~r~Not enough gang cash.")
return
end
afterPaid()
end)
end)
-- Optional: allow client to query gang balance (for UI)
RegisterNetEvent("turfwar:shop:getBalance", function()
local src = source
local gangId = getGangId(src)
if gangId <= 0 then
TriggerClientEvent("turfwar:shop:balance", src, 0)
return
end
dbFetchBalance(gangId, function(bal)
TriggerClientEvent("turfwar:shop:balance", src, bal)
end)
end)