254 lines
8.4 KiB
Lua
254 lines
8.4 KiB
Lua
-- client/gang_shops.lua
|
|
print("^2[turfwar]^7 gang_shops.lua loaded (client)")
|
|
|
|
Config = Config or {}
|
|
Config.Shops = Config.Shops or {}
|
|
Config.GANGS = Config.GANGS or {}
|
|
|
|
local currentGang = 0
|
|
local lastBal = 0
|
|
|
|
-- =========================
|
|
-- Helpers
|
|
-- =========================
|
|
local function Notify(msg)
|
|
BeginTextCommandThefeedPost("STRING")
|
|
AddTextComponentSubstringPlayerName(msg)
|
|
EndTextCommandThefeedPostTicker(false, false)
|
|
end
|
|
|
|
local function Draw3DText(x, y, z, text)
|
|
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
|
|
if not onScreen then return end
|
|
SetTextScale(0.35, 0.35)
|
|
SetTextFont(4)
|
|
SetTextProportional(1)
|
|
SetTextEntry("STRING")
|
|
SetTextCentre(1)
|
|
AddTextComponentString(text)
|
|
DrawText(_x, _y)
|
|
end
|
|
|
|
local function allowedGang()
|
|
if Config.Shops.AllowedGang then return Config.Shops.AllowedGang(currentGang) end
|
|
return currentGang ~= 0 and currentGang ~= 3
|
|
end
|
|
|
|
local function gangRGB(gangId)
|
|
local g = Config.GANGS and Config.GANGS[gangId]
|
|
if g and g.rgb and #g.rgb == 3 then
|
|
return g.rgb[1], g.rgb[2], g.rgb[3]
|
|
end
|
|
return 255, 255, 255
|
|
end
|
|
|
|
-- =========================
|
|
-- Receive gang updates
|
|
-- Hook into your existing system.
|
|
-- =========================
|
|
RegisterNetEvent("turfwar:myGang", function(gangId)
|
|
currentGang = tonumber(gangId) or 0
|
|
TriggerServerEvent("turfwar:myGang:set", currentGang) -- keep server cache aligned
|
|
end)
|
|
|
|
-- Fallback if your server broadcasts playerGang (you can remove if not needed)
|
|
RegisterNetEvent("turfwar:playerGang", function(src, gangId)
|
|
if src == GetPlayerServerId(PlayerId()) then
|
|
currentGang = tonumber(gangId) or 0
|
|
TriggerServerEvent("turfwar:myGang:set", currentGang)
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent("turfwar:shop:notify", function(msg)
|
|
Notify(msg)
|
|
end)
|
|
|
|
RegisterNetEvent("turfwar:shop:balance", function(bal)
|
|
lastBal = tonumber(bal) or 0
|
|
end)
|
|
|
|
RegisterNetEvent("turfwar:gangbank:requestRefresh", function()
|
|
-- If you already have a gangbank refresh event, call it here.
|
|
-- Otherwise harmless.
|
|
TriggerServerEvent("turfwar:gangbank:request")
|
|
end)
|
|
|
|
-- =========================
|
|
-- Grant weapon/ammo (after server approves purchase)
|
|
-- =========================
|
|
RegisterNetEvent("turfwar:shop:grantWeapon", function(item, gangId)
|
|
if not item then return end
|
|
local ped = PlayerPedId()
|
|
|
|
if item.armor then
|
|
local amt = tonumber(item.armorAmount) or 50
|
|
local cur = GetPedArmour(ped)
|
|
SetPedArmour(ped, math.min(100, cur + amt))
|
|
return
|
|
end
|
|
|
|
local wep = item.weapon
|
|
if not wep then return end
|
|
|
|
local hash = GetHashKey(wep)
|
|
if not HasPedGotWeapon(ped, hash, false) then
|
|
GiveWeaponToPed(ped, hash, 0, false, true)
|
|
end
|
|
|
|
local ammo = tonumber(item.ammo) or 0
|
|
if ammo > 0 then
|
|
AddAmmoToPed(ped, hash, ammo)
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent("turfwar:shop:grantAmmo", function(item)
|
|
if not item or not item.weapon then return end
|
|
local ped = PlayerPedId()
|
|
local hash = GetHashKey(item.weapon)
|
|
local ammo = tonumber(item.ammo) or 0
|
|
if ammo > 0 then
|
|
AddAmmoToPed(ped, hash, ammo)
|
|
end
|
|
end)
|
|
|
|
-- =========================
|
|
-- Spawn purchased vehicle (after server approves)
|
|
-- =========================
|
|
local function loadModel(model)
|
|
local hash = type(model) == "number" and model or GetHashKey(model)
|
|
if not IsModelInCdimage(hash) then return nil end
|
|
RequestModel(hash)
|
|
local timeout = GetGameTimer() + 5000
|
|
while not HasModelLoaded(hash) do
|
|
Wait(10)
|
|
if GetGameTimer() > timeout then return nil end
|
|
end
|
|
return hash
|
|
end
|
|
|
|
RegisterNetEvent("turfwar:shop:spawnPurchasedVehicle", function(item, gangId)
|
|
if not item or not item.model then return end
|
|
local ped = PlayerPedId()
|
|
local p = GetEntityCoords(ped)
|
|
local h = GetEntityHeading(ped)
|
|
|
|
local hash = loadModel(item.model)
|
|
if not hash then
|
|
Notify("~r~Vehicle model failed to load.")
|
|
return
|
|
end
|
|
|
|
-- Spawn in front of player
|
|
local forward = (Config.Shops.VehicleSpawn and Config.Shops.VehicleSpawn.forward) or 6.0
|
|
local up = (Config.Shops.VehicleSpawn and Config.Shops.VehicleSpawn.up) or 0.2
|
|
|
|
local fw = GetEntityForwardVector(ped)
|
|
local spawn = vector3(p.x + fw.x * forward, p.y + fw.y * forward, p.z + up)
|
|
|
|
local veh = CreateVehicle(hash, spawn.x, spawn.y, spawn.z, h, true, false)
|
|
SetModelAsNoLongerNeeded(hash)
|
|
|
|
if veh and veh ~= 0 then
|
|
SetVehicleOnGroundProperly(veh)
|
|
|
|
-- Gang color
|
|
local r,g,b = gangRGB(gangId)
|
|
SetVehicleCustomPrimaryColour(veh, r, g, b)
|
|
SetVehicleCustomSecondaryColour(veh, r, g, b)
|
|
|
|
-- Nice defaults
|
|
SetVehicleDirtLevel(veh, 0.0)
|
|
SetVehicleEngineOn(veh, true, true, false)
|
|
|
|
-- Warp player in
|
|
TaskWarpPedIntoVehicle(ped, veh, -1)
|
|
end
|
|
end)
|
|
|
|
-- =========================
|
|
-- “UI”: simple chat/menu commands (starter)
|
|
-- Later we can move to NUI
|
|
-- =========================
|
|
local function printShopList(title, list)
|
|
TriggerServerEvent("turfwar:shop:getBalance")
|
|
Wait(150)
|
|
|
|
print(("^3[turfwar]^7 === %s === (Gang Balance: %s)"):format(title, lastBal))
|
|
for _, it in ipairs(list) do
|
|
print(("^3[turfwar]^7 - %s ^2$%d^7 (id: %s)"):format(it.label or it.id, it.price or 0, it.id))
|
|
end
|
|
end
|
|
|
|
RegisterCommand("gshop_weapons", function()
|
|
if not allowedGang() then Notify("~r~Gang shop not available for your faction.") return end
|
|
printShopList("WEAPON SHOP", Config.Shops.WeaponList or {})
|
|
Notify("Open console (F8) to see weapon list. Buy: /gshop_buyweapon <id>")
|
|
end)
|
|
|
|
RegisterCommand("gshop_ammo", function()
|
|
if not allowedGang() then Notify("~r~Gang shop not available for your faction.") return end
|
|
printShopList("AMMO SHOP", Config.Shops.AmmoList or {})
|
|
Notify("Open console (F8) to see ammo list. Buy: /gshop_buyammo <id>")
|
|
end)
|
|
|
|
RegisterCommand("gshop_vehicles", function()
|
|
if not allowedGang() then Notify("~r~Gang shop not available for your faction.") return end
|
|
printShopList("VEHICLE SHOP", Config.Shops.VehicleList or {})
|
|
Notify("Open console (F8) to see vehicle list. Buy: /gshop_buyveh <id>")
|
|
end)
|
|
|
|
RegisterCommand("gshop_buyweapon", function(_, args)
|
|
if not allowedGang() then return end
|
|
local id = args[1]
|
|
if not id then Notify("Usage: /gshop_buyweapon <id>") return end
|
|
TriggerServerEvent("turfwar:shop:buyWeapon", id)
|
|
end)
|
|
|
|
RegisterCommand("gshop_buyammo", function(_, args)
|
|
if not allowedGang() then return end
|
|
local id = args[1]
|
|
if not id then Notify("Usage: /gshop_buyammo <id>") return end
|
|
TriggerServerEvent("turfwar:shop:buyAmmo", id)
|
|
end)
|
|
|
|
RegisterCommand("gshop_buyveh", function(_, args)
|
|
if not allowedGang() then return end
|
|
local id = args[1]
|
|
if not id then Notify("Usage: /gshop_buyveh <id>") return end
|
|
TriggerServerEvent("turfwar:shop:buyVehicle", id)
|
|
end)
|
|
|
|
-- =========================
|
|
-- World markers (optional)
|
|
-- Press E near configured coords to open lists
|
|
-- =========================
|
|
CreateThread(function()
|
|
while true do
|
|
Wait(0)
|
|
if not allowedGang() then goto continue end
|
|
|
|
local ped = PlayerPedId()
|
|
local p = GetEntityCoords(ped)
|
|
|
|
local function handleLocations(locs, hint, cmd)
|
|
for _, s in ipairs(locs or {}) do
|
|
local d = #(p - s.coords)
|
|
if d < (Config.Shops.MarkerDist or 25.0) then
|
|
DrawMarker(1, s.coords.x, s.coords.y, s.coords.z - 1.0, 0,0,0, 0,0,0, 1.2,1.2,0.8, 255,255,255, 120, false,true,2, false,nil,nil,false)
|
|
if d < (Config.Shops.UseDist or 2.0) then
|
|
Draw3DText(s.coords.x, s.coords.y, s.coords.z + 0.3, ("~w~%s~n~~y~[E]~w~ %s"):format(s.label or "Shop", hint))
|
|
if IsControlJustPressed(0, Config.Shops.InteractKey or 38) then
|
|
ExecuteCommand(cmd)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
handleLocations(Config.Shops.WeaponShopLocations, "Open Weapon Shop", "gshop_weapons")
|
|
handleLocations(Config.Shops.VehicleShopLocations, "Open Vehicle Shop", "gshop_vehicles")
|
|
|
|
::continue::
|
|
end
|
|
end)
|