diff --git a/README.md b/README.md index 7035ed3..270ea17 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,23 @@ ![Codine Development Fuel Script Banner](https://i.imgur.com/qVOMMvW.png) -# _CDN-Fuel (2.1.1)_ +# _CDN-Fuel (2.1.2)_ A highly in-depth fuel system for **FiveM** with support for the **QBCore Framework & QBox Remastered**. # _Lastest Patch Information_ *Additions:* -- Emergency Services Discounts (Config Enabled) -- Air & Water Vehicle Fueling (Config Enabled) -- Hose Attached To Nozzle (Config Enabled) -- OX Library Support (Menu/Input/Inventory/Target) Additions. -- QBox Framework now supported. -- Electric Vehicles turn off when at 0 fuel. (Config Enabled) +- Various Optimizations Throughout +- Config Option for Having Owners Pickup Reserves they Purchase *Fixes:* -- Bank Payment Double Taxing Payments. -- Paleto Locations PolyZone issue. -- Fix Electric Vehicles Not Stopping On 0 Fuel -- Fix Emergency Services Discounts -- Fix Polyzone for MRPD Helicopter Refuel +- Blip Color on Normal Blip not working. +- [Jerry Can Flipped Orientation](https://github.com/dnelyk/cdn-grub-updates/assets/95599217/0489397e-99c9-43d9-8aab-0d4a45463cfd) +- Various Syphoning Issues (Item Data / Input / Menu etc) +- Various Jerry Can Issues (Similar to Syphon Issues) +- Station Owners Not Recieving Full Price on Discounted Purchases + +*Removals:* +- NPWD "Support" as there are various large issues.

diff --git a/client/fuel_cl.lua b/client/fuel_cl.lua index 7e37e03..1e9b1bb 100644 --- a/client/fuel_cl.lua +++ b/client/fuel_cl.lua @@ -237,6 +237,7 @@ CreateThread(function() TriggerEvent('cdn-fuel:stations:updatelocation', station_id) end else + TriggerEvent('cdn-fuel:stations:updatelocation', nil) inGasStation = false end end) @@ -502,7 +503,7 @@ RegisterNetEvent('cdn-fuel:client:grabnozzle', function() end end holdingnozzle = true - Citizen.CreateThread(function() + CreateThread(function() while holdingnozzle do local currentcoords = GetEntityCoords(ped) local dist = #(grabbednozzlecoords - currentcoords) @@ -1228,7 +1229,7 @@ RegisterNetEvent('cdn-fuel:jerrycan:refuelmenu', function(itemData) title = Lang:t("menu_header_jerry_can"), options = { { - title = Lang:t("menu_header_refuel_jerry_can"), + title = Lang:t("menu_header_refuel_vehicle"), event = 'cdn-fuel:jerrycan:refuelvehicle', args = {itemData = itemData}, disabled = nogas, @@ -1396,6 +1397,7 @@ RegisterNetEvent('cdn-fuel:client:purchasejerrycan', function() end) RegisterNetEvent('cdn-fuel:jerrycan:refuelvehicle', function(data) + local ped = PlayerPedId() local vehicle = GetClosestVehicle() local vehfuel = math.floor(GetFuel(vehicle)) local maxvehrefuel = (100 - math.ceil(vehfuel)) @@ -1425,82 +1427,154 @@ RegisterNetEvent('cdn-fuel:jerrycan:refuelvehicle', function(data) maxvehrefuel = Config.JerryCanCap end if maxvehrefuel >= jerrycanfuelamount then maxvehrefuel = jerrycanfuelamount elseif maxvehrefuel < jerrycanfuelamount then maxvehrefuel = maxvehrefuel end - local refuel = exports['qb-input']:ShowInput({ - header = Lang:t("input_select_refuel_header"), - submitText = Lang:t("input_refuel_submit"), - inputs = { - { - type = 'number', - isRequired = true, - name = 'amount', - text = Lang:t("input_max_fuel_footer_1") .. maxvehrefuel .. Lang:t("input_max_fuel_footer_2") + -- Need to Convert to OX -- + if Config.Ox.Input then + local refuel = lib.inputDialog(Lang:t("input_select_refuel_header"), {Lang:t("input_max_fuel_footer_1") .. maxvehrefuel .. Lang:t("input_max_fuel_footer_2")}) + if not refuel then return end + local refuelAmount = tonumber(refuel[1]) + -- + if refuel and refuelAmount then + if tonumber(refuelAmount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuelAmount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end + if tonumber(refuelAmount) > jerrycanfuelamount then QBCore.Functions.Notify(Lang:t("jerry_can_not_enough_fuel"), 'error') return end + local refueltimer = Config.RefuelTime * tonumber(refuelAmount) + if tonumber(refuelAmount) < 10 then refueltimer = Config.RefuelTime * 10 end + if vehfuel + tonumber(refuelAmount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end + local refuelAmount = tonumber(refuelAmount) + JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false) + local lefthand = GetPedBoneIndex(ped, 18905) + AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right (Kind of)]] , 0.0 --[[Up - Down]], 0.25 --[[Forward - Backward]], 15.0, 170.0, 90.42, 0, 1, 0, 1, 0, 1) + if Config.Ox.Progress then + if lib.progressCircle({ + duration = refueltimer, + label = Lang:t("prog_refueling_vehicle"), + position = 'bottom', + useWhileDead = false, + canCancel = true, + disable = { + car = true, + move = true, + combat = true + }, + anim = { + dict = Config.JerryCanAnimDict, + clip = Config.JerryCanAnim + }, + }) then + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') + local JerryCanItemData = data.itemData + local srcPlayerData = QBCore.Functions.GetPlayerData() + TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, JerryCanItemData) + SetFuel(vehicle, (vehfuel + refuelAmount)) + else + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("cancelled"), 'error') + end + else + QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel + disableMovement = true, + disableCarMovement = true, + disableMouse = false, + disableCombat = true, + }, { + animDict = Config.JerryCanAnimDict, + anim = Config.JerryCanAnim, + flags = 17, + }, {}, {}, function() -- Play When Done + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') + local JerryCanItemData = data.itemData + local srcPlayerData = QBCore.Functions.GetPlayerData() + TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, JerryCanItemData) + SetFuel(vehicle, (vehfuel + refuelAmount)) + end, function() -- Play When Cancel + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("cancelled"), 'error') + end, "jerrycan") + end + end + else + local refuel = exports['qb-input']:ShowInput({ + header = Lang:t("input_select_refuel_header"), + submitText = Lang:t("input_refuel_submit"), + inputs = { + { + type = 'number', + isRequired = true, + name = 'amount', + text = Lang:t("input_max_fuel_footer_1") .. maxvehrefuel .. Lang:t("input_max_fuel_footer_2") + } } - } - }) - if refuel then - if tonumber(refuel.amount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end - if tonumber(refuel.amount) > jerrycanfuelamount then QBCore.Functions.Notify(Lang:t("jerry_can_not_enough_fuel"), 'error') return end - local refueltimer = Config.RefuelTime * tonumber(refuel.amount) - if tonumber(refuel.amount) < 10 then refueltimer = Config.RefuelTime * 10 end - if vehfuel + tonumber(refuel.amount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end - local refuelAmount = tonumber(refuel.amount) - JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false) - local lefthand = GetPedBoneIndex(PlayerPedId(), 18905) - AttachEntityToEntity(JerrycanProp, PlayerPedId(), lefthand, 0.11 --[[Left - Right (Kind of)]] , 0.05--[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1) - if Config.Ox.Progress then - if lib.progressCircle({ - duration = refueltimer, - label = Lang:t("prog_refueling_vehicle"), - position = 'bottom', - useWhileDead = false, - canCancel = true, - disable = { - car = true, - move = true, - combat = true - }, - anim = { - dict = Config.JerryCanAnimDict, - clip = Config.JerryCanAnim - }, - }) then - DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) - QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') - local JerryCanItemData = data.itemData - local srcPlayerData = QBCore.Functions.GetPlayerData() - TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, JerryCanItemData) - SetFuel(vehicle, (vehfuel + refuelAmount)) - else - DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) - QBCore.Functions.Notify(Lang:t("cancelled"), 'error') + }) + if refuel then + if tonumber(refuel.amount) == 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return elseif tonumber(refuel.amount) < 0 then QBCore.Functions.Notify(Lang:t("more_than_zero"), 'error') return end + if tonumber(refuel.amount) > jerrycanfuelamount then QBCore.Functions.Notify(Lang:t("jerry_can_not_enough_fuel"), 'error') return end + local refueltimer = Config.RefuelTime * tonumber(refuel.amount) + if tonumber(refuel.amount) < 10 then refueltimer = Config.RefuelTime * 10 end + if vehfuel + tonumber(refuel.amount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end + JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false) + local lefthand = GetPedBoneIndex(ped, 18905) + AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right (Kind of)]] , 0.0 --[[Up - Down]], 0.25 --[[Forward - Backward]], 15.0, 170.0, 90.42, 0, 1, 0, 1, 0, 1) + if Config.Ox.Progress then + if lib.progressCircle({ + duration = refueltimer, + label = Lang:t("prog_refueling_vehicle"), + position = 'bottom', + useWhileDead = false, + canCancel = true, + disable = { + car = true, + move = true, + combat = true + }, + anim = { + dict = Config.JerryCanAnimDict, + clip = Config.JerryCanAnim + }, + }) then + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') + local JerryCanItemData = data.itemData + local srcPlayerData = QBCore.Functions.GetPlayerData() + TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, JerryCanItemData) + SetFuel(vehicle, (vehfuel + refuel.amount)) + else + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("cancelled"), 'error') + end + else + QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel + disableMovement = true, + disableCarMovement = true, + disableMouse = false, + disableCombat = true, + }, { + animDict = Config.JerryCanAnimDict, + anim = Config.JerryCanAnim, + flags = 17, + }, {}, {}, function() -- Play When Done + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') + local JerryCanItemData = data.itemData + local srcPlayerData = QBCore.Functions.GetPlayerData() + TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, JerryCanItemData) + SetFuel(vehicle, (vehfuel + refuel.amount)) + end, function() -- Play When Cancel + DeleteObject(JerrycanProp) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + QBCore.Functions.Notify(Lang:t("cancelled"), 'error') + end, "jerrycan") end - else - QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_refueling_vehicle"), refueltimer, false, true, { -- Name | Label | Time | useWhileDead | canCancel - disableMovement = true, - disableCarMovement = true, - disableMouse = false, - disableCombat = true, - }, { - animDict = Config.JerryCanAnimDict, - anim = Config.JerryCanAnim, - flags = 17, - }, {}, {}, function() -- Play When Done - DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) - QBCore.Functions.Notify(Lang:t("jerry_can_success_vehicle"), 'success') - local JerryCanItemData = data.itemData - local srcPlayerData = QBCore.Functions.GetPlayerData() - TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, JerryCanItemData) - SetFuel(vehicle, (vehfuel + refuel.amount)) - end, function() -- Play When Cancel - DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) - QBCore.Functions.Notify(Lang:t("cancelled"), 'error') - end, "jerrycan") end end + else QBCore.Functions.Notify(Lang:t("need_electric_charger"), 'error', 7500) return end @@ -1521,8 +1595,11 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) else jerrycanfuelamount = itemData.info.gasamount end + + local ped = PlayerPedId() + if Config.Ox.Input then - local JerryCanMaxRefuel = (Config.JerryCanCap - itemData.metadata.cdn_fuel) + local JerryCanMaxRefuel = (Config.JerryCanCap - jerrycanfuelamount) local refuel = lib.inputDialog(Lang:t("input_select_refuel_header"), {Lang:t("input_max_fuel_footer_1") .. JerryCanMaxRefuel .. Lang:t("input_max_fuel_footer_2")}) if not refuel then return end local refuelAmount = tonumber(refuel[1]) @@ -1536,8 +1613,8 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) if not CanAfford(price, "cash") then QBCore.Functions.Notify(Lang:t("not_enough_money_in_cash"), 'error') return end JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false) - local lefthand = GetPedBoneIndex(PlayerPedId(), 18905) - AttachEntityToEntity(JerrycanProp, PlayerPedId(), lefthand, 0.11 --[[Left - Right]] , 0.05--[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1) + local lefthand = GetPedBoneIndex(ped, 18905) + AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right]] , 0.05--[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1) SetEntityVisible(fuelnozzle, false, 0) if lib.progressCircle({ duration = refueltimer, @@ -1557,10 +1634,15 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) }) then SetEntityVisible(fuelnozzle, true, 0) DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("jerry_can_success"), 'success') local srcPlayerData = QBCore.Functions.GetPlayerData() - TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, 'jerrycan') + if Config.Ox.Inventory then + TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, 'jerrycan') + else + TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, itemData) + end + if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", tonumber(refuelAmount), ReserveLevels, CurrentLocation) if CachedFuelPrice ~= nil then @@ -1576,7 +1658,7 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) else SetEntityVisible(fuelnozzle, true, 0) DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end end @@ -1601,8 +1683,8 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) local price = (tonumber(refuel.amount) * FuelPrice) + GlobalTax(tonumber(refuel.amount) * FuelPrice) if not CanAfford(price, "cash") then QBCore.Functions.Notify(Lang:t("not_enough_money_in_cash"), 'error') return end JerrycanProp = CreateObject(joaat('w_am_jerrycan'), 1.0, 1.0, 1.0, true, true, false) - local lefthand = GetPedBoneIndex(PlayerPedId(), 18905) - AttachEntityToEntity(JerrycanProp, PlayerPedId(), lefthand, 0.11 --[[Left - Right]] , 0.05 --[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1) + local lefthand = GetPedBoneIndex(ped, 18905) + AttachEntityToEntity(JerrycanProp, ped, lefthand, 0.11 --[[Left - Right]] , 0.05 --[[Up - Down]], 0.27 --[[Forward - Backward]], -15.0, 170.0, -90.42, 0, 1, 0, 1, 0, 1) SetEntityVisible(fuelnozzle, false, 0) QBCore.Functions.Progressbar('refuel_gas', Lang:t("prog_jerry_can_refuel"), refueltimer, false,true, { -- Name | Label | Time | useWhileDead | canCancel disableMovement = true, @@ -1616,11 +1698,15 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) }, {}, {}, function() -- Play When Done SetEntityVisible(fuelnozzle, true, 0) DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("jerry_can_success"), 'success') local jerryCanData = data.itemData local srcPlayerData = QBCore.Functions.GetPlayerData() - TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuel.amount), srcPlayerData, jerryCanData) + if Config.Ox.Inventory then + TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, 'jerrycan') + else + TriggerServerEvent('cdn-fuel:info', "add", tonumber(refuelAmount), srcPlayerData, jerryCanData) + end if RefuelingType == nil then if Config.PlayerOwnedGasStationsEnabled and not Config.UnlimitedFuel then TriggerServerEvent('cdn-fuel:station:server:updatereserves', "remove", tonumber(refuel.amount), ReserveLevels, CurrentLocation) @@ -1639,7 +1725,7 @@ RegisterNetEvent('cdn-fuel:jerrycan:refueljerrycan', function(data) end, function() -- Play When Cancel SetEntityVisible(fuelnozzle, true, 0) DeleteObject(JerrycanProp) - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end, "jerrycan") end @@ -1787,6 +1873,7 @@ end) RegisterNetEvent('cdn-syphoning:syphon', function(data) local reason = data.reason + local ped = PlayerPedId() if Config.SyphonDebug then print('Item Data Syphon: ' .. json.encode(data.itemData)) end if Config.SyphonDebug then print('Reason: ' .. reason) end local vehicle = GetClosestVehicle() @@ -1816,7 +1903,7 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) local fitamount = (Config.SyphonKitCap - currentsyphonamount) local vehicle = GetClosestVehicle() local vehiclecoords = GetEntityCoords(vehicle) - local pedcoords = GetEntityCoords(PlayerPedId()) + local pedcoords = GetEntityCoords(ped) if #(vehiclecoords - pedcoords) > 2.5 then return end local cargasamount = GetFuel(vehicle) local maxsyphon = math.floor(GetFuel(vehicle)) @@ -1861,9 +1948,9 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) clip = Config.StealAnim }, }) then - StopAnimTask(PlayerPedId(), Config.StealAnimDict, Config.StealAnim, 1.0) + StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0) if GetFuel(vehicle) >= syphonAmount then - PoliceAlert(GetEntityCoords(PlayerPedId())) + PoliceAlert(GetEntityCoords(ped)) QBCore.Functions.Notify(Lang:t("syphon_success"), 'success') SetFuel(vehicle, removeamount) local syphonData = data.itemData @@ -1873,8 +1960,8 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) QBCore.Functions.Notify(Lang:t("menu_syphon_vehicle_empty"), 'error') end else - PoliceAlert(GetEntityCoords(PlayerPedId())) - StopAnimTask(PlayerPedId(), Config.StealAnimDict, Config.StealAnim, 1.0) + PoliceAlert(GetEntityCoords(ped)) + StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end end @@ -1913,19 +2000,19 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) flags = 1, }, {}, {}, function() -- Play When Done if GetFuel(vehicle) >= tonumber(syphon.amount) then - PoliceAlert(GetEntityCoords(PlayerPedId())) + PoliceAlert(GetEntityCoords(ped)) QBCore.Functions.Notify(Lang:t("syphon_success"), 'success') SetFuel(vehicle, removeamount) local syphonData = data.itemData local srcPlayerData = QBCore.Functions.GetPlayerData() TriggerServerEvent('cdn-fuel:info', "add", tonumber(syphon.amount), srcPlayerData, syphonData) - StopAnimTask(PlayerPedId(), Config.StealAnimDict, Config.StealAnim, 1.0) + StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0) else QBCore.Functions.Notify(Lang:t("menu_syphon_vehicle_empty"), 'error') end end, function() -- Play When Cancel - PoliceAlert(GetEntityCoords(PlayerPedId())) - StopAnimTask(PlayerPedId(), Config.StealAnimDict, Config.StealAnim, 1.0) + PoliceAlert(GetEntityCoords(ped)) + StopAnimTask(ped, Config.StealAnimDict, Config.StealAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end, "syphoningkit") end @@ -1949,7 +2036,6 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) if tonumber(refuelAmount) + tonumber(cargasamount) > 100 then QBCore.Functions.Notify(Lang:t("tank_cannot_fit"), 'error') return end local refueltimer = Config.RefuelTime * tonumber(refuelAmount) if tonumber(refuelAmount) < 10 then refueltimer = Config.RefuelTime * 10 end - if lib.progressCircle({ duration = refueltimer, label = Lang:t("prog_refueling_vehicle"), @@ -1966,14 +2052,14 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) clip = Config.JerryCanAnim }, }) then - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("syphon_success_vehicle"), 'success') SetFuel(vehicle, cargasamount + tonumber(refuelAmount)) local syphonData = data.itemData local srcPlayerData = QBCore.Functions.GetPlayerData() TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuelAmount), srcPlayerData, syphonData) else - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end end @@ -2006,14 +2092,14 @@ RegisterNetEvent('cdn-syphoning:syphon', function(data) anim = Config.JerryCanAnim, flags = 17, }, {}, {}, function() -- Play When Done - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("syphon_success_vehicle"), 'success') SetFuel(vehicle, cargasamount + tonumber(refuel.amount)) local syphonData = data.itemData local srcPlayerData = QBCore.Functions.GetPlayerData() TriggerServerEvent('cdn-fuel:info', "remove", tonumber(refuel.amount), srcPlayerData, syphonData) end, function() -- Play When Cancel - StopAnimTask(PlayerPedId(), Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) + StopAnimTask(ped, Config.JerryCanAnimDict, Config.JerryCanAnim, 1.0) QBCore.Functions.Notify(Lang:t("cancelled"), 'error') end, "syphoningkit") end @@ -2098,12 +2184,12 @@ RegisterNetEvent('cdn-fuel:client:grabnozzle:special', function() SetEntityDrawOutline(SpecialFuelNozzleObj --[[ Entity ]], true --[[ boolean ]]) end end - Citizen.CreateThread(function() + CreateThread(function() while HoldingSpecialNozzle do local currentcoords = GetEntityCoords(ped) local dist = #(grabbednozzlecoords - currentcoords) TargetCreated = true - if dist > Config.AirAndWaterVehicleFueling['nozzle_length'] or IsPedInAnyVehicle(PlayerPedId(), false) then + if dist > Config.AirAndWaterVehicleFueling['nozzle_length'] or IsPedInAnyVehicle(ped, false) then HoldingSpecialNozzle = false DeleteObject(SpecialFuelNozzleObj) QBCore.Functions.Notify(Lang:t("nozzle_cannot_reach"), 'error') @@ -2576,6 +2662,8 @@ if Config.VehicleShutoffOnLowFuel['shutOffLevel'] == 0 then Config.VehicleShutoffOnLowFuel['shutOffLevel'] = 0.55 end +-- This loop does use quite a bit of performance, but, is needed due to electric vehicles running without fuel & normal vehicles driving backwards! +-- You can remove if you need the performance, but we believe it is very important. CreateThread(function() while true do Wait(0) diff --git a/client/station_cl.lua b/client/station_cl.lua index 85c6af0..012822c 100644 --- a/client/station_cl.lua +++ b/client/station_cl.lua @@ -3,7 +3,21 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat local QBCore = exports[Config.Core]:GetCoreObject() local PedsSpawned = false + -- These are for fuel pickup: + local CreatedEventHandler = false + local locationSwapHandler + local spawnedTankerTrailer + local spawnedDeliveryTruck + local ReservePickupData = {} + -- Functions + local function RequestAndLoadModel(model) + RequestModel(model) + while not HasModelLoaded(model) do + Wait(5) + end + end + local function UpdateStationInfo(info) if Config.FuelDebug then print("Fetching Information for Location #" ..CurrentLocation) end QBCore.Functions.TriggerCallback('cdn-fuel:server:fetchinfo', function(result) @@ -28,23 +42,20 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat -- Fuel Station's Balance -- if info == "all" or info == "balance" then StationBalance = v.balance - if Config.FuelDebug then print("Successfully Fetched: Balance") end + if Config.FuelDebug then print("Successfully Fetched: Balance") end end ---------------- end end end, CurrentLocation) - end exports(UpdateStationInfo, UpdateStationInfo) + end exports(UpdateStationInfo, UpdateStationInfo) local function SpawnGasStationPeds() if not Config.GasStations or not next(Config.GasStations) or PedsSpawned then return end for i = 1, #Config.GasStations do local current = Config.GasStations[i] current.pedmodel = type(current.pedmodel) == 'string' and joaat(current.pedmodel) or current.pedmodel - RequestModel(current.pedmodel) - while not HasModelLoaded(current.pedmodel) do - Wait(0) - end + RequestAndLoadModel(current.pedmodel) local ped = CreatePed(0, current.pedmodel, current.pedcoords.x, current.pedcoords.y, current.pedcoords.z, current.pedcoords.h, false, false) FreezeEntityPosition(ped, true) SetEntityInvincible(ped, true) @@ -66,10 +77,43 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat PedsSpawned = true end - -- Events + local function GenerateRandomTruckModel() + local possibleTrucks = Config.PossibleDeliveryTrucks + if possibleTrucks then + return possibleTrucks[math.random(#possibleTrucks)] + end + end + + local function SpawnPickupVehicles() + local trailer = GetHashKey('tanker') + local truckToSpawn = GetHashKey(GenerateRandomTruckModel()) + if truckToSpawn then + RequestAndLoadModel(truckToSpawn) + RequestAndLoadModel(trailer) + spawnedDeliveryTruck = CreateVehicle(truckToSpawn, Config.DeliveryTruckSpawns['truck'], true, false) + spawnedTankerTrailer = CreateVehicle(trailer, Config.DeliveryTruckSpawns['trailer'], true, false) + SetModelAsNoLongerNeeded(truckToSpawn) -- removes model from game memory as we no longer need it + SetModelAsNoLongerNeeded(trailer) -- removes model from game memory as we no longer need it + SetEntityAsMissionEntity(spawnedDeliveryTruck, 1, 1) + SetEntityAsMissionEntity(spawnedTankerTrailer, 1, 1) + AttachVehicleToTrailer(spawnedDeliveryTruck, spawnedTankerTrailer, 15.0) + -- Now our vehicle is spawned. + if spawnedDeliveryTruck ~= 0 and spawnedTankerTrailer ~= 0 then + TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(spawnedDeliveryTruck)) + return true + else + return false + end + end + end + + -- Events RegisterNetEvent('cdn-fuel:stations:updatelocation', function(updatedlocation) - if Config.FuelDebug then if CurrentLocation == nil then CurrentLocation = 0 end print('Location: '..CurrentLocation..' has been replaced with a new location: ' ..updatedlocation) end - CurrentLocation = updatedlocation + if Config.FuelDebug then if CurrentLocation == nil then CurrentLocation = 0 end + if updatedlocation == nil then updatedlocation = 0 end + print('Location: '..CurrentLocation..' has been replaced with a new location: ' ..updatedlocation) + end + CurrentLocation = updatedlocation or 0 end) RegisterNetEvent('cdn-fuel:stations:client:buyreserves', function(data) @@ -80,6 +124,173 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if Config.FuelDebug then print("^5Attempting Purchase of ^2"..amount.. "^5 Fuel Reserves for location #"..location.."! Purchase Price: ^2"..price) end end) + RegisterNetEvent('cdn-fuel:station:client:initiatefuelpickup', function(amountBought, finalReserveAmountAfterPurchase, location) + if amountBought and finalReserveAmountAfterPurchase and location then + ReservePickupData = nil + ReservePickupData = { + finalAmount = finalReserveAmountAfterPurchase, + amountBought = amountBought, + location = location, + } + + if SpawnPickupVehicles() then + QBCore.Functions.Notify('Your fuel order is available for pickup! Take a look at your GPS to find the pickup!', 'success') + SetNewWaypoint(Config.DeliveryTruckSpawns['truck'].x, Config.DeliveryTruckSpawns['truck'].y) + SetUseWaypointAsDestination(true) + ReservePickupData.blip = CreateBlip(vector3(Config.DeliveryTruckSpawns['truck'].x, Config.DeliveryTruckSpawns['truck'].y, Config.DeliveryTruckSpawns['truck'].z), "Truck Pickup") + SetBlipColour(ReservePickupData.blip, 5) + + -- Create Zone + ReservePickupData.PolyZone = PolyZone:Create(Config.DeliveryTruckSpawns.PolyZone.coords, { + name = "cdn_fuel_zone_delivery_truck_pickup", + minZ = Config.DeliveryTruckSpawns.PolyZone.minz, + maxZ = Config.DeliveryTruckSpawns.PolyZone.maxz, + debugPoly = Config.PolyDebug + }) + + -- Setup onPlayerInOut Events for zone that is created. + ReservePickupData.PolyZone:onPlayerInOut(function(isPointInside) + if isPointInside then + if Config.FuelDebug then + print("Player has arrived at the pickup location!") + end + RemoveBlip(ReservePickupData.blip) + ReservePickupData.blip = nil + CreateThread(function() + local ped = PlayerPedId() + local alreadyHasTruck = false + local hasArrivedAtLocation = false + local VehicleDelivered = false + local EndAwaitListener = false + local stopNotifyTemp = false + local AwaitingInput = false + while true do + Wait(100) + if VehicleDelivered then break end + if IsPedInAnyVehicle(ped, false) then + if GetVehiclePedIsIn(ped, false) == spawnedDeliveryTruck then + if Config.FuelDebug then + print("Player is inside of the delivery truck!") + end + + if not alreadyHasTruck then + local loc = {} + loc.x, loc.y = Config.GasStations[ReservePickupData.location].pedcoords.x, Config.GasStations[ReservePickupData.location].pedcoords.y + SetNewWaypoint(loc.x, loc.y) + SetUseWaypointAsDestination(true) + alreadyHasTruck = true + else + if not CreatedEventHandler then + local function AwaitInput() + if AwaitingInput then return end + AwaitingInput = true + if Config.FuelDebug then print("Executing function `AwaitInput()`") end + CreateThread(function() + while true do + Wait(0) + if EndAwaitListener or not hasArrivedAtLocation then + AwaitingInput = false + break + end + if IsControlJustReleased(2, 38) then + local distBetweenTruckAndTrailer = #(GetEntityCoords(spawnedDeliveryTruck) - GetEntityCoords(spawnedTankerTrailer)) + if distBetweenTruckAndTrailer > 10.0 then + distBetweenTruckAndTrailer = nil + if not stopNotifyTemp then + QBCore.Functions.Notify('The trailer is not attached to the truck or is too far!', 'error', 7500) + end + stopNotifyTemp = true + Wait(1000) + stopNotifyTemp = false + else + EndAwaitListener = true + local ped = PlayerPedId() + VehicleDelivered = true + -- Handle Vehicle Dropoff + -- Remove PolyZone -- + ReservePickupData.PolyZone:destroy() + ReservePickupData.PolyZone = nil + -- Get Ped Out of Vehicle if Inside -- + if IsPedInAnyVehicle(ped, true) and GetVehiclePedIsIn(ped, false) == spawnedDeliveryTruck then + TaskLeaveVehicle( + ped --[[ Ped ]], + spawnedDeliveryTruck --[[ Vehicle ]], + 1 --[[ flags | integer ]] + ) + Wait(5000) + end + + if Config.Ox.DrawText then + lib.hideTextUI() + else + exports[Config.Core]:HideText() + end + + -- Remove Vehicle -- + DeleteEntity(spawnedDeliveryTruck) + DeleteEntity(spawnedTankerTrailer) + -- Send Data to Server to Put Into Station -- + TriggerServerEvent('cdn-fuel:station:server:fuelpickup:finished', ReservePickupData.location) + -- Remove Handler + RemoveEventHandler(locationSwapHandler) + AwaitingInput = false + CreatedEventHandler = false + ReservePickupData = nil + ReservePickupData = {} + -- Break Loop + break + end + end + end + end) + AwaitingInput = true + end + locationSwapHandler = AddEventHandler('cdn-fuel:stations:updatelocation', function(location) + if location == nil or location ~= ReservePickupData.location then + hasArrivedAtLocation = false + if Config.Ox.DrawText then + lib.hideTextUI() + else + exports[Config.Core]:HideText() + end + -- Break Listener + EndAwaitListener = true + Wait(50) + EndAwaitListener = false + else + hasArrivedAtLocation = true + if Config.Ox.DrawText then + lib.showTextUI("[E] Drop Off Truck", { + position = 'left-center' + }) + else + exports[Config.Core]:DrawText("[E] Drop Off Truck", 'left') + end + -- Add Listner for Keypress + AwaitInput() + end + end) + end + end + end + end + end + end) + else + + end + end) + else + -- This is just a worst case scenario event, if the vehicles somehow do not spawn. + TriggerServerEvent('cdn-fuel:station:server:fuelpickup:failed', location) + end + else + if Config.FuelDebug then + print("An error has occurred. The amountBought / finalReserveAmountAfterPurchase / location is nil: `cdn-fuel:station:client:initiatefuelpickup`") + end + end + end) + RegisterNetEvent('cdn-fuel:stations:client:purchaselocation', function(data) local location = data.location local CitizenID = QBCore.Functions.GetPlayerData().citizenid @@ -98,7 +309,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if not IsOwned then TriggerServerEvent('cdn-fuel:server:buyStation', location, CitizenID) - elseif IsOwned then + elseif IsOwned then QBCore.Functions.Notify(Lang:t("station_already_owned"), 'error', 7500) end end) @@ -163,8 +374,8 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat event = 'cdn-fuel:stations:client:buyreserves', args = { location = location, - price = price, - amount = amount, + price = price, + amount = amount, } }, { @@ -188,20 +399,20 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat }, { header = Lang:t("menu_station_reserves_purchase_header")..price, - txt = Lang:t("menu_station_reserves_purchase_footer")..price.."!", + txt = Lang:t("menu_station_reserves_purchase_footer")..price.."!", icon = "fas fa-usd", params = { event = "cdn-fuel:stations:client:buyreserves", args = { location = location, - price = price, - amount = amount, + price = price, + amount = amount, }, }, }, { header = Lang:t("menu_header_close"), - txt = Lang:t("menu_station_reserves_cancel_footer"), + txt = Lang:t("menu_station_reserves_cancel_footer"), icon = "fas fa-times-circle", params = { event = "qb-menu:closeMenu", @@ -215,7 +426,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat end) RegisterNetEvent('cdn-fuel:stations:client:purchasereserves', function(data) - CanOpen = false + local CanOpen = false local location = data.location QBCore.Functions.TriggerCallback('cdn-fuel:server:isowner', function(result) local CitizenID = QBCore.Functions.GetPlayerData().citizenid @@ -243,9 +454,9 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat { type = "input", label = 'Required Reserves', default = Config.MaxFuelReserves - Currentreserveamount, disabled = true }, - { type = "slider", label = 'Full Reserve Cost: $' ..GlobalTax((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice) + ((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice).. '', - default = Config.MaxFuelReserves - Currentreserveamount, - min = 0, + { type = "slider", label = 'Full Reserve Cost: $' ..math.ceil(GlobalTax((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice) + ((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice)).. '', + default = Config.MaxFuelReserves - Currentreserveamount, + min = 0, max = Config.MaxFuelReserves - Currentreserveamount }, }) @@ -261,20 +472,20 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if (Reservebuyamount + Currentreserveamount) > Config.MaxFuelReserves then QBCore.Functions.Notify(Lang:t("station_reserve_cannot_fit"), "error") else - if GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice) <= bankmoney then - local price = GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice) + if math.ceil(GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice)) <= bankmoney then + local price = math.ceil(GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice)) if Config.FuelDebug then print("Price: "..price) end TriggerEvent("cdn-fuel:stations:client:purchasereserves:final", location, price, amount) - + else QBCore.Functions.Notify(Lang:t("not_enough_money_in_bank"), 'error', 7500) end - end + end end else local reserves = exports['qb-input']:ShowInput({ header = Lang:t("input_purchase_reserves_header_1") .. Lang:t("input_purchase_reserves_header_2") .. Currentreserveamount .. Lang:t("input_purchase_reserves_header_3") .. - GlobalTax((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice) + ((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice) .. "", + math.ceil(GlobalTax((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice) + ((Config.MaxFuelReserves - Currentreserveamount) * Config.FuelReservesPrice)) .. "", submitText = Lang:t("input_purchase_reserves_submit_text"), inputs = { { type = 'number', @@ -293,21 +504,21 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if (Reservebuyamount + Currentreserveamount) > Config.MaxFuelReserves then QBCore.Functions.Notify(Lang:t("station_reserve_cannot_fit"), "error") else - if GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice) <= bankmoney then - local price = GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice) + if math.ceil(GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice)) <= bankmoney then + local price = math.ceil(GlobalTax(Reservebuyamount * Config.FuelReservesPrice) + (Reservebuyamount * Config.FuelReservesPrice)) if Config.FuelDebug then print("Price: "..price) end TriggerEvent("cdn-fuel:stations:client:purchasereserves:final", location, price, amount) - + else QBCore.Functions.Notify(Lang:t("not_enough_money_in_bank"), 'error', 7500) end - end + end end end end end) - RegisterNetEvent('cdn-fuel:stations:client:changefuelprice', function(data) + RegisterNetEvent('cdn-fuel:stations:client:changefuelprice', function(data) CanOpen = false local location = data.location QBCore.Functions.TriggerCallback('cdn-fuel:server:isowner', function(result) @@ -330,8 +541,8 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat default = '$'.. Comma_Value(StationFuelPrice) .. ' Per Liter', disabled = true }, { type = "number", label = 'Enter New Fuel Price Per Liter', - default = StationFuelPrice, - min = Config.MinimumFuelPrice, + default = StationFuelPrice, + min = Config.MinimumFuelPrice, max = Config.MaxFuelPrice }, }) @@ -347,7 +558,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_price_too_high"), "error") else TriggerServerEvent("cdn-fuel:station:server:updatefuelprice", NewFuelPrice, CurrentLocation) - end + end end else local fuelprice = exports['qb-input']:ShowInput({ @@ -370,7 +581,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_price_too_high"), "error") else TriggerServerEvent("cdn-fuel:station:server:updatefuelprice", NewFuelPrice, CurrentLocation) - end + end end end end @@ -431,7 +642,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat }, { header = Lang:t("menu_sell_station_header_accept"), - txt = Lang:t("menu_sell_station_footer_accept")..SalePrice..".", + txt = Lang:t("menu_sell_station_footer_accept")..SalePrice..".", icon = "fas fa-usd", params = { event = "cdn-fuel:stations:client:sellstation", @@ -443,7 +654,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat }, { header = Lang:t("menu_header_close"), - txt = Lang:t("menu_sell_station_footer_close"), + txt = Lang:t("menu_sell_station_footer_close"), icon = "fas fa-times-circle", params = { event = "qb-menu:closeMenu", @@ -487,14 +698,14 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if not NewNameName then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) return end NewName = NewNameName if type(NewName) ~= "string" then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error') return end - if Config.ProfanityList[NewName] then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) + if Config.ProfanityList[NewName] then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) -- You can add logs for people that put prohibited words into the name changer if wanted, and here is where you would do it. - return + return end if string.len(NewName) > Config.NameChangeMaxChar then QBCore.Functions.Notify(Lang:t("station_name_too_long"), 'error') return end if string.len(NewName) < Config.NameChangeMinChar then QBCore.Functions.Notify(Lang:t("station_name_too_short"), 'error') return end Wait(100) - TriggerServerEvent("cdn-fuel:station:server:updatelocationname", NewName, CurrentLocation) + TriggerServerEvent("cdn-fuel:station:server:updatelocationname", NewName, CurrentLocation) end else local NewName = exports['qb-input']:ShowInput({ @@ -512,14 +723,14 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if not NewName.newname then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) return end NewName = NewName.newname if type(NewName) ~= "string" then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error') return end - if Config.ProfanityList[NewName] then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) + if Config.ProfanityList[NewName] then QBCore.Functions.Notify(Lang:t("station_name_invalid"), 'error', 7500) -- You can add logs for people that put prohibited words into the name changer if wanted, and here is where you would do it. - return + return end if string.len(NewName) > Config.NameChangeMaxChar then QBCore.Functions.Notify(Lang:t("station_name_too_long"), 'error') return end if string.len(NewName) < Config.NameChangeMinChar then QBCore.Functions.Notify(Lang:t("station_name_too_short"), 'error') return end Wait(100) - TriggerServerEvent("cdn-fuel:station:server:updatelocationname", NewName, CurrentLocation) + TriggerServerEvent("cdn-fuel:station:server:updatelocationname", NewName, CurrentLocation) end end end @@ -556,7 +767,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = true, -- puts arrow to the right event = 'cdn-fuel:stations:client:purchasereserves', args = { - location = location, + location = location, }, metadata = { {label = 'Reserve Stock: ', value = ReserveLevels..Lang:t("menu_manage_reserves_footer_1")..Config.MaxFuelReserves}, @@ -570,7 +781,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:changefuelprice', args = { - location = location, + location = location, }, metadata = { {label = 'Current Fuel Price: ', value = "$"..Comma_Value(StationFuelPrice)..Lang:t("input_alter_fuel_price_header_2")}, @@ -599,7 +810,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:sellstation:menu', args = { - location = location, + location = location, }, }, { @@ -634,7 +845,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat params = { event = "cdn-fuel:stations:client:purchasereserves", args = { - location = location, + location = location, } }, disabled = ReservesNotBuyable, @@ -646,7 +857,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat params = { event = "cdn-fuel:stations:client:changefuelprice", args = { - location = location, + location = location, } }, disabled = CanNotChangeFuelPrice, @@ -670,18 +881,18 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat }, { header = Lang:t("menu_sell_station_header_accept"), - txt = Lang:t("menu_manage_sell_station_footer")..math.percent(Config.GasStationSellPercentage, GasStationCost), + txt = Lang:t("menu_manage_sell_station_footer")..math.percent(Config.GasStationSellPercentage, GasStationCost), icon = "fas fa-usd", params = { event = "cdn-fuel:stations:client:sellstation:menu", args = { - location = location, + location = location, } }, }, { header = Lang:t("menu_header_close"), - txt = Lang:t("menu_manage_close"), + txt = Lang:t("menu_manage_close"), icon = "fas fa-times-circle", params = { event = "qb-menu:closeMenu", @@ -721,7 +932,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:WithdrawFunds', args = { - location = location, + location = location, } }, { @@ -731,7 +942,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:DepositFunds', args = { - location = location, + location = location, } }, { @@ -741,7 +952,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:managemenu', args = { - location = location, + location = location, } }, { @@ -770,7 +981,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat params = { event = "cdn-fuel:stations:client:WithdrawFunds", args = { - location = location, + location = location, } }, }, @@ -781,18 +992,18 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat params = { event = "cdn-fuel:stations:client:DepositFunds", args = { - location = location, + location = location, } }, }, { header = Lang:t("menu_manage_company_funds_return_header"), - txt = Lang:t("menu_manage_company_funds_return_footer"), + txt = Lang:t("menu_manage_company_funds_return_footer"), icon = "fas fa-circle-left", params = { event = "cdn-fuel:stations:client:managemenu", args = { - location = location, + location = location, } }, }, @@ -843,7 +1054,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_withdraw_too_much"), 'error', 7500) else TriggerServerEvent('cdn-fuel:station:server:Withdraw', amount, location, StationBalance) - end + end end else local Withdraw = exports['qb-input']:ShowInput({ @@ -868,7 +1079,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_withdraw_too_much"), 'error', 7500) else TriggerServerEvent('cdn-fuel:station:server:Withdraw', amount, location, StationBalance) - end + end end end end @@ -916,7 +1127,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_deposity_too_much"), "error") else TriggerServerEvent('cdn-fuel:station:server:Deposit', amount, location, StationBalance) - end + end end else local Deposit = exports['qb-input']:ShowInput({ @@ -940,7 +1151,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat QBCore.Functions.Notify(Lang:t("station_deposity_too_much"), "error") else TriggerServerEvent('cdn-fuel:station:server:Deposit', amount, location, StationBalance) - end + end end end end @@ -964,7 +1175,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat PlayerOwnsAStation = false end end) - + Wait(Config.WaitTime) if PlayerOwnsAStation == true then @@ -990,7 +1201,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat arrow = true, -- puts arrow to the right event = 'cdn-fuel:stations:client:purchaselocation', args = { - location = location, + location = location, }, metadata = { {label = 'Station Cost: $', value = Comma_Value(costofstation)..Lang:t("menu_purchase_station_header_2")}, @@ -1028,13 +1239,13 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat params = { event = "cdn-fuel:stations:client:purchaselocation", args = { - location = location, + location = location, } } }, { header = Lang:t("menu_header_close"), - txt = Lang:t("menu_purchase_station_cancel_footer"), + txt = Lang:t("menu_purchase_station_cancel_footer"), icon = "fas fa-times-circle", params = { event = "qb-menu:closeMenu", @@ -1098,7 +1309,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat { title = Lang:t("menu_ped_manage_location_header"), description = Lang:t("menu_ped_manage_location_footer"), - icon = "fas fa-gas-pump", + icon = "fas fa-gas-pump", arrow = false, -- puts arrow to the right event = 'cdn-fuel:stations:client:managemenu', args = CurrentLocation, @@ -1139,7 +1350,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat { header = Config.GasStations[CurrentLocation].label, isMenuHeader = true, - icon = "fas fa-gas-pump", + icon = "fas fa-gas-pump", }, { header = Lang:t("menu_ped_manage_location_header"), diff --git a/server/station_sv.lua b/server/station_sv.lua index 746c1c1..17c16ec 100644 --- a/server/station_sv.lua +++ b/server/station_sv.lua @@ -2,7 +2,8 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat -- Variables local QBCore = exports[Config.Core]:GetCoreObject() - + local FuelPickupSent = {} -- This is in case of an issue with vehicles not spawning when picking up vehicles. + -- Functions local function GlobalTax(value) local tax = (value / 100 * Config.GlobalTax) @@ -58,7 +59,6 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if Player.Functions.RemoveMoney("bank", CostOfStation, Lang:t("station_purchased_location_payment_label")..Config.GasStations[location].label) then MySQL.Async.execute('UPDATE fuel_stations SET owned = ? WHERE `location` = ?', {1, location}) MySQL.Async.execute('UPDATE fuel_stations SET owner = ? WHERE `location` = ?', {CitizenID, location}) - if Config.NPWD then TriggerClientEvent('cdn-fuel:client:buysellStationNPWDNotif', src, "buy", comma_value(CostOfStation), Config.GasStations[location].label) end end end) @@ -71,7 +71,7 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat MySQL.Async.execute('UPDATE fuel_stations SET owned = ? WHERE `location` = ?', {0, location}) MySQL.Async.execute('UPDATE fuel_stations SET owner = ? WHERE `location` = ?', {0, location}) TriggerClientEvent('QBCore:Notify', src, Lang:t("station_sold_success"), 'success') - if Config.NPWD then TriggerClientEvent('cdn-fuel:client:buysellStationNPWDNotif', src, "sell", comma_value(SalePrice), Config.GasStations[location].label) end + else TriggerClientEvent('QBCore:Notify', src, Lang:t("station_cannot_sell"), 'error') end @@ -86,7 +86,6 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat MySQL.Async.execute('UPDATE fuel_stations SET balance = ? WHERE `location` = ?', {setamount, location}) Player.Functions.AddMoney("bank", amount, Lang:t("station_withdraw_payment_label")..Config.GasStations[location].label) TriggerClientEvent('QBCore:Notify', src, Lang:t("station_success_withdrew_1")..amount..Lang:t("station_success_withdrew_2"), 'success') - if Config.NPWD then TriggerClientEvent('cdn-fuel:client:StationTransfersNPWDNotif', src, "deposit", comma_value(setamount), Config.GasStations[location].label) end end) RegisterNetEvent('cdn-fuel:station:server:Deposit', function(amount, location, StationBalance) @@ -97,7 +96,6 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if Player.Functions.RemoveMoney("bank", amount, Lang:t("station_deposit_payment_label")..Config.GasStations[location].label) then MySQL.Async.execute('UPDATE fuel_stations SET balance = ? WHERE `location` = ?', {setamount, location}) TriggerClientEvent('QBCore:Notify', src, Lang:t("station_success_deposit_1")..amount..Lang:t("station_success_deposit_2"), 'success') - if Config.NPWD then TriggerClientEvent('cdn-fuel:client:StationTransfersNPWDNotif', src, "deposit", comma_value(setamount), Config.GasStations[location].label) end else TriggerClientEvent('QBCore:Notify', src, Lang:t("station_cannot_afford_deposit")..amount.."!", 'success') end @@ -149,9 +147,10 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat if Config.FuelDebug then print('Successfully executed the previous SQL Update!') end end) + RegisterNetEvent('cdn-fuel:stations:server:buyreserves', function(location, price, amount) local location = location - local price = price + local price = math.ceil(price) local amount = amount local src = source local Player = QBCore.Functions.GetPlayer(src) @@ -179,13 +178,64 @@ if Config.PlayerOwnedGasStationsEnabled then -- This is so Player Owned Gas Stat end if Config.FuelDebug then print("Attempting Sale Server Side for location: #"..location.." for Price: $"..price) end if ReserveBuyPossible and Player.Functions.RemoveMoney("bank", price, "Purchased"..amount.."L of Reserves for: "..Config.GasStations[location].label.." @ $"..Config.FuelReservesPrice.." / L!") then - MySQL.Async.execute('UPDATE fuel_stations SET fuel = ? WHERE `location` = ?', {NewAmount, location}) - if Config.FuelDebug then print("SQL Execute Update: fuel_station level to: "..NewAmount.. " Math: ("..amount.." + "..OldAmount.." = "..NewAmount) end + if not Config.OwnersPickupFuel then + MySQL.Async.execute('UPDATE fuel_stations SET fuel = ? WHERE `location` = ?', {NewAmount, location}) + if Config.FuelDebug then print("SQL Execute Update: fuel_station level to: "..NewAmount.. " Math: ("..amount.." + "..OldAmount.." = "..NewAmount) end + else + FuelPickupSent[location] = { + ['src'] = src, + ['refuelAmount'] = NewAmount, + ['amountBought'] = amount, + } + TriggerClientEvent('cdn-fuel:station:client:initiatefuelpickup', src, amount, NewAmount, location) + if Config.FuelDebug then print("Initiating a Fuel Pickup for Location: "..location.." with for the amount of "..NewAmount.." | Triggered By: Source: "..src) end + end + elseif ReserveBuyPossible then TriggerClientEvent('QBCore:Notify', src, Lang:t("not_enough_money"), 'error') end end) + RegisterNetEvent('cdn-fuel:station:server:fuelpickup:failed', function(location) + local src = source + if location then + if FuelPickupSent[location] then + local cid = QBCore.Functions.GetPlayer(src).PlayerData.citizenid + MySQL.Async.execute('UPDATE fuel_stations SET fuel = ? WHERE `location` = ?', {FuelPickupSent[location]['refuelAmount'], location}) + TriggerClientEvent('QBCore:Notify', src, "Ron Oil has just dropped off the fuel to your station!", 'success') + -- This will print player information just in case someone figures out a way to exploit this. + print("User encountered an error with fuel pickup, so we are updating the fuel level anyways, and cancelling the pickup. SQL Execute Update: fuel_station level to: "..FuelPickupSent[location].refuelAmount.. " | Source: "..src.." | Citizen Id: "..cid..".") + FuelPickupSent[location] = nil + else + if Config.FuelDebug then + print("`cdn-fuel:station:server:fuelpickup:failed` | FuelPickupSent[location] is not valid! Location: "..location) + end + -- They are probably exploiting in some way/shape/form. + end + end + end) + + RegisterNetEvent('cdn-fuel:station:server:fuelpickup:finished', function(location) + local src = source + if location then + if FuelPickupSent[location] then + local cid = QBCore.Functions.GetPlayer(src).PlayerData.citizenid + MySQL.Async.execute('UPDATE fuel_stations SET fuel = ? WHERE `location` = ?', {FuelPickupSent[location].refuelAmount, location}) + TriggerClientEvent('QBCore:Notify', src, 'Your reserves have been filled to: '..tostring(tonumber(FuelPickupSent[location].refuelAmount)).."L", 'success') + -- This will print player information just in case someone figures out a way to exploit this. + if Config.FuelDebug then + print("User successfully dropped off fuel truck, so we are updating the fuel level and clearing the pickup table. SQL Execute Update: fuel_station level to: "..FuelPickupSent[location].refuelAmount.. " | Source: "..src.." | Citizen Id: "..cid..".") + end + FuelPickupSent[location] = nil + else + if Config.FuelDebug then + print("FuelPickupSent[location] is not valid! Location: "..location) + end + -- They are probably exploiting in some way/shape/form. + end + end + end) + RegisterNetEvent('cdn-fuel:station:server:updatelocationname', function(newName, location) local src = source if Config.FuelDebug then print('Attempting to set name for Location #'..location..' to: '..newName) end