-- 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 ") 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 ") 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 ") end) RegisterCommand("gshop_buyweapon", function(_, args) if not allowedGang() then return end local id = args[1] if not id then Notify("Usage: /gshop_buyweapon ") 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 ") 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 ") 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)