24/7 SHOP
+ + Altid åbent, fordi du sover vel aldrig? + +
-
+
+ + Indkøbskurv +
++
" + itemData.label + "
"); + $(".item-info-description").html("Gal: " + itemData.info.gal + "
" + "Type: " + itemData.info.type + "
" + "Octane: " + itemData.info.avg_gas_octane + "
"); +} +``` + +# Support + +- [Discord](https://discord.gg/ccMArCwrPV) + +# Donation + +- [Donation](https://swkeep.github.io) + + + + + + + + + + diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client.lua new file mode 100644 index 0000000..830d74f --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client.lua @@ -0,0 +1,407 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +PlayerJob = {} +OnDuty = nil +OBJECT = nil +local rigmodel = GetHashKey('p_oil_pjack_03_s') + +function CheckJob() + return (PlayerJob.name == 'oilwell') +end + +function CheckOnduty() + return (PlayerJob.name == 'oilwell' and PlayerJob.onduty) +end + +-- class +OilRigs = { + dynamicSpawner_state = false, + data_table = {}, -- this table holds oilwells data and defined by server + core_entities = {} -- this table holds objects that has some functions to them and filled by dynamic spawner +} + +function OilRigs:add(s_res, id) + if self.data_table[id] ~= nil then + return + end + self.data_table[id] = {} + self.data_table[id] = s_res + if self.data_table[id].isOwner == true then + local blip_settings = Oilwell_config.Settings.oil_well.blip + blip_settings.type = 'oil_well' + blip_settings.id = id + self.data_table[id].blip_handle = createCustom(self.data_table[id].position.coord, blip_settings) + end +end + +function OilRigs:update(s_res, id) + if self.data_table[id] == nil then return end + s_res.entity = self.data_table[id].entity + s_res.Qbtarget = self.data_table[id].Qbtarget + self.data_table[id] = s_res + QBCore.Functions.TriggerCallback('keep-oilwell:server:oilwell_metadata', function(metadata) + self:syncSpeed(self.data_table[id].entity, metadata.speed) + end, self.data_table[id].oilrig_hash) +end + +function OilRigs:startUpdate(cb) + QBCore.Functions.TriggerCallback('keep-oilrig:server:getNetIDs', function(result) + for key, value in pairs(result) do + self:update(value, key) + Wait(15) + end + cb(true) + end) +end + +function OilRigs:syncSpeed(entity, speed) + local anim_speed = Round((speed / Oilwell_config.AnimationSpeedDivider), 2) + SetEntityAnimSpeed(entity, 'p_v_lev_des_skin', 'p_oil_pjack_03_s', anim_speed + .0) +end + +function OilRigs:getById(id) + for key, value in pairs(self.data_table) do + if value.id == id then + return value + end + end + return false +end + +function OilRigs:getByEntityHandle(handle) + for key, value in pairs(self.data_table) do + if value.entity == handle then + return value + end + end + return false +end + +function OilRigs:readAll() + return self.data_table +end + +function OilRigs:DynamicSpawner() + self.dynamicSpawner_state = true + local object_spawn_distance = 125.0 + + CreateThread(function() + -- create core blips + Wait(50) + for index, value in pairs(Oilwell_config.locations) do + value.blip.type = index + if not value.blip.handle and PlayerJob.name == 'oilwell' then + value.blip.handle = createCustom(value.position, value.blip) + end + if not value.qbtarget then + Add_3rd_eye(value.position, index) + value.qbtarget = true + end + end + + for _, oilwell in pairs(self.data_table) do + if not oilwell.qbtarget then + local c = oilwell.position.coord + local coord = vector3(c.x, c.y, c.z) + createOwnerQbTarget(oilwell.oilrig_hash, coord) + oilwell.qbtarget = true + end + end + + while self.dynamicSpawner_state do + local pedCoord = GetEntityCoords(PlayerPedId()) + -- oilwells/pumps + for index, value in pairs(self.data_table) do + local c = value.position.coord + c = vector3(c.x, c.y, c.z) + local distance = #(c - pedCoord) + if distance < object_spawn_distance and self.data_table[index].entity == nil then + self.data_table[index].entity = spawnObjects(rigmodel, self.data_table[index].position) + QBCore.Functions.TriggerCallback('keep-oilwell:server:oilwell_metadata', function(metadata) + self:syncSpeed(self.data_table[index].entity, metadata.speed) + end, self.data_table[index].oilrig_hash) + elseif distance > object_spawn_distance and self.data_table[index].entity ~= nil then + DeleteEntity(self.data_table[index].entity) + self.data_table[index].entity = nil + end + end + + for index, value in pairs(Oilwell_config.locations) do + local position = vector3(value.position.x, value.position.y, value.position.z) + local distance = #(position - pedCoord) + if self.core_entities[index] == nil then + self.core_entities[index] = {} + end + if distance < object_spawn_distance and self.core_entities[index].entity == nil then + self.core_entities[index].entity = spawnObjects(value.model, { + coord = { x = position.x, y = position.y, z = position.z, }, + rotation = { x = value.rotation.x, y = value.rotation.y, z = value.rotation.z, } + }) + elseif distance > object_spawn_distance and self.core_entities[index].entity ~= nil then + DeleteEntity(self.core_entities[index].entity) + self.core_entities[index].entity = nil + end + end + Wait(1250) + end + end) +end + +function OilRigs:Flush_Entities() + for _, oilwell in pairs(self.data_table) do + if oilwell.entity then + DeleteObject(oilwell.entity) + end + RemoveBlip(oilwell.blip_handle) + end + self.dynamicSpawner_state = false + Wait(5) + self.data_table = {} +end + +-- +RegisterNetEvent('keep-oilrig:client:changeRigSpeed', function(qbtarget) + if not CheckJob() then + QBCore.Functions.Notify('Du er ikke hyret af et oliefirma', "error") + return false + end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + return false + end + local rig = OilRigs:getByEntityHandle(qbtarget.entity) + if not rig then + return --print('oilwell not found') + end + QBCore.Functions.TriggerCallback('keep-oilwell:server:oilwell_metadata', function(metadata) + OilRigs:startUpdate(function() + + local inputData = exports['qb-input']:ShowInput({ + header = "Skift hastighed", + submitText = "change", + inputs = { + { + type = 'text', + isRequired = true, + name = 'Hastighed', + text = 'Nuværrende hastighed ' .. metadata.speed + }, + } + }) + if inputData then + local speed = tonumber(inputData.speed) + if not inputData.speed then + return + end + if not (0 <= speed and speed <= 100) then + QBCore.Functions.Notify('Hastighed skal være mellem 0-100', "error") + return + end + QBCore.Functions.Notify('Hanstighed er nu ' .. speed, "success") + TriggerServerEvent('keep-oilrig:server:updateSpeed', inputData, rig.id) + end + end) + end, rig.oilrig_hash) +end) + +local function loadData() + OilRigs:Flush_Entities() + QBCore.Functions.GetPlayerData(function(PlayerData) + PlayerJob = PlayerData.job + OnDuty = PlayerData.job.onduty + QBCore.Functions.TriggerCallback('keep-oilrig:server:getNetIDs', function(result) + for key, value in pairs(result) do + OilRigs:add(value, key) + end + + OilRigs:DynamicSpawner() + end) + end) +end + +RegisterNetEvent('keep-oilrig:client:syncSpeed', function(id, speed) + local rig = OilRigs:getById(id) + if rig then + OilRigs:syncSpeed(rig.entity, speed) + end +end) + +function spawnObjects(model, position) + TriggerEvent('keep-oilrig:client:clearArea', position.coord) + -- every oilwell exist only on client side! + local entity = CreateObject(model, position.coord.x, position.coord.y, position.coord.z, 0, 0, 0) + while not DoesEntityExist(entity) do Wait(10) end + SetEntityRotation(entity, position.rotation.x, position.rotation.y, position.rotation.z, 0.0, true) + FreezeEntityPosition(entity, true) + SetEntityProofs(entity, 1, 1, 1, 1, 1, 1, 1, 1) + return entity +end + +-- -------------------------------------------------------------- + +RegisterNetEvent('keep-oilrig:client:spawn') +AddEventHandler('keep-oilrig:client:spawn', function() + local coords = ChooseSpawnLocation() + QBCore.Functions.TriggerCallback('keep-oilrig:server:createNewOilrig', function(NetId) + if NetId ~= nil then + local entity = NetworkGetEntityFromNetworkId(NetId) + OBJECT = entity + exports['qb-target']:AddEntityZone("oil-rig-" .. entity, entity, { + name = "oil-rig-" .. entity, + heading = GetEntityHeading(entity), + debugPoly = false, + }, { + options = { + { + type = "client", + event = "keep-oilrig:client:enterInformation", + icon = "fa-regular fa-file-lines", + label = "Tildel personel", + canInteract = function(entity) + if not CheckJob() then return false end + if not (PlayerJob.grade.level == 4) then + TriggerEvent('QBCore:Notify', 'Du skal være på job!', "error") + Wait(2000) + return false + end + if not CheckOnduty() then + TriggerEvent('QBCore:Notify', 'Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + { + type = "client", + event = "keep-oilwell:menu:OPENMENU", + icon = "fa-regular fa-file-lines", + label = "Adjust position", + canInteract = function(entity) + if not CheckJob() then + TriggerEvent('QBCore:Notify', 'Kun chefen kan dette', "error") + Wait(2000) + return false + end + if not (PlayerJob.grade.level == 4) then + TriggerEvent('QBCore:Notify', 'Kun chefen kan dette', "error") + Wait(2000) + return false + end + if not CheckOnduty() then + TriggerEvent('QBCore:Notify', 'Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 2.5 + }) + end + end, coords) +end) + + +RegisterNetEvent('keep-oilrig:client:enterInformation', function(qbtarget) + local inputData = exports['qb-input']:ShowInput({ + header = "Tildel oliebrønd: ", + submitText = "Tildel", + inputs = { { + type = 'text', + isRequired = true, + name = 'Navn', + text = "Navn på oliebrønd" + }, + { + type = 'number', + isRequired = true, + name = 'BorgerID', + text = "Borgerens ID" + }, + } + }) + if inputData then + if not inputData.name and not inputData.cid then + return + end + local netId = NetworkGetNetworkIdFromEntity(qbtarget.entity) + + inputData.netId = netId + QBCore.Functions.TriggerCallback('keep-oilrig:server:regiserOilrig', function(result) + DeleteEntity(qbtarget.entity) + if result == true then + Wait(1500) + QBCore.Functions.Notify('Registrerer oliebrønd til: ' .. inputData.cid, "success") + loadData() + end + end, inputData) + end +end) + +RegisterNetEvent('keep-oilwell:client:force_reload', function() + Wait(25) + loadData() +end) + +AddEventHandler('onResourceStart', function(resourceName) + if (GetCurrentResourceName() ~= resourceName) then + return + end + Wait(500) + + QBCore.Functions.GetPlayerData(function(PlayerData) + PlayerJob = PlayerData.job + OnDuty = PlayerData.job.onduty + loadData() + end) + StartBarellAnimation() +end) + +RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() + Wait(3000) + QBCore.Functions.GetPlayerData(function(PlayerData) + PlayerJob = PlayerData.job + OnDuty = PlayerData.job.onduty + loadData() + end) + StartBarellAnimation() +end) + +RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() + OilRigs.dynamicSpawner_state = false +end) + +RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo) + PlayerJob = JobInfo + OnDuty = PlayerJob.onduty + loadData() +end) + +RegisterNetEvent('QBCore:Client:SetDuty', function(duty) + OnDuty = duty + loadData() +end) + +RegisterNetEvent('keep-oilrig:client:local_mail_sender', function(data) + local Lang = Oilwell_config.Locale + Lang.mail.message = string.format(Lang.mail.message, data.gender, data.charinfo.lastname, data.money, data.amount, + data.refund) + TriggerServerEvent('qb-phone:server:sendNewMail', { + sender = Lang.mail.sender, + subject = Lang.mail.subject, + message = Lang.mail.message, + button = {} + }) +end) + +RegisterNetEvent('keep-oilwell:server_lib:AddExplosion', function(bullding_type) + local c = Oilwell_config.locations[bullding_type].position + local t = 0 + for i = 1, 5, 1 do + AddExplosion(c.x, c.y, c.z + 0.5, 9, 10.0, true, false, true) + t = t + 1000 + Wait(t) + end +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/client_lib_entry.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/client_lib_entry.lua new file mode 100644 index 0000000..4db940d --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/client_lib_entry.lua @@ -0,0 +1,203 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +function isOwner(entity) + local oilrig = OilRigs:getByEntityHandle(entity) + if not oilrig then + return --print('failed to get oilwell') + end + local is_employee = nil + local is_owner = nil + -- await didn't work! + QBCore.Functions.TriggerCallback('keep-oilwell:server:is_employee', function(_is_employee, _is_owner) + is_employee, is_owner = _is_employee, _is_owner + end, oilrig.oilrig_hash) + for i = 1, 5, 1 do + if is_employee ~= nil then + break + end + Wait(50) + end + return is_employee, is_owner +end + +local function Draw2DText(content, font, colour, scale, x, y) + SetTextFont(font) + SetTextScale(scale, scale) + SetTextColour(colour[1], colour[2], colour[3], 255) + SetTextEntry("STRING") + SetTextDropShadow(0, 0, 0, 0, 255) + SetTextDropShadow() + SetTextEdge(4, 0, 0, 0, 255) + SetTextOutline() + AddTextComponentString(content) + DrawText(x, y) +end + +local function RotationToDirection(rotation) + local adjustedRotation = { + x = (math.pi / 180) * rotation.x, + y = (math.pi / 180) * rotation.y, + z = (math.pi / 180) * rotation.z + } + local direction = { + x = -math.sin(adjustedRotation.z) * + math.abs(math.cos(adjustedRotation.x)), + y = math.cos(adjustedRotation.z) * + math.abs(math.cos(adjustedRotation.x)), + z = math.sin(adjustedRotation.x) + } + return direction +end + +local function RayCastGamePlayCamera(distance) + local cameraRotation = GetGameplayCamRot() + local cameraCoord = GetGameplayCamCoord() + local direction = RotationToDirection(cameraRotation) + local destination = { + x = cameraCoord.x + direction.x * distance, + y = cameraCoord.y + direction.y * distance, + z = cameraCoord.z + direction.z * distance + } + local a, b, c, d, e = GetShapeTestResult( + StartShapeTestRay(cameraCoord.x, cameraCoord.y, + cameraCoord.z, destination.x, + destination.y, destination.z, + -1, PlayerPedId(), 0)) + return c, e +end + +function ChooseSpawnLocation() + local plyped = PlayerPedId() + local pedCoord = GetEntityCoords(plyped) + local activeLaser = true + local oilrig = CreateObject(GetHashKey('p_oil_pjack_03_s'), pedCoord.x, pedCoord.y, pedCoord.z, 1, 1, 0) + SetEntityAlpha(oilrig, 150, true) + + while activeLaser do + Wait(0) + local color = { + r = 2, + g = 241, + b = 181, + a = 200 + } + local position = GetEntityCoords(plyped) + local coords, entity = RayCastGamePlayCamera(1000.0) + Draw2DText('Tryk ~g~E~w~ for at placere oliebrønd', 4, { 255, 255, 255 }, 0.4, 0.43, + 0.888 + 0.025) + if IsControlJustReleased(0, 38) then + activeLaser = false + DeleteEntity(oilrig) + return coords + end + DrawLine(position.x, position.y, position.z, coords.x, coords.y, + coords.z, color.r, color.g, color.b, color.a) + SetEntityCollision(oilrig, false, false) + SetEntityCoords(oilrig, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0) + end +end + +function createCustom(coord, o) + local blip = AddBlipForCoord( + coord.x, + coord.y, + coord.z + ) + SetBlipSprite(blip, o.sprite) + SetBlipColour(blip, o.colour) + if o.range == 'short' then + SetBlipAsShortRange(blip, true) + else + SetBlipAsShortRange(blip, false) + end + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(replaceString(o)) + EndTextCommandSetBlipName(blip) + return blip +end + +function replaceString(o) + local s = o.name + if o.id ~= nil then + -- oilwells + local oilrig = OilRigs:getById(o.id) + s = s:gsub("OILWELLNAME", oilrig.name) + s = s:gsub("OILWELL_HASH", oilrig.oilrig_hash) + s = s:gsub("DB_ID_RAW", o.id) + s = s:gsub("TYPE", o.type) + + else + s = s:gsub("TYPE", o.type) + end + return s +end + +function createOwnerQbTarget(hash, coord) + exports['qb-target']:RemoveZone("oil-rig-" .. hash) + Targets.qb_target.oilwell(coord, hash) +end + +RegisterNetEvent('keep-oilwell:client:remove_oilwell', function(data) + local oilwell = OilRigs:getByEntityHandle(data.entity) + for i = 1, 3, 1 do + local value = RandomHash(4) + local inputData = exports['qb-input']:ShowInput({ + header = 'Gentag: ' .. value .. '', + inputs = { + { + type = 'text', + isRequired = true, + name = 'Gentag', + text = '' + }, + } + }) + if not inputData then + QBCore.Functions.Notify('Annulleret', "primary") + return + end + if inputData.RandomHash ~= value then + QBCore.Functions.Notify('Fejlede', "primary") + return + end + end + TriggerServerEvent('keep-oilwell:server:remove_oilwell', oilwell.oilrig_hash) +end) + +function Add_3rd_eye(coord, Type) + local key = Type + if key == 'storage' then + Targets.qb_target.storage(coord, key) + elseif key == 'distillation' then + Targets.qb_target.distillation(coord, key) + elseif key == 'blender' then + Targets.qb_target.blender(coord, key) + elseif key == 'barrel_withdraw' then + Targets.qb_target.barrel_withdraw(coord, key) + elseif key == 'crude_oil_transport' then + Targets.qb_target.crude_oil_transport(coord, key) + elseif key == 'toggle_job' then + Targets.qb_target.toggle_job(coord, key) + end +end + +---force remove objects in area +---@param coord table +RegisterNetEvent('keep-oilrig:client:clearArea', function(coord) + ClearAreaOfObjects(coord.x, coord.y, coord.z, 5.0, 1) +end) + +RegisterNetEvent('QBCore:Client:OnJobUpdate', function(PlayerJob) + if CheckJob() then + OnDuty = CheckOnduty() + end +end) + +RegisterNetEvent('keep-oilrig:client:goOnDuty', function(PlayerJob) + TriggerServerEvent("QBCore:ToggleDuty") + if CheckJob() and CheckOnduty() == false then + OnDuty = true + else + OnDuty = false + end +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/CDU_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/CDU_menu.lua new file mode 100644 index 0000000..36778d7 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/CDU_menu.lua @@ -0,0 +1,122 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +local function showCDU(data) + if not data then return end + local state = '' + if data.metadata.state == true then + state = 'Aktiv' + else + state = 'Inaktiv' + end + local header = "Råoile destilations-enhed (" .. state .. ')' + -- header + local CDU_Temperature = data.metadata.temp + local CDU_Gal = data.metadata.oil_storage + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-gear' + }, { + header = 'Temperatur', + icon = 'fa-solid fa-temperature-high', + txt = "" .. CDU_Temperature .. " °C", + }, + { + header = 'Råoile i CDU', + icon = 'fa-solid fa-oil-can', + txt = CDU_Gal .. " Liter", + }, + { + header = 'Pump råoile til CDU', + icon = 'fa-solid fa-arrows-spin', + params = { + event = "keep-oilrig:CDU_menu:pumpCrudeOil_to_CDU" + } + }, + { + header = 'Skift temperatur', + icon = 'fa-solid fa-temperature-arrow-up', + params = { + event = "keep-oilrig:CDU_menu:set_CDU_temp" + } + }, + { + header = 'Toggle CDU', + icon = 'fa-solid fa-sliders', + params = { + event = "keep-oilrig:CDU_menu:switchPower_of_CDU" + } + }, + { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + } + exports['qb-menu']:openMenu(openMenu) +end + +AddEventHandler('keep-oilrig:CDU_menu:ShowCDU', function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:get_CDU_Data', function(result) + showCDU(result) + end) +end) + +AddEventHandler('keep-oilrig:CDU_menu:switchPower_of_CDU', function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:switchPower_of_CDU', function(result) + showCDU(result) + end) +end) + +AddEventHandler('keep-oilrig:CDU_menu:set_CDU_temp', function() + local inputData = exports['qb-input']:ShowInput({ + header = "CDU Temperatur", + submitText = "Angiv ny temperatur", + inputs = { { + type = 'number', + isRequired = true, + name = 'temp', + text = "Angiv ny temperatur" + }, + } + }) + if inputData then + if not inputData.temp then + return + end + QBCore.Functions.TriggerCallback('keep-oilrig:server:set_CDU_temp', function(result) + showCDU(result) + end, inputData) + end +end) + +AddEventHandler('keep-oilrig:CDU_menu:pumpCrudeOil_to_CDU', function() + local inputData = exports['qb-input']:ShowInput({ + header = "Pump råoile til CDU", + submitText = "Enter", + inputs = { { + type = 'number', + isRequired = true, + name = 'mændge', + text = "Angiv mængde råoile" + }, + } + }) + if inputData then + inputData.amount = tonumber(inputData.amount) + if not inputData.amount then + return + end + + if inputData.amount <= 0 then + QBCore.Functions.Notify('Mængde skal være mere end 0', "error") + return + end + QBCore.Functions.TriggerCallback('keep-oilrig:server:pumpCrudeOil_to_CDU', function(result) + showCDU(result) + end, inputData) + end +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/blender_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/blender_menu.lua new file mode 100644 index 0000000..e8edf2a --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/blender_menu.lua @@ -0,0 +1,199 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +local function showblender(data) + local state = '' + local start_btn = 'Start' + local start_icon = 'fa-solid fa-square-caret-right' + if type(data) == "table" and data.metadata.state == false then + state = 'Inactive' + start_btn = 'Start' + start_icon = 'fa-solid fa-square-caret-right' + else + state = 'Active' + start_btn = 'Stop' + start_icon = "fa-solid fa-circle-stop" + end + + local header = "Blender unit (" .. state .. ')' + -- header + local heavy_naphtha = data.metadata.heavy_naphtha + local light_naphtha = data.metadata.light_naphtha + local other_gases = data.metadata.other_gases + -- new elements + local diesel = data.metadata.diesel + local kerosene = data.metadata.kerosene + local fuel_oil = data.metadata.fuel_oil + + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-blender' + }, { + header = 'Tung råoile', + icon = 'fa-solid fa-circle', + txt = heavy_naphtha .. " liter", + disabled = true + }, + { + header = 'Let råoile', + icon = 'fa-solid fa-circle', + txt = light_naphtha .. " liter", + disabled = true + }, + { + header = 'Andre gasser', + icon = 'fa-solid fa-circle', + txt = other_gases .. " liter", + disabled = true + }, + } + -- new elements + if diesel then + openMenu[#openMenu + 1] = { + header = 'Diesel', + icon = 'fa-solid fa-circle', + txt = diesel .. " liter", + disabled = true + } + end + + if kerosene then + openMenu[#openMenu + 1] = { + header = 'Petroleum', + icon = 'fa-solid fa-circle', + txt = kerosene .. " liter", + disabled = true + } + end + + if fuel_oil then + openMenu[#openMenu + 1] = { + header = 'Brændselsolie', + icon = 'fa-solid fa-circle', + txt = fuel_oil .. " Liter (Bruges ikke i blandingsprocessen)", + disabled = true + } + end + + openMenu[#openMenu + 1] = { + header = 'Skift opskrift', + icon = 'fa-solid fa-scroll', + params = { + event = "keep-oilrig:blender_menu:recipe_blender" + } + } + + openMenu[#openMenu + 1] = { + header = start_btn .. ' Blander', + icon = start_icon, + params = { + event = "keep-oilrig:blender_menu:toggle_blender" + } + } + + openMenu[#openMenu + 1] = { + header = 'Pump brændselsolie til tank', + icon = 'fa-solid fa-arrows-spin', + params = { + event = "keep-oilrig:blender_menu:pump_fueloil" + } + } + + openMenu[#openMenu + 1] = { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + + exports['qb-menu']:openMenu(openMenu) +end + +AddEventHandler('keep-oilrig:blender_menu:pump_fueloil', function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:pump_fueloil', function(result) + showblender(result) + end) +end) + +AddEventHandler('keep-oilrig:blender_menu:ShowBlender', function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:ShowBlender', function(result) + showblender(result) + end) +end) + +AddEventHandler('keep-oilrig:blender_menu:toggle_blender', function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:toggle_blender', function(result) + showblender(result) + end) +end) + +local function inRange(x, min, max) + return (x >= min and x <= max) +end + +AddEventHandler('keep-oilrig:blender_menu:recipe_blender', function() + local inputData = exports['qb-input']:ShowInput({ + header = "Pump råoile til CDU", + submitText = "Enter", + inputs = { + { + type = 'number', + isRequired = true, + name = 'heavy_naphtha', + text = "Tung råoile" + }, + { + type = 'number', + isRequired = true, + name = 'light_naphtha', + text = "Let råoile" + }, + { + type = 'number', + isRequired = true, + name = 'other_gases', + text = "Andre gasser" + }, + -- new elements + + { + type = 'number', + isRequired = true, + name = 'diesel', + text = "Diesel" + }, + + { + type = 'number', + isRequired = true, + name = 'kerosene', + text = "Petroleum" + }, + } + }) + if inputData then + if not + ( + inputData.heavy_naphtha + and inputData.light_naphtha + and inputData.other_gases + and inputData.diesel + and inputData.kerosene + ) then + return + end + + for _, value in pairs(inputData) do + if not inRange(tonumber(value), 0, 100) then + QBCore.Functions.Notify('Nummer skal være mellem 0-100', "primary") + return + end + end + + QBCore.Functions.TriggerCallback('keep-oilrig:server:recipe_blender', function(result) + showblender(result) + end, inputData) + end +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/edit_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/edit_menu.lua new file mode 100644 index 0000000..2af8e20 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/edit_menu.lua @@ -0,0 +1,83 @@ +local menu = MenuV:CreateMenu('Swkeep Oliebrønd', 'Menu', 'topright', 0, 0, 0, 'size-125', 'default', 'menuv', 'swkeep_oilwell', 'default') +menu.Title = ('Entity: %s'):format(OBJECT) + +local slider = menu:AddSlider({ icon = '❓', label = 'Præcision', value = '', values = { + { label = 'X1', value = 1 }, + { label = 'X2', value = 2 }, + { label = 'X3', value = 3 }, + { label = 'X4', value = 4 }, + { label = 'X5', value = 5 }, + { label = 'X6', value = 6 } +} }) + +local range = menu:AddRange({ + icon = '↔️', + label = 'Roter på Z', + min = -10, + max = 10, + value = 0, + saveOnUpdate = true +}) +local range2 = menu:AddRange({ + icon = '↕️', + label = 'Roter på Y', + min = -10, + max = 10, + value = 0, + saveOnUpdate = true +}) + +local range3 = menu:AddRange({ + icon = '↕️', + label = 'Roter på X', + min = -10, + max = 10, + value = 0, + saveOnUpdate = true +}) + +--- Events + +slider:On('change', function(item, newValue, oldValue) + local m = 10 * newValue + range.Max = m + range.Min = -m + + range2.Max = m + range2.Min = -m + + range3.Max = m + range3.Min = -m +end) + +range:On('change', function(item, newValue, oldValue) + menu.Title = ('Enhed: %s'):format(OBJECT) + range.Description = ('Nuværrende værdi (x) : %s'):format(newValue) + local roration = GetEntityRotation(OBJECT, 0) + SetEntityRotation(OBJECT, roration.x, roration.y, 0.0 + newValue * 6, 0.0, true) +end) + +range2:On('change', function(item, newValue, oldValue) + menu.Title = ('Enhed: %s'):format(OBJECT) + range2.Description = ('Nuværrende værdi (y) : %s'):format(newValue) + local roration = GetEntityRotation(OBJECT, 0) + SetEntityRotation(OBJECT, roration.x, 0.0 + newValue * 6, roration.z, 0.0, true) +end) + +range3:On('change', function(item, newValue, oldValue) + menu.Title = ('Enhed: %s'):format(OBJECT) + range3.Description = ('Nuværrende værdi (z) : %s'):format(newValue) + local roration = GetEntityRotation(OBJECT, 0) + SetEntityRotation(OBJECT, 0.0 + newValue * 3, roration.y, roration.z, 0.0, true) +end) + +local isOpen = false +AddEventHandler('keep-oilwell:menu:OPENMENU', function() + if not IsPauseMenuActive() and IsNuiFocused() ~= 1 and not isOpen then + MenuV:OpenMenu(menu) + isOpen = true + elseif isOpen == true then + MenuV:CloseMenu(menu) + isOpen = false + end +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/pump_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/pump_menu.lua new file mode 100644 index 0000000..9ff4f44 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/pump_menu.lua @@ -0,0 +1,290 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +local function showInfo(data) + QBCore.Functions.TriggerCallback('keep-oilwell:server:oilwell_metadata', function(selected_oilrig) + local header = "Navn: " .. data.name + local partInfoString = "Bælte: " .. + selected_oilrig.part_info.belt .. + " Polish: " .. selected_oilrig.part_info.polish .. " Clutch: " .. selected_oilrig.part_info.clutch + local duration = math.floor(selected_oilrig.duration / 60) + -- header + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-oil-well' + }, { + header = 'Hastighed', + icon = 'fa-solid fa-gauge', + txt = "" .. selected_oilrig.speed .. " RPM", + disabled = true, + }, + { + header = 'Køretid', + icon = 'fa-solid fa-clock', + txt = "" .. duration .. " Min", + disabled = true, + }, + { + header = 'Temperatur', + icon = 'fa-solid fa-temperature-high', + txt = "" .. selected_oilrig.temp .. " °C", + disabled = true, + }, + { + header = 'Olie i tanken', + icon = 'fa-solid fa-oil-can', + txt = "" .. selected_oilrig.oil_storage .. "/L", + disabled = true, + }, + { + header = 'Part Info', + icon = 'fa-solid fa-oil-can', + txt = partInfoString, + disabled = true, + }, + { + header = 'Pump olie til tank', + icon = 'fa-solid fa-arrows-spin', + params = { + event = 'keep-oilrig:storage_menu:PumpOilToStorage', + args = { + oilrig_hash = data.oilrig_hash + } + } + }, + { + header = 'Manage ansatte', + icon = 'fa-solid fa-people-group', + params = { + event = 'keep-oilwell:menu:ManageEmployees', + args = data.oilrig_hash + + } + }, + { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + } + + exports['qb-menu']:openMenu(openMenu) + end, data.oilrig_hash) +end + +RegisterNetEvent('keep-oilwell:menu:ManageEmployees', function(oilrig_hash) + QBCore.Functions.TriggerCallback('keep-oilwell:server:employees_list', function(result) + if not result then return end + -- header + local Menu = { + { + header = 'Oliebrønd ansatte', + isMenuHeader = true, + icon = 'fa-solid fa-vest' + }, + } + + Menu[#Menu + 1] = { + header = 'Tilføj ansat', + icon = 'fa-solid fa-person-circle-plus', + params = { + event = "keep-oilwell:client:add_employee", + args = { + oilrig_hash = oilrig_hash, + state_id = 1 + } + } + } + + for index, employee in ipairs(result) do + local name = employee.charinfo.firstname .. ' ' .. employee.charinfo.lastname + local gender = (employee.charinfo.gender == 0 and 'Mand' or employee.charinfo.gender ~= 0 and 'Kvinde') + local information = 'Navn: %s Telefon: %s Køn: %s ' + local other = ' (Online: %s)' + local online = (employee.online and '🟢' or not employee.online and '🔴') + + Menu[#Menu + 1] = { + header = 'Ansat #' .. index .. string.format(other, online), + txt = string.format(information, name, employee.charinfo.phone, gender), + icon = 'fa-solid fa-person', + params = { + event = "keep-oilwell:menu:remove_employee", + args = { + employee = employee, + oilrig_hash = oilrig_hash + } + } + } + end + + Menu[#Menu + 1] = { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + + exports['qb-menu']:openMenu(Menu) + end, oilrig_hash) +end) + +RegisterNetEvent('keep-oilwell:client:add_employee', function(data) + local inputData = exports['qb-input']:ShowInput({ + header = 'BorgerID', + inputs = { + { + type = 'number', + isRequired = true, + name = 'BorgerID', + text = 'Skriv BorgerID' + }, + } + }) + if inputData then + if not inputData.stateId then return end + inputData.stateId = tonumber(inputData.stateId) + TriggerServerEvent('keep-oilwell:server:add_employee', data.oilrig_hash, inputData.stateId) + end +end) + +RegisterNetEvent('keep-oilwell:menu:remove_employee', function(data) + local employee = data.employee + local name = employee.charinfo.firstname .. ' ' .. employee.charinfo.lastname + -- header + local Menu = { + { + header = 'Tilbage', + icon = 'fa-solid fa-angle-left', + params = { + event = "keep-oilwell:menu:ManageEmployees", + args = data.oilrig_hash + } + }, + { + header = 'Fyr ansat', + txt = 'Name: ' .. name, + isMenuHeader = true, + icon = 'fa-solid fa-vest' + }, + { + header = 'Ja', + icon = 'fa-solid fa-circle-check', + params = { + event = "keep-oilwell:menu:fire_employee", + args = { + employee = data.employee, + oilrig_hash = data.oilrig_hash + } + } + } + } + + Menu[#Menu + 1] = { + header = 'Annuller', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + + exports['qb-menu']:openMenu(Menu) +end) + +RegisterNetEvent('keep-oilwell:menu:fire_employee', function(data) + TriggerServerEvent('keep-oilwell:server:remove_employee', data.oilrig_hash, data.employee.citizenid) +end) + +local function show_oilwell_stash(data) + QBCore.Functions.TriggerCallback('keep-oilwell:server:oilwell_metadata', function(selected_oilrig) + local header = "Navn: " .. data.name + local partInfoString = "Bælte: " .. + selected_oilrig.part_info.belt .. + " Polish: " .. selected_oilrig.part_info.polish .. " Clutch: " .. selected_oilrig.part_info.clutch + -- header + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-oil-well' + }, + { + header = 'Part Info', + icon = 'fa-solid fa-oil-can', + txt = partInfoString, + disabled = true, + }, + { + header = 'Åben stash', + icon = 'fa-solid fa-cart-flatbed', + params = { + event = 'keep-oilwell:client:openOilPump', + args = { + oilrig_hash = data.oilrig_hash + } + } + }, + { + header = 'Fiks oliebrønd', + icon = 'fa-solid fa-screwdriver-wrench', + + params = { + event = 'keep-oilwell:client:fix_oilwell', + args = { + oilrig_hash = data.oilrig_hash + } + } + }, + { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + } + + exports['qb-menu']:openMenu(openMenu) + end, data.oilrig_hash) +end + +-- Events +AddEventHandler('keep-oilrig:storage_menu:PumpOilToStorage', function(data) + QBCore.Functions.TriggerCallback('keep-oilrig:server:PumpOilToStorageCallback', function(result) + + end, data.oilrig_hash) +end) + +AddEventHandler('keep-oilrig:client:viewPumpInfo', function(qbtarget) + -- ask for updated data + OilRigs:startUpdate(function() + showInfo(OilRigs:getByEntityHandle(qbtarget.entity)) + end) +end) + + +AddEventHandler('keep-oilrig:client:show_oilwell_stash', function(qbtarget) + -- ask for updated data + OilRigs:startUpdate(function() + show_oilwell_stash(OilRigs:getByEntityHandle(qbtarget.entity)) + end) +end) + +-- Open oil pump stash. +RegisterNetEvent("keep-oilwell:client:openOilPump", function(data) + if not data then return end + TriggerServerEvent("inventory:server:OpenInventory", "stash", "oilPump_" .. data.oilrig_hash, + { maxweight = 100000, slots = 5 }) + TriggerEvent("inventory:client:SetCurrentStash", "oilPump_" .. data.oilrig_hash) +end) + +AddEventHandler('keep-oilwell:client:fix_oilwell', function(data) + -- ask for updated data + QBCore.Functions.TriggerCallback('keep-oilwell:server:fix_oil_well', function(result) + -- print(result) + end, data.oilrig_hash) + +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/storage_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/storage_menu.lua new file mode 100644 index 0000000..4304e16 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/storage_menu.lua @@ -0,0 +1,322 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +local function showStorage(storage_data) + local header = storage_data.name + -- header + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-warehouse' + }, { + header = 'Råoile', + icon = 'fa-solid fa-oil-can', + txt = "" .. storage_data.metadata.crudeOil .. " /l", + params = { + event = 'keep-oilrig:storage_menu:StorageActions', + args = { + type = 'crudeOil', + storage_data = storage_data + } + } + }, + { + header = 'Brændstof', + icon = 'fa-solid fa-oil-can', + txt = "" .. storage_data.metadata.gasoline .. " /l | Oktan: " .. storage_data.metadata.avg_gas_octane, + params = { + event = 'keep-oilrig:storage_menu:StorageActions', + args = { + type = 'gasoline', + storage_data = storage_data + } + } + }, + + } + + if storage_data.metadata.fuel_oil then + openMenu[#openMenu + 1] = { + header = 'Brændselsolie', + icon = 'fa-solid fa-oil-can', + txt = "" .. storage_data.metadata.fuel_oil .. " /l", + params = { + event = 'keep-oilrig:storage_menu:StorageActions', + args = { + type = 'fuel_oil', + storage_data = storage_data + } + } + } + end + + + openMenu[#openMenu + 1] = { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + + exports['qb-menu']:openMenu(openMenu) +end + +local function showStorageActions(data) + local header = "Actions " .. data.type + local storage_data = data.storage_data + -- header + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-pump' + }, { + header = 'Tag fra lager', + icon = 'fa-solid fa-truck-ramp-box', + txt = "", + params = { + event = 'keep-oilrig:storage_menu:StorageWithdraw', + args = data + } + }, + { + header = 'Lagerhandling', + icon = 'fa-solid fa-arrow-right-arrow-left', + params = { + event = '', + } + }, + { + header = 'Tilbage', + icon = 'fa-solid fa-angle-left', + params = { + event = "keep-oilrig:storage_menu:ShowStorage" + } + } + } + + exports['qb-menu']:openMenu(openMenu) +end + +local function showStorageWithdraw(data) + local header = "Tag fra lager (" .. data.type .. ")" + local currentWithdrawTarget = data.storage_data.metadata[data.type] -- oil or gas + -- header + local openMenu = { + { + header = header, + isMenuHeader = true, + icon = 'fa-solid fa-boxes-packing' + }, + { + header = 'Du har ' .. currentWithdrawTarget .. ' liter ' .. data.type, + isMenuHeader = true, + icon = 'fa-solid fa-boxes-packing' + }, { + header = 'Gem i tønde', + icon = 'fa-solid fa-bottle-droplet', + txt = "Depositum: 500,- Kapacitet: 5000 /l", + params = { + event = 'keep-oilrig:storage_menu:Callback', + args = { + eventName = 'keep-oilrig:server:Withdraw', + citizenid = data.storage_data.citizenid, + type = data.type, + truck = false + } + } + }, + { + header = 'Fyld tankbil', + icon = 'fa-solid fa-truck-droplet', + txt = "Depositum: 25.000,- Kapacitet: 100.000 /l", + params = { + event = 'keep-oilrig:storage_menu:Callback', + args = { + eventName = 'keep-oilrig:server:Withdraw', + citizenid = data.storage_data.citizenid, + type = data.type, + truck = true + } + } + }, + { + header = 'Tilbage', + icon = 'fa-solid fa-angle-left', + params = { + event = "keep-oilrig:storage_menu:StorageActions", + args = data + } + } + } + exports['qb-menu']:openMenu(openMenu) +end + +MakeVehicle = function(model, Coord, TriggerLocation, DinstanceToTrigger, items) + local plyped = PlayerPedId() + local pedCoord = GetEntityCoords(plyped) + local finished = false + local distance = GetDistanceBetweenCoords(pedCoord.x, pedCoord.y, pedCoord.z, TriggerLocation.x, TriggerLocation.y, + TriggerLocation.z, true) + CreateThread(function() + while distance > DinstanceToTrigger do + local pedCoord = GetEntityCoords(plyped) + distance = GetDistanceBetweenCoords(pedCoord.x, pedCoord.y, pedCoord.z, TriggerLocation.x, + TriggerLocation.y, TriggerLocation.z, true) + Wait(1000) + end + finished = true + end) + + -- wait for player at delivery coord + while finished == false do + DrawMarker(2, TriggerLocation.x, TriggerLocation.y, TriggerLocation.z + 2, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 1.0 + , 1.0, + 1.0, 255, 128, 0, 50, false, true, 2, nil, nil, false) + Wait(0) + end + + local vehiclePlate = "HPO" .. math.random(1, 9) .. math.random(1, 9) .. math.random(1, 9) + model = GetHashKey(model) + RequestModel(model) + while not HasModelLoaded(model) do + Wait(10) + end + + local veh = CreateVehicle(model, Coord.x, Coord.y, Coord.z, Coord.w, true, false) + local netid = NetworkGetNetworkIdFromEntity(veh) + SetVehicleHasBeenOwnedByPlayer(veh, true) + + SetNetworkIdCanMigrate(netid, true) + SetVehicleNeedsToBeHotwired(veh, false) + SetVehRadioStation(veh, "OFF") + + SetVehicleNumberPlateText(veh, vehiclePlate) + + exports[Oilwell_config.fuel_script]:SetFuel(veh, math.random(80, 90)) + SetVehicleEngineOn(veh, true, true) + + SetNetworkIdAlwaysExistsForPlayer(NetworkGetNetworkIdFromEntity(veh), PlayerPedId(), true) + TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh)) + TriggerEvent("vehiclekeys:client:SetOwner", vehiclePlate) + SetModelAsNoLongerNeeded(model) + Targets.qb_target.truck(vehiclePlate, veh) + + TriggerServerEvent('keep-oilwell:server_lib:update_vehicle', vehiclePlate, items) +end + + +RegisterNetEvent('keep-oilrig:client_lib:withdraw_from_queue', function(data) + QBCore.Functions.TriggerCallback('keep-oilrig:server:withdraw_from_queue', function(result) + -- res >> table of items + if result == false then + return + end + if not result.truck then + return + end + local SpawnLocation = Oilwell_config.Delivery.SpawnLocation + local TriggerLocation = Oilwell_config.Delivery.TriggerLocation + local DinstanceToTrigger = Oilwell_config.Delivery.DinstanceToTrigger + local model = Oilwell_config.Delivery.vehicleModel + + MakeVehicle(model, SpawnLocation, TriggerLocation, DinstanceToTrigger, result) + end, data.truck) +end) + +-- Events + +AddEventHandler('keep-oilrig:storage_menu:ShowStorage', function(data) + QBCore.Functions.TriggerCallback('keep-oilrig:server:getStorageData', function(result) + showStorage(result) + end) +end) + +AddEventHandler('keep-oilrig:storage_menu:StorageActions', function(storage_data) + showStorageActions(storage_data) +end) + +AddEventHandler('keep-oilrig:storage_menu:StorageWithdraw', function(data) + showStorageWithdraw(data) +end) + +AddEventHandler('keep-oilrig:storage_menu:Callback', function(data) + local inputData = exports['qb-input']:ShowInput({ + header = "Angiv mængde", + submitText = "Bekræft", + inputs = { + { + type = 'number', + isRequired = true, + name = 'Mængde', + text = "Mængde" + }, + } + }) + if inputData then + if not inputData.amount then + return + end + data.amount = inputData.amount + QBCore.Functions.TriggerCallback(data.eventName, function(res) + + end, data) + end +end) + + +-- withdraw spot +AddEventHandler("keep-oilwell:client:openWithdrawStash", function(data) + local player = QBCore.Functions.GetPlayerData() + if not data then return end + local settings = { maxweight = 100000, slots = 5 } + TriggerServerEvent("inventory:server:OpenInventory", "stash", "Withdraw_" .. player.citizenid, settings) + TriggerEvent("inventory:client:SetCurrentStash", "Withdraw_" .. player.citizenid) +end) + +-- purge menu +local function purge_menu() + local openMenu = { + { + header = 'TØM', + txt = 'Ønsker du at tømme lageret?', + icon = 'fa-solid fa-trash-can', + isMenuHeader = true, + }, + { + header = 'Bekræft', + icon = 'fa-solid fa-square-check', + params = { + event = 'keep-oilwell:client:purgeWithdrawStash', + } + }, + { + header = 'Annuller', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + } + exports['qb-menu']:openMenu(openMenu) +end + +AddEventHandler('keep-oilwell:client:open_purge_menu', function() + purge_menu() +end) + +local purge_conf = 0 +AddEventHandler('keep-oilwell:client:purgeWithdrawStash', function() + if purge_conf == 0 then + QBCore.Functions.Notify('Prøv igen! (Resetter om 5 sekunder)', "primary") + purge_conf = purge_conf + 1 + SetTimeout(5000, function() + purge_conf = 0 + end) + purge_menu() + return + end + purge_conf = 0 + TriggerServerEvent('keep-oilwell:server:purgeWithdrawStash') +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/transport_menu.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/transport_menu.lua new file mode 100644 index 0000000..7eb560f --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/client_lib/menu/transport_menu.lua @@ -0,0 +1,205 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +local function show_transport_menu() + + -- header + local openMenu = { + { + header = 'Transport', + txt = "Sælg råoile for at tjene penge", + isMenuHeader = true, + icon = 'fa-solid fa-ship' + }, + { + header = 'Kontroller nuværende pris/lager', + icon = 'fa-solid fa-hand-holding-dollar', + txt = "", + params = { + event = 'keep-oilwell:menu:show_transport_menu:ask_stock_price', + } + }, + { + header = 'Anmod om salgsorder', + icon = 'fa-solid fa-diagram-successor', + txt = "", + params = { + event = 'keep-oilwell:menu:show_transport_menu:ask_to_sell_amount', + } + }, + { + header = 'Forlad', + icon = 'fa-solid fa-circle-xmark', + params = { + event = "qb-menu:closeMenu" + } + } + } + + exports['qb-menu']:openMenu(openMenu) +end + +AddEventHandler('keep-oilwell:menu:show_transport_menu', function() + show_transport_menu() +end) + +AddEventHandler('keep-oilwell:menu:show_transport_menu:ask_stock_price', function() + TriggerServerEvent('keep-oilrig:server:oil_transport:checkPrice') +end) + +local function disableCombat() + DisablePlayerFiring(PlayerId(), true) -- Disable weapon firing + DisableControlAction(0, 24, true) -- disable attack + DisableControlAction(0, 25, true) -- disable aim + DisableControlAction(1, 37, true) -- disable weapon select + DisableControlAction(0, 47, true) -- disable weapon + DisableControlAction(0, 58, true) -- disable weapon + DisableControlAction(0, 140, true) -- disable melee + DisableControlAction(0, 141, true) -- disable melee + DisableControlAction(0, 142, true) -- disable melee + DisableControlAction(0, 143, true) -- disable melee + DisableControlAction(0, 263, true) -- disable melee + DisableControlAction(0, 264, true) -- disable melee + DisableControlAction(0, 257, true) -- disable melee +end + +function LoadAnim(dict) + while not HasAnimDictLoaded(dict) do + RequestAnimDict(dict) + Wait(10) + end +end + +function LoadPropDict(model) + while not HasModelLoaded(GetHashKey(model)) do + RequestModel(GetHashKey(model)) + Wait(10) + end +end + +local active_prop = nil +function AttachProp(model, bone, x, y, z, rot1, rot2, rot3) + local playerped = PlayerPedId() + local model_hash = GetHashKey(model) + local playercoord = GetEntityCoords(playerped) + local bone_index = GetPedBoneIndex(playerped, bone) + local _x, _y, _z = table.unpack(playercoord) + + if not HasModelLoaded(model) then + LoadPropDict(model) + end + + active_prop = CreateObject(model_hash, _x, _y, _z + 0.2, true, true, true) + AttachEntityToEntity(active_prop, playerped, bone_index, x, y, z, rot1, rot2, rot3, true, true, false, true, 1, true) + SetModelAsNoLongerNeeded(model) +end + +local function start_barell_animation() + local playerped = PlayerPedId() + local dict = 'anim@heists@box_carry@' + local anim = 'idle' + local PropName = 'prop_barrel_exp_01a' + local PropBone = 60309 + + LoadAnim(dict) + ClearPedTasks(playerped) + RemoveAnimDict(dict) + Wait(250) + AttachProp(PropName, PropBone, 0.0, 0.41, 0.3, 130.0, 290.0, 0.0) + CreateThread(function() + while active_prop do + local not_animation = IsEntityPlayingAnim(playerped, dict, anim, 3) + if not_animation ~= 1 then + TaskPlayAnim(playerped, dict, anim, 2.0, 2.0, -1, 51, 0, false, false, false) + DisableControlAction(0, 22, true) + end + Wait(1500) + end + end) + CreateThread(function() + while active_prop do + --disable combat while player have barell in their hands + disableCombat() + Wait(1) + end + end) +end + +local function end_barell_animaiton() + local playerped = PlayerPedId() + local dict = 'anim@heists@box_carry@' + local anim = 'idle' + + if active_prop then + DeleteObject(active_prop) + active_prop = nil + end + StopAnimTask(playerped, dict, anim, 1.0) +end + +AddEventHandler('keep-oilwell:menu:show_transport_menu:ask_to_sell_amount', function() + local inputData = exports['qb-input']:ShowInput({ + header = "Antal tønder", + submitText = "Sælg", + inputs = { + { + type = 'number', + isRequired = true, + name = 'Mængde', + text = "Mængde" + }, + } + }) + if inputData then + if not inputData.amount then + return + end + if type(inputData.amount) == 'string' then + inputData.amount = math.floor(tonumber(inputData.amount)) + end + -- start_barell_animation() + QBCore.Functions.Progressbar("keep_oilwell_transport", 'Fylder', Oilwell_config.Transport.duration * 1000, + false, false, { + disableMovement = true, + disableCarMovement = false, + disableMouse = false, + disableCombat = true + }, {}, {}, {}, function() + QBCore.Functions.TriggerCallback('keep-oilrig:server:oil_transport:fillTransportWell', function(res) + -- end_barell_animaiton() + end, inputData.amount) + end) + end +end) + +local inventory_max_size = Oilwell_config.inventory_max_size + +local function isBarellInInventory() + local items = QBCore.Functions.GetPlayerData().items + for slot = 1, inventory_max_size, 1 do + if items[slot] and items[slot].name == 'oilbarell' then + return true + end + end + return false +end + +local already_started = false +function StartBarellAnimation() + if already_started then return end + already_started = true + CreateThread(function() + while true do + local b = isBarellInInventory() + if b then + if not active_prop then + start_barell_animation() + end + else + if active_prop then + end_barell_animaiton() + end + end + Wait(1500) + end + end) +end diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/qb_target.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/qb_target.lua new file mode 100644 index 0000000..a2c4772 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/qb_target.lua @@ -0,0 +1,285 @@ +local QBCore = exports['qb-core']:GetCoreObject() +local debugPoly = false + +Targets['qb_target'] = {} + +function Targets.qb_target.storage(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 2) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 1, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilrig:storage_menu:ShowStorage", + icon = "fa-solid fa-arrows-spin", + label = "Vis lager", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.distillation(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 1.1) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 1.2, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilrig:CDU_menu:ShowCDU", + icon = "fa-solid fa-gear", + label = "Åben CDU panel", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 1.5 + }) +end + +function Targets.qb_target.toggle_job(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 1.1) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 0.75, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilrig:client:goOnDuty", + icon = "fa-solid fa-boxes-packing", + label = "Gå hjem/på arbejde", + canInteract = function(entity) + if not CheckJob() then return false end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.barrel_withdraw(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 1.1) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 1.0, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilrig:client_lib:withdraw_from_queue", + icon = "fa-solid fa-boxes-packing", + label = "Overfør til lager", + truck = false, + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + { + type = "client", + event = "keep-oilwell:client:openWithdrawStash", + icon = "fa-solid fa-boxes-packing", + label = "Open Withdraw Stash", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + { + type = "client", + event = "keep-oilwell:client:open_purge_menu", + icon = "fa-solid fa-trash-can", + label = "Tøm lager", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.blender(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 2.5) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 3.5, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilrig:blender_menu:ShowBlender", + icon = "fa-solid fa-gear", + label = "Åben blandingspanel", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.crude_oil_transport(coords, name) + local tmp_coord = vector3(coords.x, coords.y, coords.z + 2.5) + + exports['qb-target']:AddCircleZone(name, tmp_coord, 2, { + name = name, + debugPoly = debugPoly, + useZ = true + }, { + options = { + { + type = "client", + event = "keep-oilwell:menu:show_transport_menu", + icon = "fa-solid fa-boxes-packing", + label = "Fyld transportbrønd", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then + QBCore.Functions.Notify('Du skal være på job!', "error") + Wait(2000) + return false + end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.oilwell(coords, name) + local coord = vector3(coords.x, coords.y, coords.z + 2.5) + + exports['qb-target']:AddCircleZone("oil-rig-" .. name, coord, 3.5, { + name = "oil-rig-" .. name, + debugPoly = false, + useZ = true, + }, { + options = { + { + type = "client", + event = "keep-oilrig:client:viewPumpInfo", + icon = "fa-solid fa-info", + label = "Se pumpe info", + canInteract = function(entity) + return true + end, + }, + { + type = "client", + event = "keep-oilrig:client:changeRigSpeed", + icon = "fa-solid fa-gauge-high", + label = "Modificer pumpe indstillinger", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then return false end + return isOwner(entity) + end, + }, + { + type = "client", + event = "keep-oilrig:client:show_oilwell_stash", + icon = "fa-solid fa-gears", + label = "Håndter dele", + canInteract = function(entity) + if not CheckJob() then return false end + if not CheckOnduty() then return false end + return isOwner(entity) + end, + }, + { + type = "client", + event = "keep-oilwell:client:remove_oilwell", + icon = "fa-regular fa-file-lines", + label = "Fjern oliebrønd", + canInteract = function(entity) + if not CheckJob() then + return false + end + if not (PlayerJob.grade.level == 4) then + return false + end + if not CheckOnduty() then + return false + end + return true + end, + }, + }, + distance = 2.5 + }) +end + +function Targets.qb_target.truck(plate, truck) + exports['qb-target']:AddEntityZone("device-" .. plate, truck, { + name = "device-" .. plate, + debugPoly = false, + }, { + options = { + { + type = "client", + event = "keep-oilwell:client:refund_truck", + icon = "fa-solid fa-location-arrow", + label = "Refunder køretøj", + vehiclePlate = plate + }, + }, + distance = 2.5 + }) +end diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/target.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/target.lua new file mode 100644 index 0000000..116d627 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/client/target/target.lua @@ -0,0 +1,137 @@ +Targets = {} +local QBCore = exports['qb-core']:GetCoreObject() + +local loaded = false +local PED = nil +local function setPedVariation(pedHnadle, variation) + for componentId, v in pairs(variation) do + if IsPedComponentVariationValid(pedHnadle, componentId, v.drawableId, v.textureId) then + SetPedComponentVariation(pedHnadle, componentId, v.drawableId, v.textureId) + end + end +end + +function GETPED() + return PED +end + +function SETPED(ped) + PED = ped +end + +local function spawn_ped(data) + RequestModel(data.model) + while not HasModelLoaded(data.model) do + Wait(0) + end + + if type(data.model) == 'string' then data.model = GetHashKey(data.model) end + + local ped = CreatePed(1, data.model, data.coords, data.networked or false, true) + + if data.variant then setPedVariation(ped, data.variant) end + if data.freeze then FreezeEntityPosition(ped, true) end + if data.invincible then SetEntityInvincible(ped, true) end + if data.blockevents then SetBlockingOfNonTemporaryEvents(ped, true) end + if data.animDict and data.anim then + RequestAnimDict(data.animDict) + while not HasAnimDictLoaded(data.animDict) do + Wait(0) + end + + if type(data.anim) == "table" then + CreateThread(function() + while true do + local anim = data.anim[math.random(0, #data.anim)] + ClearPedTasks(ped) + TaskPlayAnim(ped, data.animDict, anim, 8.0, 0, -1, data.flag or 1, 0, 0, 0, 0) + SETPED(ped) + Wait(7000) + end + end) + else + TaskPlayAnim(ped, data.animDict, data.anim, 8.0, 0, -1, data.flag or 1, 0, 0, 0, 0) + end + end + + if data.scenario then + SetPedCanPlayAmbientAnims(ped, true) + TaskStartScenarioInPlace(ped, data.scenario, 0, true) + end + + if data.voice then + SetAmbientVoiceName(ped, 'A_F_Y_BUSINESS_01_WHITE_FULL_01') + end + SETPED(ped) +end + +local function makeCore() + if loaded then return end + Citizen.CreateThread(function() + local c = Oilwell_config.TruckWithdraw.npc.coords + local vec3_coord = vector3(c.x, c.y, c.z) + PED = spawn_ped(Oilwell_config.TruckWithdraw.npc) + + exports['qb-target']:AddBoxZone("keep_oilwell_withdraw_truck_target", vec3_coord, + Oilwell_config.TruckWithdraw.box.l, + Oilwell_config.TruckWithdraw.box.w, + { + name = "keep_oilwell_withdraw_truck_target", + heading = Oilwell_config.TruckWithdraw.box.heading, + debugPoly = false, + minZ = vec3_coord.z + Oilwell_config.TruckWithdraw.box.minz_offset, + maxZ = vec3_coord.z + Oilwell_config.TruckWithdraw.box.maxz_offset, + }, { + options = { + { + event = "keep-oilrig:client_lib:withdraw_from_queue", + icon = "fa-solid fa-truck-droplet", + label = 'Tag lastbil', + truck = true + }, + }, + distance = 2.0 + }) + loaded = true + end) +end + +AddEventHandler('keep-oilwell:client:refund_truck', function(data) + local coord = GetEntityCoords(data.entity) + local spawnLocation = vector3(Oilwell_config.Delivery.SpawnLocation.x, Oilwell_config.Delivery.SpawnLocation.y, + Oilwell_config.Delivery.SpawnLocation.z) + + local plate = data.vehiclePlate + + if #(coord - spawnLocation) > 5.0 then + QBCore.Functions.Notify('Du er ikke tæt nok på, for at kunne refundere', "primary") + return + end + QBCore.Functions.TriggerCallback('keep-oilwell:server:refund_truck', function(result) + if result == true then + local netId = NetworkGetNetworkIdFromEntity(data.entity) + local entity = NetworkGetEntityFromNetworkId(netId) + NetworkRequestControlOfEntity(entity) + DeleteEntity(entity) + end + end, plate) +end) + + +AddEventHandler('onResourceStart', function(resourceName) + if (GetCurrentResourceName() ~= resourceName) then return end + Wait(1000) + makeCore() +end) + +RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() + Wait(1000) + makeCore() +end) + +AddEventHandler('onResourceStop', function(resourceName) + if resourceName ~= GetCurrentResourceName() then + return + end + DeleteEntity(GETPED()) +end) diff --git a/resources/[qb]/[qb_jobs]/keep-oilwell/config.lua b/resources/[qb]/[qb_jobs]/keep-oilwell/config.lua new file mode 100644 index 0000000..3088b9d --- /dev/null +++ b/resources/[qb]/[qb_jobs]/keep-oilwell/config.lua @@ -0,0 +1,167 @@ +Oilwell_config = Oilwell_config or {} + +Oilwell_config.inventory_max_size = 41 +Oilwell_config.AnimationSpeedDivider = 20 -- higher value => less animation speed at 100% +Oilwell_config.actionSpeed = 5 -- how fast oilpump actionspeed is updated to new action speed / just visual +Oilwell_config.fuel_script = 'qb-fuel' + +Oilwell_config.Settings = { + size = { + oilwell_storage = 10000, + }, + oil_well = { + blip = { + sprite = 436, + colour = 5, + range = 'short', + -- CITIZENID | OILWELLNAME | DB_ID_RAW | TYPE | OILWELL_HASH + -- if scirpt detect this keywords inside string it will replace them. + name = 'Oil DB_ID_RAW' + } + }, + capacity = { + oilbarell = { + size = 5000, -- gal + cost = 500 + }, + truck = { + size = 5000, -- gal placeholder + cost = 25000 + } + } +} + +Oilwell_config.locations = { + storage = { + position = vector4(1710.67, -1662.0, 110.8, 325.22), + rotation = vector3(0.0, 0.0, 0.0), + model = 'prop_storagetank_06', + blip = { + sprite = 478, + colour = 5, + range = 'short', + name = 'Olie-type' + } + }, + distillation = { + position = vector4(1674, -1650.5, 110.2, 10), + rotation = vector3(0.0, 0.0, 10.0), + model = 'prop_gas_tank_01a', + blip = { + sprite = 467, + colour = 5, + range = 'short', + name = 'Olie-type' + } + }, + blender = { + position = vector4(1737.56, -1635.58, 110.88, 190), + rotation = vector3(0.0, 0.0, 190.0), + model = 'prop_storagetank_01', + blip = { + sprite = 365, + colour = 5, + range = 'short', + name = 'Olie-type' + } + }, + barrel_withdraw = { + position = vector4(1712.23, -1622.53, 111.48, 214.88), + rotation = vector3(0.0, 0.0, 0.0), + model = 'imp_prop_groupbarrel_03', + blip = { + sprite = 549, + colour = 5, + range = 'short', + name = 'Olie-type' + } + }, + -- placeholder + -- oil_wellhead = { + -- position = vector4(1480.9, -1850.85, 70.1, 246.85), + -- rotation = vector3(0.0, 0.0, 0.0), + -- model = 'prop_oil_wellhead_01', + -- }, + toggle_job = { + position = vector4(1703.5, -1635, 111.49, 100.11), + rotation = vector3(0.0, 0.0, 100.0), + model = 'xm_base_cia_server_02', + blip = { + sprite = 306, + colour = 5, + range = 'short', + name = 'Olie-type' + } + }, + crude_oil_transport = { + position = vector4(1220.0, -2986.0, 4.7, 180), + rotation = vector3(0.0, 0.0, 180.0), + model = 'prop_oil_wellhead_04', + blip = { + sprite = 306, + colour = 5, + range = 'short', + name = 'Olie-type' + } + } +} + +Oilwell_config.Delivery = { + refund = 20000, + TriggerLocation = vector3(1737.45, -1691.28, 112.73), + SpawnLocation = vector4(1741.19, -1694.61, 112.73, 125.57), + DinstanceToTrigger = 5.0, + vehicleModel = 'rallytruck' +} + +Oilwell_config.Transport = { + max_stock = 20000, --gal per type + prices = { + crudeOil = 3, + gasoline = 7, + fuel_oil = 3.5 + }, + barell_refund = 200, + duration = 5 --sec +} + +-- Make separate file for locale +Oilwell_config.Locale = { + mail = { + sender = 'Olie-firma', + subject = 'Betalings kvittering', + message = 'Kære %s %s,This is a multi-framework taxi job.
+ +It's a great fit for any type of roleplaying server, whether it's Serious RP or not.
+ +With this resource, you will be able to do the following: + +- Create multiple taxi businesses. +- Allow multiple groups to access and manage a business. +- Earn money through NPC missions. +- Spawn Vehicles at the depot. +- Go on/off duty. +- Manage the business. + +## Supported Frameworks + +- ESX 1.1+ & Legacy +- QBCore +- Other (Code your own bridge) + +## What do I need? + +Use a supported framework or make it work with yours via the bridge folder. + +Ox Lib (Required). + +## Installation + +Start ox_lib before pickle_taxijob.
+Add your businesses in the config.lua.
+Add the groups via the SQL files (use included examples in the "_INSTALL" folder).
+Restart the server.
+ +## Need Support? + +Click here! + +## Licensing + +Do not at any point redistribute this without my permission and credit.
+I've already had to issue reports on people selling my Television Script (which is free).
+That is not fair to anyone, especially to the people who get scammed out of their money.
+So please, respect the rules and have fun!
diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/client.lua new file mode 100644 index 0000000..887fe53 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/client.lua @@ -0,0 +1,48 @@ +if GetResourceState('es_extended') ~= 'started' then return end + +ESX = exports.es_extended:getSharedObject() + +function ShowNotification(text) + ESX.ShowNotification(text) +end + +function ShowHelpNotification(text) + ESX.ShowHelpNotification(text) +end + +function ServerCallback(name, cb, ...) + ESX.TriggerServerCallback(name, cb, ...) +end + +function GetPlayersInArea(coords, maxDistance) + return ESX.Game.GetPlayersInArea(coords, maxDistance) +end + +function CanAccessGroup(data) + if not data then return true end + local pdata = ESX.GetPlayerData() + for k,v in pairs(data) do + if (pdata.job.name == k and pdata.job.grade >= v) then return true end + end + return false +end + +function AccessBossMenu(businessID) + local cfg = Config.Businesses[businessID] + if not CanAccessGroup(cfg.bossgroups) then + return ShowNotification(_L("no_access")) + end + TriggerEvent('esx_society:openBossMenu', cfg.info.society, function(data, menu) + menu.close() + end, { + withdraw = false, + deposit = false, + wash = true, + employees = true, + grades = false + }) +end + +RegisterNetEvent(GetCurrentResourceName()..":showNotification", function(text) + ShowNotification(text) +end) \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/server.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/server.lua new file mode 100644 index 0000000..0f5ac41 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/esx/server.lua @@ -0,0 +1,75 @@ +if GetResourceState('es_extended') ~= 'started' then return end + +ESX = exports.es_extended:getSharedObject() + +function RegisterCallback(name, cb) + ESX.RegisterServerCallback(name, cb) +end + +function RegisterUsableItem(...) + ESX.RegisterUsableItem(...) +end + +function ShowNotification(target, text) + TriggerClientEvent(GetCurrentResourceName()..":showNotification", target, text) +end + +function Search(source, name) + local xPlayer = ESX.GetPlayerFromId(source) + if (name == "money") then + return xPlayer.getMoney() + elseif (name == "bank") then + return xPlayer.getAccount('bank').money + else + local item = xPlayer.getInventoryItem(name) + if item ~= nil then + return item.count + else + return 0 + end + end +end + +function AddItem(source, name, amount, metadata) + local xPlayer = ESX.GetPlayerFromId(source) + if (name == "money") then + return xPlayer.addMoney(amount) + elseif (name == "bank") then + return xPlayer.addAccountMoney('bank', amount) + else + return exports.ox_inventory:AddItem(source, name, amount, metadata) + end +end + +function RemoveItem(source, name, amount) + local xPlayer = ESX.GetPlayerFromId(source) + if (name == "money") then + return xPlayer.removeMoney(amount) + elseif (name == "bank") then + return xPlayer.removeAccountMoney('bank', amount) + else + return xPlayer.removeInventoryItem(name, amount) + end +end + +function CanAccessGroup(source, data) + if not data then return true end + local pdata = ESX.GetPlayerFromId(source) + for k,v in pairs(data) do + if (pdata.job.name == k and pdata.job.grade >= v) then return true end + end + return false +end + +function GetIdentifier(source) + local xPlayer = ESX.GetPlayerFromId(source) + return xPlayer.identifier +end + +-- REMOVE BELOW IF NOT USING ESX SOCIETY + +for i=1, #Config.Businesses do + local cfg = Config.Businesses[i] + local society = cfg.info.society + TriggerEvent('esx_society:registerSociety', society, society, 'society_'..society, 'society_'..society, 'society_'..society, {type = 'public'}) +end \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/client.lua new file mode 100644 index 0000000..bb62209 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/client.lua @@ -0,0 +1,42 @@ +if GetResourceState('qb-core') ~= 'started' then return end + +QBCore = exports['qb-core']:GetCoreObject() + +function ServerCallback(name, cb, ...) + QBCore.Functions.TriggerCallback(name, cb, ...) +end + +function ShowNotification(text) + QBCore.Functions.Notify(text) +end + +function ShowHelpNotification(text) + AddTextEntry('qbHelpNotification', text) + BeginTextCommandDisplayHelp('qbHelpNotification') + EndTextCommandDisplayHelp(0, false, false, -1) +end + +function GetPlayersInArea(coords, maxDistance) + return QBCore.Functions.GetPlayersFromCoords(coords, maxDistance) +end + +function CanAccessGroup(data) + if not data then return true end + local pdata = QBCore.Functions.GetPlayerData() + for k,v in pairs(data) do + if (pdata.job.name == k and pdata.job.grade.level >= v) then return true end + end + return false +end + +function AccessBossMenu(businessID) + local cfg = Config.Businesses[businessID] + if not CanAccessGroup(cfg.bossgroups) then + return ShowNotification(_L("no_access")) + end + TriggerEvent('qb-bossmenu:client:OpenMenu') +end + +RegisterNetEvent(GetCurrentResourceName()..":showNotification", function(text) + ShowNotification(text) +end) diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/server.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/server.lua new file mode 100644 index 0000000..696fa32 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/qb/server.lua @@ -0,0 +1,67 @@ +if GetResourceState('qb-core') ~= 'started' then return end + +QBCore = exports['qb-core']:GetCoreObject() + +function RegisterCallback(name, cb) + QBCore.Functions.CreateCallback(name, cb) +end + +function RegisterUsableItem(...) + QBCore.Functions.CreateUseableItem(...) +end + +function ShowNotification(target, text) + TriggerClientEvent(GetCurrentResourceName()..":showNotification", target, text) +end + +function Search(source, name) + local xPlayer = QBCore.Functions.GetPlayer(source) + if (name == "money") then + return xPlayer.PlayerData.money['cash'] + elseif (name == "bank") then + return xPlayer.PlayerData.money['cash'] -- If anyone knows how to get bank balance for QBCore, let me know. + else + local item = xPlayer.Functions.GetItemByName(name) + if item ~= nil then + return item.amount + else + return 0 + end + end +end + +function AddItem(source, name, amount, metadata) + local xPlayer = QBCore.Functions.GetPlayer(source) + if (name == "money") then + return xPlayer.Functions.AddMoney("cash", amount) + elseif (name == "bank") then + return xPlayer.Functions.AddMoney("cash", amount) -- If anyone knows how to add to bank balance for QBCore, let me know. + else + return xPlayer.Functions.AddItem(name, amount, nil, metadata) + end +end + +function RemoveItem(source, name, amount) + local xPlayer = QBCore.Functions.GetPlayer(source) + if (name == "money") then + return xPlayer.Functions.RemoveMoney("cash", amount) + elseif (name == "bank") then + return xPlayer.Functions.RemoveMoney("cash", amount) -- If anyone knows how to remove from bank balance for QBCore, let me know. + else + return xPlayer.Functions.RemoveItem(name, amount) + end +end + +function CanAccessGroup(source, data) + if not data then return true end + local pdata = QBCore.Functions.GetPlayer(source).PlayerData + for k,v in pairs(data) do + if (pdata.job.name == k and pdata.job.grade.level >= v) then return true end + end + return false +end + +function GetIdentifier(source) + local xPlayer = QBCore.Functions.GetPlayer(source).PlayerData + return xPlayer.citizenid +end \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/client.lua new file mode 100644 index 0000000..89c1cd1 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/client.lua @@ -0,0 +1,4 @@ +if GetResourceState('es_extended') == 'started' then return end +if GetResourceState('qb-core') == 'started' then return end + +print("You are not using a supported framework, it will be required to make edits to the bridge files.") \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/server.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/server.lua new file mode 100644 index 0000000..89c1cd1 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/bridge/standalone/server.lua @@ -0,0 +1,4 @@ +if GetResourceState('es_extended') == 'started' then return end +if GetResourceState('qb-core') == 'started' then return end + +print("You are not using a supported framework, it will be required to make edits to the bridge files.") \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/config.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/config.lua new file mode 100644 index 0000000..3540631 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/config.lua @@ -0,0 +1,74 @@ +Config = {} + +Config.Debug = false + +Config.Language = "da" + +Config.Businesses = { + { + info = { + id = "pickle_taxi", + society = "taxi", + label = "HP Taxa Selskab", + }, + blip = { + Label = "HP Taxa Selskab", + Location = vector3(912.0522, -174.0470, 74.2908), + ID = 198, + Display = 4, + Scale = 0.75, + Color = 5 + }, + groups = { + ["taxi"] = 0, + }, + bossgroups = { + ["taxi"] = 4, + }, + vehicles = { + { + label = "Taxi", + model = `taxi`, + groups = { + ["taxi"] = 0, + } + }, + { + label = "Limosine", + model = `stretch`, + groups = { + ["taxi"] = 0, + } + }, + }, + locations = { + vehicle = vector4(916.0678, -163.4347, 74.6782, 152.6545), + boss = vector3(895.5319, -179.3002, 74.7003), + duty = vector3(900.5847, -171.5111, 74.0756) + } + } +} + +Config.Missions = { + loop = false, -- Keep doing missions until /taxijob is used. + reward = {name = "money", min = 10, max = 50, miles = 2.0}, -- multiples reward by miles traveled. + models = { + `s_m_m_cntrybar_01`, + `u_f_y_comjane`, + `a_f_y_hipster_04`, + `s_m_m_highsec_02`, + `a_m_y_hipster_03`, + }, + locations = { + vector4(946.3250, -171.7351, 74.5242, 56.1620), + vector4(397.9923, -870.3594, 29.2102, 322.1986), + vector4(59.2745, -1483.8176, 29.2773, 270.6085), + vector4(1246.3237, -1453.9513, 34.9354, 344.2509), + vector4(-289.3166, -1847.9614, 26.2498, 4.3302), + vector4(-45.8459, -1029.7800, 28.6224, 71.5370), + vector4(181.9603, -322.1017, 43.9382, 211.4422), + vector4(-514.8563, -260.6308, 35.5337, 211.8925), + vector4(-1284.6191, 297.2318, 64.9439, 154.2817), + vector4(-1440.0933, -773.8246, 23.4396, 343.2090), + } +} \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/core/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/core/client.lua new file mode 100644 index 0000000..9d7ae3b --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/core/client.lua @@ -0,0 +1,62 @@ +function CreateVeh(modelHash, ...) + RequestModel(modelHash) + while not HasModelLoaded(modelHash) do Wait(0) end + local veh = CreateVehicle(modelHash, ...) + SetModelAsNoLongerNeeded(modelHash) + return veh +end + +function CreateNPC(modelHash, ...) + RequestModel(modelHash) + while not HasModelLoaded(modelHash) do Wait(0) end + local ped = CreatePed(26, modelHash, ...) + SetModelAsNoLongerNeeded(modelHash) + return ped +end + +function CreateProp(modelHash, ...) + RequestModel(modelHash) + while not HasModelLoaded(modelHash) do Wait(0) end + local obj = CreateObject(modelHash, ...) + SetModelAsNoLongerNeeded(modelHash) + return obj +end + +function PlayAnim(ped, dict, ...) + RequestAnimDict(dict) + while not HasAnimDictLoaded(dict) do Wait(0) end + TaskPlayAnim(ped, dict, ...) +end + +function PlayEffect(dict, particleName, entity, off, rot, time, cb) + CreateThread(function() + RequestNamedPtfxAsset(dict) + while not HasNamedPtfxAssetLoaded(dict) do + Wait(0) + end + UseParticleFxAssetNextCall(dict) + Wait(10) + local particleHandle = StartParticleFxLoopedOnEntity(particleName, entity, off.x, off.y, off.z, rot.x, rot.y, rot.z, 1.0) + SetParticleFxLoopedColour(particleHandle, 0, 255, 0 , 0) + Wait(time) + StopParticleFxLooped(particleHandle, false) + cb() + end) +end + +function CreateBlip(data) + local x,y,z = table.unpack(data.Location) + local blip = AddBlipForCoord(x, y, z) + SetBlipSprite(blip, data.ID) + SetBlipDisplay(blip, data.Display) + SetBlipScale(blip, data.Scale) + SetBlipColour(blip, data.Color) + if (data.Rotation) then + SetBlipRotation(blip, math.ceil(data.Rotation)) + end + SetBlipAsShortRange(blip, true) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString(data.Label) + EndTextCommandSetBlipName(blip) + return blip +end \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/core/shared.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/core/shared.lua new file mode 100644 index 0000000..30e73a8 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/core/shared.lua @@ -0,0 +1,10 @@ +function v3(coords) return vec3(coords.x, coords.y, coords.z), coords.w end + +function GetRandomInt(min, max, exclude) + for i=1, 1000 do + local int = math.random(min, max) + if exclude == nil or exclude ~= int then + return int + end + end +end \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/fxmanifest.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/fxmanifest.lua new file mode 100644 index 0000000..3256f13 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/fxmanifest.lua @@ -0,0 +1,24 @@ +fx_version 'cerulean' +game "gta5" +version "v1.0.0" + +shared_scripts { + "@ox_lib/init.lua", + "config.lua", + "locales/locale.lua", + "locales/translations/da.lua", + "core/shared.lua" +} + +client_scripts { + "bridge/**/client.lua", + "modules/**/client.lua", + "core/client.lua" +} + +server_scripts { + "bridge/**/server.lua", + "modules/**/server.lua", +} + +lua54 'yes' \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/locale.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/locale.lua new file mode 100644 index 0000000..0cab5e5 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/locale.lua @@ -0,0 +1,14 @@ +Language = {} + +function _L(name, ...) + if name then + local str = Language[Config.Language][name] + if str then + return string.format(str, ...) + else + return "ERR_TRANSLATE_"..(name).."_404" + end + else + return "ERR_TRANSLATE_404" + end +end \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/translations/da.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/translations/da.lua new file mode 100644 index 0000000..9b0b48b --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/locales/translations/da.lua @@ -0,0 +1,26 @@ +Language["da"] = { + marker_interact_vehicle = "Tryk ~INPUT_CONTEXT~ for at åbne køretøjsmenuen.", + marker_remove_vehicle = "Tryk ~INPUT_CONTEXT~ for at parkere køretøjet.", + marker_interact_boss = "Tryk ~INPUT_CONTEXT~ for at åbne ledermenuen.", + marker_interact_duty = "Tryk ~INPUT_CONTEXT~ for at gå %s-duty.", + + vehicle_menu = "Køretøjsvalg", + vehicle_none = "Du har ingen køretøjer at vælge imellem.", + vehicle_stored = "Dit køretøj er blevet parkeret.", + vehicle_spawned = "Du er spawnet i arbejdskøretøjet.", + + no_access = "Du kan ikke gøre dette.", + duty_toggle = "Du er gået %s-duty hos %s.", + duty_forceoff = "Du gik hjem fra arbejde", + not_duty = "Du er ikke på arbejde.", + + taxi_occupied = "Der er en person i bilen, kør dem til deres destination før du starter et nyt job.", + taxi_pickup = "Hent personen der er markeret på din GPS.", + taxi_dropoff = "Aflever personen på den lokation der er markeret på din GPS.", + not_driver = "Du kører ikke en taxa.", + mission_fail = "Du har fejlet dit job.", + mission_success = "Du har fuldført ruten, og modtaget %s,-", + cancelled_mission = "Annullerede det nuværende job.", + taxi_pickup_blip = "Hent Kunde", + taxi_dropoff_blip = "Aflever Kunde", +} \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/client.lua new file mode 100644 index 0000000..945a11f --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/client.lua @@ -0,0 +1,109 @@ +STATUS = { + BUSINESS = nil, + DUTY = false +} + +function GetStatus() + return STATUS +end + +function SetDutyStatus(businessID, bool) + TriggerServerEvent("pickle_taxijob:setDutyStatus", businessID, bool) +end + +function OpenVehicleMenu(businessID) + local cfg = Config.Businesses[businessID] + if not CanAccessGroup(cfg.groups) then + return ShowNotification(_L("no_access")) + end + if not STATUS.DUTY then + return ShowNotification(_L("not_duty")) + end + local options = {} + for i=1, #cfg.vehicles do + if CanAccessGroup(cfg.vehicles[i].groups) then + table.insert(options, {label = cfg.vehicles[i].label, value = i}) + end + end + if #options < 1 then return ShowNotification(_L("vehicle_none")) end + lib.registerMenu({ + id = 'pickle_taxijob_vehicle', + title = _L("vehicle_menu"), + position = 'top-right', + options = options + }, function(selected, scrollIndex, args) + local ped = PlayerPedId() + local vehicleData = cfg.vehicles[options[selected].value] + local coords, heading = v3(cfg.locations.vehicle) + local vehicle = CreateVeh(vehicleData.model, coords.x, coords.y, coords.z, heading, true, true) + TaskWarpPedIntoVehicle(ped, vehicle, -1) + ShowNotification(_L("vehicle_spawned")) + end) + + lib.showMenu('pickle_taxijob_vehicle') +end + +function InteractLocation(businessID, locationID) + if locationID == "vehicle" then + local vehicle = GetVehiclePedIsIn(PlayerPedId()) + if vehicle ~= 0 then + TaskLeaveAnyVehicle(PlayerPedId()) + Wait(1500) + DeleteEntity(vehicle) + ShowNotification(_L("vehicle_stored")) + else + OpenVehicleMenu(businessID) + end + elseif locationID == "boss" then + AccessBossMenu(businessID) + elseif locationID == "duty" then + SetDutyStatus(businessID, not STATUS.DUTY) + end +end + +function DisplayHelp(businessID, locationID) + if locationID == "vehicle" then + if GetVehiclePedIsIn(PlayerPedId()) ~= 0 then + ShowHelpNotification(_L("marker_remove_vehicle")) + else + ShowHelpNotification(_L("marker_interact_vehicle")) + end + elseif locationID == "boss" then + ShowHelpNotification(_L("marker_interact_boss")) + elseif locationID == "duty" then + ShowHelpNotification(_L("marker_interact_duty", STATUS.DUTY and "hjem fra arbejde" or "på arbejde")) + end +end + +RegisterNetEvent("pickle_taxijob:onDutyUpdate", function(businessID, bool) + STATUS.BUSINESS = businessID + STATUS.DUTY = bool +end) + +CreateThread(function() + for i=1, #Config.Businesses do + if Config.Businesses[i].blip then + CreateBlip(Config.Businesses[i].blip) + end + end + while true do + local wait = 1000 + for i=1, #Config.Businesses do + local cfg = Config.Businesses[i] + local ped = PlayerPedId() + local pcoords = GetEntityCoords(ped) + for k,v in pairs(cfg.locations) do + local coords = v3(v) + local dist = #(coords - pcoords) + if (dist < 20) then + wait = 0 + DrawMarker(2, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 255, 255, 255, 127, false, true) + if (dist < 1.25 and not DisplayHelp(i, k) and IsControlJustPressed(1, 51)) then + InteractLocation(i, k) + end + end + end + end + Wait(wait) + end +end) \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/server.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/server.lua new file mode 100644 index 0000000..5acbc1f --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/business/server.lua @@ -0,0 +1,32 @@ +Players = {} + +function GetPlayer(source, createIfEmpty) + if Players[source] then + return Players[source] + elseif createIfEmpty then + Players[source] = {} + return Players[source] + end +end + +function SetDutyStatus(source, businessID, bool) + local player = GetPlayer(source, true) + Players[source].BUSINESS = businessID + Players[source].DUTY = bool + TriggerClientEvent("pickle_taxijob:onDutyUpdate", source, businessID, bool) +end + +RegisterNetEvent("pickle_taxijob:setDutyStatus", function(businessID, bool) + if type(businessID) ~= "boolean" then + local cfg = Config.Businesses[businessID] + if CanAccessGroup(cfg.groups) then + SetDutyStatus(source, businessID, bool) + ShowNotification(source, _L("duty_toggle", bool and "på arbejde" or "hjem fra arbejde", cfg.info.label)) + else + ShowNotification(source, _L("no_access")) + end + else + SetDutyStatus(source, nil, false) + ShowNotification(source, _L("duty_forceoff")) + end +end) \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/client.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/client.lua new file mode 100644 index 0000000..2ed42e9 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/client.lua @@ -0,0 +1,174 @@ +local blip +local mission + +function Destination(text, coords) + if blip then + RemoveBlip(blip) + end + if not text then + return + end + blip = CreateBlip({ + Location = coords, + Label = text, + ID = 1, + Display = 4, + Color = 5, + Scale = 0.75 + }) + SetBlipRoute(blip, true) + SetBlipRouteColour(blip, 5) + return blip +end + +function IsVehicleTaxi(vehicle, list) + local model = GetEntityModel(vehicle) + for i=1, #list do + if model == list[i].model then + return true + end + end +end + +function StartMission(lastIndex) + if not STATUS.DUTY then + return ShowNotification(_L("not_duty")) + end + local business = Config.Businesses[STATUS.BUSINESS] + local cfg = Config.Missions + mission = {} + mission.from = GetRandomInt(1, #cfg.locations, lastIndex) + mission.to = GetRandomInt(1, #cfg.locations, mission.from) + mission.model = cfg.models[GetRandomInt(1, #cfg.models)] + mission.ped = nil + mission.taxi = GetVehiclePedIsIn(PlayerPedId()) + mission.status = "pickup" + + if GetPedInVehicleSeat(mission.taxi, 2) ~= 0 then + return ShowNotification(_L("taxi_occupied")) + end + + if GetPedInVehicleSeat(mission.taxi, -1) ~= PlayerPedId() or not IsVehicleTaxi(mission.taxi, business.vehicles) then + return ShowNotification(_L("not_driver")) + end + + if (mission and mission.status == "pickup") then + local coords, heading = v3(cfg.locations[mission.from]) + local enteringVehicle = false + + ShowNotification(_L("taxi_pickup")) + Destination(_L("taxi_pickup_blip"), coords) + + while mission and mission.status == "pickup" do + local wait = 1000 + local ped = PlayerPedId() + local pedCoords = GetEntityCoords(ped) + local dist = #(coords - pedCoords) + if (not DoesEntityExist(mission.taxi) or GetEntityHealth(mission.taxi) == 0) then + mission.status = "fail" + end + if (dist < 60.0) then + if not mission.ped then + enteringVehicle = false + mission.ped = CreateNPC(mission.model, coords.x, coords.y, coords.z, heading, true, true) + else + if IsEntityDead(mission.ped) then + mission.status = "fail" + end + if (dist < 10.0 and not enteringVehicle) then + enteringVehicle = true + TaskEnterVehicle(mission.ped, mission.taxi, -1, 2, 2.0, 1, 0) + elseif GetVehiclePedIsIn(mission.ped) == mission.taxi then + mission.status = "dropoff" + end + end + elseif mission.ped then + DeleteEntity(mission.ped) + mission.ped = nil + end + Wait(wait) + end + end + + if (mission and mission.status == "dropoff") then + local coords, heading = v3(cfg.locations[mission.to]) + local exitingVehicle = false + + ShowNotification(_L("taxi_dropoff")) + Destination(_L("taxi_dropoff_blip"), coords) + + while mission and mission.status == "dropoff" do + local wait = 1000 + local ped = PlayerPedId() + local pedCoords = GetEntityCoords(ped) + local dist = #(coords - pedCoords) + + if (not DoesEntityExist(mission.taxi) or GetEntityHealth(mission.taxi) == 0) then + mission.status = "fail" + end + if (not exitingVehicle and GetVehiclePedIsIn(mission.ped) ~= mission.taxi) or (not DoesEntityExist(mission.ped) or IsEntityDead(mission.ped)) then + mission.status = "fail" + end + if (dist < 5.0 and not exitingVehicle) then + exitingVehicle = true + TaskLeaveAnyVehicle(mission.ped, 1, 1) + elseif exitingVehicle and GetVehiclePedIsIn(mission.ped) ~= mission.taxi then + mission.status = "success" + end + Wait(wait) + end + end + + Destination() + + if (mission and mission.status == "success") then + for i=-1, 4 do + SetVehicleDoorShut(mission.taxi, i, false) + end + + ServerCallback("pickle_taxijob:npcMissionComplete", function(result) + if result then + local ped = mission.ped + TaskWanderStandard(ped, 1, 1) + SetTimeout(5000, function() + DeleteEntity(ped) + end) + else + ShowNotification(_L("mission_fail")) + end + if cfg.loop then + StartMission(mission.to) + else + mission = nil + end + end, mission.from, mission.to) + elseif (mission) then + for i=-1, 4 do + SetVehicleDoorShut(mission.taxi, i, false) + end + ShowNotification(_L("mission_fail")) + if cfg.loop then + StartMission(mission.to) + else + mission = nil + end + end +end + +function StopMission() + local _mission = mission + mission = nil + if _mission.ped then + DeleteEntity(_mission.ped) + end + Destination() + ShowNotification(_L("cancelled_mission")) +end + +RegisterCommand("taxijob", function() + if mission then + StopMission() + else + StartMission() + end +end) \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/server.lua b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/server.lua new file mode 100644 index 0000000..535bad2 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/pickle_taxijob/modules/mission/server.lua @@ -0,0 +1,19 @@ +RegisterCallback("pickle_taxijob:npcMissionComplete", function(source, cb, from, to) + local player = GetPlayer(source, true) + local cfg = Config.Missions + local coords = { + from = v3(cfg.locations[from]), + to = v3(cfg.locations[to]), + } + local dist = #(coords.from - coords.to) + if (player.DUTY) then + local amount = math.random(cfg.reward.min, cfg.reward.max) + local multi = cfg.reward.miles * (dist / 1000) + amount = math.ceil(amount * multi) + AddItem(source, cfg.reward.name, amount) + ShowNotification(source, _L("mission_success", amount)) + cb(true) + else + cb(false) + end +end) \ No newline at end of file diff --git a/resources/[qb]/[qb_jobs]/qb-ambulancejob/LICENSE b/resources/[qb]/[qb_jobs]/qb-ambulancejob/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/resources/[qb]/[qb_jobs]/qb-ambulancejob/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc.No result
+MODEL: COSAGNETTI
+Spanish Ave | Lagunas Pl
+PLATE: 01AGB123
+420 KM/U
+No result
"); +} + +Fingerprint.Close = function() { + $(".fingerprint-container").fadeOut(150); + $.post('https://qb-policejob/closeFingerprint'); +} + +Fingerprint.Update = function(data) { + $(".fingerprint-id").html("Fingerprint ID"+data.fingerprintId+"
"); +} + +$(document).on('click', '.take-fingerprint', function(){ + $.post('https://qb-policejob/doFingerScan'); +}) + +document.onreadystatechange = () => { + if (document.readyState === "complete") { + window.addEventListener('message', function(event) { + + if (event.data.type == "enablecam") { + CameraApp.OpenCameras(event.data.label, event.data.connected, event.data.id, event.data.time); + } else if (event.data.type == "disablecam") { + CameraApp.CloseCameras(); + } else if (event.data.type == "updatecam") { + CameraApp.UpdateCameraLabel(event.data.label); + } else if (event.data.type == "updatecamtime") { + CameraApp.UpdateCameraTime(event.data.time); + } else if (event.data.type == "heliopen") { + HeliCam.Open(event.data); + } else if (event.data.type == "heliclose") { + HeliCam.Close(); + } else if (event.data.type == "heliscan") { + HeliCam.UpdateScan(event.data); + } else if (event.data.type == "heliupdateinfo") { + HeliCam.UpdateVehicleInfo(event.data); + } else if (event.data.type == "disablescan") { + HeliCam.DisableVehicleInfo(); + } else if (event.data.type == "databank") { + Databank.Open(); + } else if (event.data.type == "closedatabank") { + Databank.Close(); + } else if (event.data.type == "fingerprintOpen") { + Fingerprint.Open(); + } else if (event.data.type == "fingerprintClose") { + Fingerprint.Close(); + } else if (event.data.type == "updateFingerprintId") { + Fingerprint.Update(event.data); + } + }); + }; +}; + +$(document).on('keydown', function() { + switch(event.keyCode) { + case 27: // ESC + Databank.Close(); + Fingerprint.Close(); + break; + } +}); diff --git a/resources/[qb]/[qb_jobs]/qb-policejob/html/tablet-frame.png b/resources/[qb]/[qb_jobs]/qb-policejob/html/tablet-frame.png new file mode 100644 index 0000000..3ed34e5 Binary files /dev/null and b/resources/[qb]/[qb_jobs]/qb-policejob/html/tablet-frame.png differ diff --git a/resources/[qb]/[qb_jobs]/qb-policejob/html/vcr-ocd.ttf b/resources/[qb]/[qb_jobs]/qb-policejob/html/vcr-ocd.ttf new file mode 100644 index 0000000..dcca687 Binary files /dev/null and b/resources/[qb]/[qb_jobs]/qb-policejob/html/vcr-ocd.ttf differ diff --git a/resources/[qb]/[qb_jobs]/qb-policejob/html/vue.min.js b/resources/[qb]/[qb_jobs]/qb-policejob/html/vue.min.js new file mode 100644 index 0000000..836793b --- /dev/null +++ b/resources/[qb]/[qb_jobs]/qb-policejob/html/vue.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.5.13 + * (c) 2014-2017 Evan You + * Released under the MIT License. + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vue=e()}(this,function(){"use strict";function t(t){return void 0===t||null===t}function e(t){return void 0!==t&&null!==t}function n(t){return!0===t}function r(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function i(t){return null!==t&&"object"==typeof t}function o(t){return"[object Object]"===Nn.call(t)}function a(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function s(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function c(t){var e=parseFloat(t);return isNaN(e)?t:e}function u(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i