local HasAlreadyEnteredMarker, OnJob, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, IsDead, CurrentActionData = false, false, false, false, false, false, {} local CurrentCustomer, CurrentCustomerBlip, DestinationBlip, targetCoords, LastZone, CurrentAction, CurrentActionMsg ESX = nil function DrawSub(msg, time) ClearPrints() BeginTextCommandPrint('STRING') AddTextComponentSubstringPlayerName(msg) EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) Citizen.CreateThread(function() Citizen.Wait(0) BeginTextCommandBusyString('STRING') AddTextComponentSubstringPlayerName(msg) EndTextCommandBusyString(type) Citizen.Wait(time) RemoveLoadingPrompt() end) end function GetRandomWalkingNPC() local search = {} local peds = ESX.Game.GetPeds() for i=1, #peds, 1 do if IsPedHuman(peds[i]) and IsPedWalking(peds[i]) and not IsPedAPlayer(peds[i]) then table.insert(search, peds[i]) end end if #search > 0 then return search[GetRandomIntInRange(1, #search)] end for i=1, 250, 1 do local ped = GetRandomPedAtCoord(0.0, 0.0, 0.0, math.huge + 0.0, math.huge + 0.0, math.huge + 0.0, 26) if DoesEntityExist(ped) and IsPedHuman(ped) and IsPedWalking(ped) and not IsPedAPlayer(ped) then table.insert(search, ped) end end if #search > 0 then return search[GetRandomIntInRange(1, #search)] end end function ClearCurrentMission() if DoesBlipExist(CurrentCustomerBlip) then RemoveBlip(CurrentCustomerBlip) end if DoesBlipExist(DestinationBlip) then RemoveBlip(DestinationBlip) end CurrentCustomer = nil CurrentCustomerBlip = nil DestinationBlip = nil IsNearCustomer = false CustomerIsEnteringVehicle = false CustomerEnteredVehicle = false targetCoords = nil end function StartTaxiJob() ShowLoadingPromt(_U('taking_service'), 5000, 3) ClearCurrentMission() OnJob = true end function StopTaxiJob() local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) and CurrentCustomer ~= nil then local vehicle = GetVehiclePedIsIn(playerPed, false) TaskLeaveVehicle(CurrentCustomer, vehicle, 0) if CustomerEnteredVehicle then TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, 1.0, -1, 0.0, 0.0) end end ClearCurrentMission() OnJob = false DrawSub(_U('mission_complete'), 5000) end function OpenCloakroom() ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_cloakroom', { title = _U('cloakroom_menu'), align = 'top-left', elements = { { label = _U('wear_citizen'), value = 'wear_citizen' }, { label = _U('wear_work'), value = 'wear_work'} } }, function(data, menu) if data.current.value == 'wear_citizen' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) TriggerEvent('skinchanger:loadSkin', skin) end) elseif data.current.value == 'wear_work' then ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) if skin.sex == 0 then TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) else TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) end end) end end, function(data, menu) menu.close() CurrentAction = 'cloakroom' CurrentActionMsg = _U('cloakroom_prompt') CurrentActionData = {} end) end function OpenVehicleSpawnerMenu() ESX.UI.Menu.CloseAll() local elements = {} if Config.EnableSocietyOwnedVehicles then ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) for i=1, #vehicles, 1 do table.insert(elements, { label = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', value = vehicles[i] }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { title = _U('spawn_veh'), align = 'top-left', elements = elements }, function(data, menu) if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then ESX.ShowNotification(_U('spawnpoint_blocked')) return end menu.close() local vehicleProps = data.current.value ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, Config.Zones.VehicleSpawnPoint.Heading, function(vehicle) ESX.Game.SetVehicleProperties(vehicle, vehicleProps) local playerPed = PlayerPedId() TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) TriggerServerEvent('esx_society:removeVehicleFromGarage', 'taxi', vehicleProps) end, function(data, menu) CurrentAction = 'vehicle_spawner' CurrentActionMsg = _U('spawner_prompt') CurrentActionData = {} menu.close() end) end, 'taxi') else -- not society vehicles ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', { title = _U('spawn_veh'), align = 'top-left', elements = Config.AuthorizedVehicles }, function(data, menu) if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then ESX.ShowNotification(_U('spawnpoint_blocked')) return end menu.close() ESX.Game.SpawnVehicle(data.current.model, Config.Zones.VehicleSpawnPoint.Pos, Config.Zones.VehicleSpawnPoint.Heading, function(vehicle) local playerPed = PlayerPedId() TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) end, function(data, menu) CurrentAction = 'vehicle_spawner' CurrentActionMsg = _U('spawner_prompt') CurrentActionData = {} menu.close() end) end end function DeleteJobVehicle() local playerPed = PlayerPedId() if Config.EnableSocietyOwnedVehicles then local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) TriggerServerEvent('esx_society:putVehicleInGarage', 'taxi', vehicleProps) ESX.Game.DeleteVehicle(CurrentActionData.vehicle) else if IsInAuthorizedVehicle() then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) if Config.MaxInService ~= -1 then TriggerServerEvent('esx_service:disableService', 'taxi') end else ESX.ShowNotification(_U('only_taxi')) end end end function OpenTaxiActionsMenu() local elements = { {label = _U('deposit_stock'), value = 'put_stock'}, {label = _U('take_stock'), value = 'get_stock'} } if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == 'boss' then table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) end ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'taxi_actions', { title = 'Taxi', align = 'top-left', elements = elements }, function(data, menu) if data.current.value == 'put_stock' then OpenPutStocksMenu() elseif data.current.value == 'get_stock' then OpenGetStocksMenu() elseif data.current.value == 'boss_actions' then TriggerEvent('esx_society:openBossMenu', 'taxi', function(data, menu) menu.close() end) end end, function(data, menu) menu.close() CurrentAction = 'taxi_actions_menu' CurrentActionMsg = _U('press_to_open') CurrentActionData = {} end) end function OpenMobileTaxiActionsMenu() ESX.UI.Menu.CloseAll() ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'mobile_taxi_actions', { title = 'Taxi', align = 'top-left', elements = { {label = _U('billing'), value = 'billing'}, {label = _U('start_job'), value = 'start_job'} }}, function(data, menu) if data.current.value == 'billing' then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', { title = _U('invoice_amount') }, function(data, menu) local amount = tonumber(data.value) if amount == nil then ESX.ShowNotification(_U('amount_invalid')) else menu.close() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then ESX.ShowNotification(_U('no_players_near')) else TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', 'Taxi', amount) ESX.ShowNotification(_U('billing_sent')) end end end, function(data, menu) menu.close() end) elseif data.current.value == 'start_job' then if OnJob then StopTaxiJob() else if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'taxi' then local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then if tonumber(ESX.PlayerData.job.grade) >= 3 then StartTaxiJob() else if IsInAuthorizedVehicle() then StartTaxiJob() else ESX.ShowNotification(_U('must_in_taxi')) end end else if tonumber(ESX.PlayerData.job.grade) >= 3 then ESX.ShowNotification(_U('must_in_vehicle')) else ESX.ShowNotification(_U('must_in_taxi')) end end end end end end, function(data, menu) menu.close() end) end function IsInAuthorizedVehicle() local playerPed = PlayerPedId() local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) for i=1, #Config.AuthorizedVehicles, 1 do if vehModel == GetHashKey(Config.AuthorizedVehicles[i].model) then return true end end return false end function OpenGetStocksMenu() ESX.TriggerServerCallback('esx_taxijob:getStockItems', function(items) local elements = {} for i=1, #items, 1 do table.insert(elements, { label = 'x' .. items[i].count .. ' ' .. items[i].label, value = items[i].name }) end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = 'Taxi Stock', align = 'top-left', elements = elements }, function(data, menu) local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { title = _U('quantity') }, function(data2, menu2) local count = tonumber(data2.value) if count == nil then ESX.ShowNotification(_U('quantity_invalid')) else menu2.close() menu.close() -- todo: refresh on callback TriggerServerEvent('esx_taxijob:getStockItem', itemName, count) Citizen.Wait(1000) OpenGetStocksMenu() end end, function(data2, menu2) menu2.close() end) end, function(data, menu) menu.close() end) end) end function OpenPutStocksMenu() ESX.TriggerServerCallback('esx_taxijob:getPlayerInventory', function(inventory) local elements = {} for i=1, #inventory.items, 1 do local item = inventory.items[i] if item.count > 0 then table.insert(elements, { label = item.label .. ' x' .. item.count, type = 'item_standard', -- not used value = item.name }) end end ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { title = _U('inventory'), align = 'top-left', elements = elements }, function(data, menu) local itemName = data.current.value ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { title = _U('quantity') }, function(data2, menu2) local count = tonumber(data2.value) if count == nil then ESX.ShowNotification(_U('quantity_invalid')) else menu2.close() menu.close() -- todo: refresh on callback TriggerServerEvent('esx_taxijob:putStockItems', itemName, count) Citizen.Wait(1000) OpenPutStocksMenu() end end, function(data2, menu2) menu2.close() end) end, function(data, menu) menu.close() end) end) end Citizen.CreateThread(function() RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function (xPlayer) while ESX == nil do Citizen.Wait(0) end ESX.PlayerData = xPlayer end) end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) ESX.PlayerData.job = job end) AddEventHandler('esx_taxijob:hasEnteredMarker', function(zone) if zone == 'VehicleSpawner' then CurrentAction = 'vehicle_spawner' CurrentActionMsg = _U('spawner_prompt') CurrentActionData = {} elseif zone == 'VehicleDeleter' then local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then CurrentAction = 'delete_vehicle' CurrentActionMsg = _U('store_veh') CurrentActionData = { vehicle = vehicle } end elseif zone == 'TaxiActions' then CurrentAction = 'taxi_actions_menu' CurrentActionMsg = _U('press_to_open') CurrentActionData = {} elseif zone == 'Cloakroom' then CurrentAction = 'cloakroom' CurrentActionMsg = _U('cloakroom_prompt') CurrentActionData = {} end end) AddEventHandler('esx_taxijob:hasExitedMarker', function(zone) ESX.UI.Menu.CloseAll() CurrentAction = nil end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) local specialContact = { name = _U('phone_taxi'), number = 'taxi', base64Icon = 'data:image/png;base64,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', } TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Create Blips Citizen.CreateThread(function() local blip = AddBlipForCoord(Config.Zones.TaxiActions.Pos.x, Config.Zones.TaxiActions.Pos.y, Config.Zones.TaxiActions.Pos.z) SetBlipSprite (blip, 198) SetBlipDisplay(blip, 4) SetBlipScale (blip, 1.0) SetBlipColour (blip, 5) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName(_U('blip_taxi')) EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers Citizen.CreateThread(function() while true do Citizen.Wait(0) if ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then local coords = GetEntityCoords(PlayerPedId()) local isInMarker, letSleep, currentZone = false, true for k,v in pairs(Config.Zones) do local distance = GetDistanceBetweenCoords(coords, v.Pos.x, v.Pos.y, v.Pos.z, true) if v.Type ~= -1 and distance < Config.DrawDistance then letSleep = false DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, false, 2, v.Rotate, nil, nil, false) end if distance < v.Size.x then isInMarker, currentZone = true, k end end if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then HasAlreadyEnteredMarker, LastZone = true, currentZone TriggerEvent('esx_taxijob:hasEnteredMarker', currentZone) end if not isInMarker and HasAlreadyEnteredMarker then HasAlreadyEnteredMarker = false TriggerEvent('esx_taxijob:hasExitedMarker', LastZone) end if letSleep then Citizen.Wait(500) end else Citizen.Wait(1000) end end end) -- Taxi Job Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerPed = PlayerPedId() if OnJob then if CurrentCustomer == nil then DrawSub(_U('drive_search_pass'), 5000) if IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then local waitUntil = GetGameTimer() + GetRandomIntInRange(30000, 45000) while OnJob and waitUntil > GetGameTimer() do Citizen.Wait(0) end if OnJob and IsPedInAnyVehicle(playerPed, false) and GetEntitySpeed(playerPed) > 0 then CurrentCustomer = GetRandomWalkingNPC() if CurrentCustomer ~= nil then CurrentCustomerBlip = AddBlipForEntity(CurrentCustomer) SetBlipAsFriendly(CurrentCustomerBlip, true) SetBlipColour(CurrentCustomerBlip, 2) SetBlipCategory(CurrentCustomerBlip, 3) SetBlipRoute(CurrentCustomerBlip, true) SetEntityAsMissionEntity(CurrentCustomer, true, false) ClearPedTasksImmediately(CurrentCustomer) SetBlockingOfNonTemporaryEvents(CurrentCustomer, true) local standTime = GetRandomIntInRange(60000, 180000) TaskStandStill(CurrentCustomer, standTime) ESX.ShowNotification(_U('customer_found')) end end end else if IsPedFatallyInjured(CurrentCustomer) then ESX.ShowNotification(_U('client_unconcious')) if DoesBlipExist(CurrentCustomerBlip) then RemoveBlip(CurrentCustomerBlip) end if DoesBlipExist(DestinationBlip) then RemoveBlip(DestinationBlip) end SetEntityAsMissionEntity(CurrentCustomer, false, true) CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end if IsPedInAnyVehicle(playerPed, false) then local vehicle = GetVehiclePedIsIn(playerPed, false) local playerCoords = GetEntityCoords(playerPed) local customerCoords = GetEntityCoords(CurrentCustomer) local customerDistance = #(playerCoords - customerCoords) if IsPedSittingInVehicle(CurrentCustomer, vehicle) then if CustomerEnteredVehicle then local targetDistance = #(playerCoords - targetCoords) if targetDistance <= 10.0 then TaskLeaveVehicle(CurrentCustomer, vehicle, 0) ESX.ShowNotification(_U('arrive_dest')) TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, 1.0, -1, 0.0, 0.0) SetEntityAsMissionEntity(CurrentCustomer, false, true) TriggerServerEvent('esx_taxijob:success') RemoveBlip(DestinationBlip) local scope = function(customer) ESX.SetTimeout(60000, function() DeletePed(customer) end) end scope(CurrentCustomer) CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end if targetCoords then DrawMarker(36, targetCoords.x, targetCoords.y, targetCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) end else RemoveBlip(CurrentCustomerBlip) CurrentCustomerBlip = nil targetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] local distance = #(playerCoords - targetCoords) while distance < Config.MinimumDistance do Citizen.Wait(5) targetCoords = Config.JobLocations[GetRandomIntInRange(1, #Config.JobLocations)] distance = #(playerCoords - targetCoords) end local street = table.pack(GetStreetNameAtCoord(targetCoords.x, targetCoords.y, targetCoords.z)) local msg = nil if street[2] ~= 0 and street[2] ~= nil then msg = string.format(_U('take_me_to_near', GetStreetNameFromHashKey(street[1]), GetStreetNameFromHashKey(street[2]))) else msg = string.format(_U('take_me_to', GetStreetNameFromHashKey(street[1]))) end ESX.ShowNotification(msg) DestinationBlip = AddBlipForCoord(targetCoords.x, targetCoords.y, targetCoords.z) BeginTextCommandSetBlipName('STRING') AddTextComponentSubstringPlayerName('Destination') EndTextCommandSetBlipName(blip) SetBlipRoute(DestinationBlip, true) CustomerEnteredVehicle = true end else DrawMarker(36, customerCoords.x, customerCoords.y, customerCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) if not CustomerEnteredVehicle then if customerDistance <= 40.0 then if not IsNearCustomer then ESX.ShowNotification(_U('close_to_client')) IsNearCustomer = true end end if customerDistance <= 20.0 then if not CustomerIsEnteringVehicle then ClearPedTasksImmediately(CurrentCustomer) local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat then TaskEnterVehicle(CurrentCustomer, vehicle, -1, freeSeat, 2.0, 0) CustomerIsEnteringVehicle = true end end end end end else DrawSub(_U('return_to_veh'), 5000) end end else Citizen.Wait(500) end end end) -- Key Controls Citizen.CreateThread(function() while true do Citizen.Wait(0) if CurrentAction and not IsDead then ESX.ShowHelpNotification(CurrentActionMsg) if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then if CurrentAction == 'taxi_actions_menu' then OpenTaxiActionsMenu() elseif CurrentAction == 'cloakroom' then OpenCloakroom() elseif CurrentAction == 'vehicle_spawner' then OpenVehicleSpawnerMenu() elseif CurrentAction == 'delete_vehicle' then DeleteJobVehicle() end CurrentAction = nil end end if IsControlJustReleased(0, 167) and IsInputDisabled(0) and not IsDead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then OpenMobileTaxiActionsMenu() end end end) AddEventHandler('esx:onPlayerDeath', function() IsDead = true end) AddEventHandler('playerSpawned', function(spawn) IsDead = false end)
Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.4. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.
OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.
name = io.read("*a")
print ("Hello ", name)
Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.
-- global variables
a = 10
-- local variables
local x = 30
Value Type | Description |
---|---|
number | Represents numbers |
string | Represents text |
nil | Differentiates values whether it has data or not |
boolean | Value can be either true or false |
function | Represents a sub-routine |
userdata | Represents arbitary C data |
thread | Represents independent threads of execution. |
table | Can hold any value except nil |
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while(condition)
do
--code
end
Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.
repeat
--code
until( condition )
For loop is used to iterate a set of statements based on a condition.
for init,max/min value, increment
do
--code
end
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.
optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end