do a pull request and either i could make it configurable what items you could have, but do an pr and see if i can make it better or i just merge it.
Fantastic script, only issue is that it is easily abusable. Find to trash cans, push them close together, run between them and get infinite bottles. Very hard to balance around this.
Is there a same script but LUA?
This is lua?
Ye, this is in lua?
Where can I edit esx_jobs so that you donāt need the job from the job center to start working like your script?
What? This is not associated with esx_jobs.
Yes but do you know how I can make for example the lumberjack job working without taking the job in the job center?
Whitelist it and set the job on you??
No I mean that I can do for example the miner or lumberjack job with for example the police job.
I only want to knok how I can do that the job blips are shown on the map all the time and I can do jobs like miner, slaughter or lumberjack as a employed people.
Um hi, I added this to my server and put the sql in my data base and its not working. Can you tell me anything i could have done wrong?
Update
- Major performance fix.
- Fixed formatting.
- Fixed configurable things in the
config.lua
I hope i can help improve this incredible nice script.
Feel free to comment if my additions are welcome.
Below are allmost all trashcans extracted from all props available in the game.
Please add this into the āconfig.luaā of esx-ecobottles:
Config.BinsAvailable = {
"v_serv_tc_bin1_",
"v_serv_tc_bin2_",
"prop_cs_bin_02",
"prop_cs_bin_03",
"prop_cs_rub_binbag_01",
"prop_fbibombbin",
"prop_ld_binbag_01",
"prop_ld_rub_binbag_01",
"prop_rub_binbag_sd_01",
"prop_rub_binbag_sd_02",
"prop_cs_street_binbag_01",
"prop_snow_bin_01",
"prop_snow_bin_02",
"p_rub_binbag_test",
"prop_rub_binbag_01",
"prop_rub_binbag_01b",
"prop_rub_binbag_03",
"prop_rub_binbag_03b",
"prop_rub_binbag_04",
"prop_rub_binbag_05",
"prop_rub_binbag_06",
"prop_rub_binbag_08",
"prop_gas_smallbin01",
"prop_bin_01a",
"prop_bin_02a",
"prop_bin_03a",
"prop_bin_04a",
"prop_bin_05a",
"prop_bin_06a",
"prop_bin_07a",
"prop_bin_07b",
"prop_bin_07c",
"prop_bin_07d",
"prop_bin_08a",
"prop_bin_08open",
"prop_bin_09a",
"prop_bin_10a",
"prop_bin_10b",
"prop_bin_11a",
"prop_bin_11b",
"prop_bin_12a",
"prop_bin_13a",
"prop_bin_14a",
"prop_bin_14b",
"prop_bin_beach_01a",
"prop_bin_beach_01d",
"prop_bin_delpiero",
"prop_bin_delpiero_b",
"prop_recyclebin_01a",
"prop_recyclebin_02_c",
"prop_recyclebin_02_d",
"prop_recyclebin_02a",
"prop_recyclebin_02b",
"prop_recyclebin_03_a",
"prop_recyclebin_04_a",
"prop_recyclebin_04_b",
"prop_recyclebin_05_a",
"zprop_bin_01a_old"
}
Another hopefull contribution, since the trashcan list is long and I noticed it lags on the server. With my little fresh gained knowledge of LUA scripting, Iāve altered the script to be far more efficient and never takes framerate hits anymore (which was over 25 fps):
Below is the client side main.lua script and only the part to optimize.
Please use it in the next update if your tests also give better performance.
Note: my optimization is that by using only the player coords and one entity coords instead of checking the whole list every update cycle, the fps gain is huge. Before my update I noticed FiveM warnings about >25fps drops and after no fps drops.
Citizen.CreateThread(function()
Citizen.Wait(100)
while true do
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local entity, entityDst = ESX.Game.GetClosestObject(Config.BinsAvailable)
local binCoords = GetEntityCoords(entity)
if DoesEntityExist(entity) then
while GetDistanceBetweenCoords(playerCoords,binCoords) <= 1.0 do
binCoords = GetEntityCoords(entity)
playerCoords = GetEntityCoords(playerPed)
ESX.Game.Utils.DrawText3D(binCoords + vector3(0.0, 0.0, 0.5), "[~g~E~s~] Search Trashbin", 0.4)
if IsControlJustReleased(0, 38) then
if not cachedBins[entity] then
cachedBins[entity] = true
OpenTrashCan()
else
ESX.ShowNotification("You've already searched this bin!")
end
end
Citizen.Wait(0)
end
end
Citizen.Wait(1000)
end
end)
Another note:
After my just posted optimization and some ingame testing on my server, I noticed the script now remembers a lot of previous searched trashbins. So exploiting the script by pulling a bunch of trashbins together and hop from one to a previous one does not work anymore
All reactions are welcome and I hope I can be of any help.
Can I add tools before work?
thank you very much probe the code you put and really there is a very good improvement in both performance and fuides, the eco bottle came to a point that with 3-2 people reach 4-6ms
now there are estalas 0.27 -0.50
a way to implement that apart from the fact that ābottleā comes out when you search in a container, you also get a āweapon_bottleā?
iām stuck in the same, I wish to add WEAPON_BOTTLE with
GiveWeaponToPed(GetPlayerPed(-1), GetHashKey("WEAPON_BOTTLE"), false, true)
but when it comes to the math, it throw me this error:
Error running system event handling function for resource esx-ecobottles: citizen:/scripting/lua/scheduler.lua:41: Failed to execute thread: @esx-ecobottles/server/main.lua:34: attempt to call a nil value (global 'PlayerPedId')
stack traceback:
@esx-ecobottles/server/main.lua:34: in upvalue 'handler'
citizen:/scripting/lua/scheduler.lua:219: in function <citizen:/scripting/lua/scheduler.lua:218>
stack traceback:
[C]: in function 'error'
citizen:/scripting/lua/scheduler.lua:41: in field 'CreateThreadNow'
citizen:/scripting/lua/scheduler.lua:218: in function <citizen:/scripting/lua/scheduler.lua:182>
This is my client.lua -->
ESX = nil
local cachedBins = {}
Citizen.CreateThread(function ()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj)
ESX = obj
end)
Citizen.Wait(5)
end
end)
Citizen.CreateThread(function()
Citizen.Wait(100)
for locationIndex = 1, #Config.SellBottleLocations do
local locationPos = Config.SellBottleLocations[locationIndex]
local blip = AddBlipForCoord(locationPos)
SetBlipSprite (blip, 409)
SetBlipDisplay(blip, 4)
SetBlipScale (blip, 0.8)
SetBlipColour (blip, 48)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString("Vender Botellas Vacias")
EndTextCommandSetBlipName(blip)
end
while true do
local sleepThread = 500
local ped = PlayerPedId()
local pedCoords = GetEntityCoords(ped)
for locationIndex = 1, #Config.SellBottleLocations do
local locationPos = Config.SellBottleLocations[locationIndex]
local dstCheck = GetDistanceBetweenCoords(pedCoords, locationPos, true)
if dstCheck <= 5.0 then
sleepThread = 5
local text = "Vender Botellas Vacias"
if dstCheck <= 1.5 then
text = "[~g~E~s~] " .. text
if IsControlJustReleased(0, 38) then
TriggerServerEvent("esx-ecobottles:sellBottles")
end
end
ESX.Game.Utils.DrawText3D(locationPos, text, 0.8)
end
end
Citizen.Wait(sleepThread)
end
end)
Citizen.CreateThread(function()
Citizen.Wait(100)
while true do
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local entity, entityDst = ESX.Game.GetClosestObject(Config.BinsAvailable)
local binCoords = GetEntityCoords(entity)
if DoesEntityExist(entity) then
while GetDistanceBetweenCoords(playerCoords,binCoords) <= 2.0 do
binCoords = GetEntityCoords(entity)
playerCoords = GetEntityCoords(playerPed)
ESX.Game.Utils.DrawText3D(binCoords + vector3(0.0, 0.0, 0.5), "[~g~E~s~] Revisar basura", 0.8)
if IsControlJustReleased(0, 38) then
if not cachedBins[entity] then
cachedBins[entity] = true
OpenTrashCan()
else
ESX.ShowNotification("~r~Ya revisaste esta basura!")
end
end
Citizen.Wait(0)
end
end
Citizen.Wait(1000)
end
end)
-- Citizen.CreateThread(function()
-- Citizen.Wait(100)
-- while true do
-- local sleepThread = 1000
-- local entity, entityDst = ESX.Game.GetClosestObject(Config.BinsAvailable)
-- if DoesEntityExist(entity) and entityDst <= 2.0 then
-- sleepThread = 5
-- local binCoords = GetEntityCoords(entity)
-- ESX.Game.Utils.DrawText3D(binCoords + vector3(0.0, 0.0, 0.5), "[~g~E~s~] Revisar basura", 0.8)
-- if IsControlJustReleased(0, 38) then
-- if not cachedBins[entity] then
-- cachedBins[entity] = true
-- OpenTrashCan()
-- else
-- ESX.ShowNotification("Ya revisaste esta basura!")
-- end
-- end
-- end
-- Citizen.Wait(sleepThread)
-- end
-- end)
function OpenTrashCan()
TaskStartScenarioInPlace(PlayerPedId(), "PROP_HUMAN_BUM_BIN", 0, true)
Citizen.Wait(10000)
TriggerServerEvent("esx-ecobottles:retrieveBottle")
ClearPedTasks(PlayerPedId())
end
Server.lua ā>
local ESX = nil
TriggerEvent("esx:getSharedObject", function(obj)
ESX = obj
end)
RegisterServerEvent("esx-ecobottles:sellBottles")
AddEventHandler("esx-ecobottles:sellBottles", function()
local player = ESX.GetPlayerFromId(source)
local currentBottles = player.getInventoryItem("bottle")["count"]
if currentBottles > 0 then
math.randomseed(os.time())
local randomMoney = math.random((Config.BottleReward[1] or 10), (Config.BottleReward[2] or 40))
player.removeInventoryItem("bottle", currentBottles)
player.addMoney(randomMoney * currentBottles)
TriggerClientEvent("esx:showNotification", source, ("Entregaste al local %s botellas y recibiste como pago $%s."):format(currentBottles, currentBottles * randomMoney))
else
TriggerClientEvent("esx:showNotification", source, "No tenes botellas vacias para entregarle al local.")
end
end)
RegisterServerEvent("esx-ecobottles:retrieveBottle")
AddEventHandler("esx-ecobottles:retrieveBottle", function()
local player = ESX.GetPlayerFromId(source)
math.randomseed(os.time())
local luck = math.random(0, 100)
local randomBottle = math.random((Config.BottleRecieve[1] or 1), (Config.BottleRecieve[2] or 6))
local randomBandage = math.random((Config.BandageRecieve[1] or 1), (Config.BandageRecieve[2] or 2))--
--local weaponbottle = math.random ((Config.WeaponBottle[1] or 1), (Config.WeaponBottle[1] or 1)) --
if luck >= 0 and luck <= 29 then
TriggerClientEvent("esx:showNotification", source, "No habia nada interesante en la basura.")
end
if luck >= 30 and luck <= 35 then
player.addInventoryItem("bandage", randomBandage)
TriggerClientEvent("esx:showNotification", source, ("Encontraste x%s ~y~Vendaje!"):format(randomBandage))
end
if luck >= 36 and luck <= 42 then
player.addInventoryItem("bandage", randomBandage)
TriggerClientEvent("esx:showNotification", source, ("Encontraste x%s ~y~Vendaje!"):format(randomBandage))
player.addInventoryItem("bottle", randomBottle)
TriggerClientEvent("esx:showNotification", source, ("Encontraste x%s ~g~Botellas vacia"):format(randomBottle))
end
--if luck >= 42 and luck <= 64 then
--local player = GetPlayerPed(-1)
TriggerClientEvent("esx:showNotification", source, "No habia nada interesante en la basura.(BOTELLA ERROR)")
-- TriggerClientEvent("esx:showNotification", source, ("Encontraste x%s ~o~Botella Partida! estĆ” afilada!"):format(weaponbottle))
--end
if luck >= 65 and luck <= 100 then
player.addInventoryItem("bottle", randomBottle)
TriggerClientEvent("esx:showNotification", source, ("Encontraste x%s ~g~Botellas vacia"):format(randomBottle))
end
end)