Andres99907 Posted August 30, 2021 Share Posted August 30, 2021 (edited) I am making a script to use flares on aircraft, the script works fine until two players use a flare at the same time, the declared variables change and one of the flares is not destroyed. Here is a video of my script: I was checking the creator of the flare with an outpuchatbox at the end of the script, and I saw that the creator changed, which means that the variable was declared again. Flares = {} Chaffs = {} function FlarePhys(x, y, z, distance, gz) player = client index = #Flares + 1 Flares[index] = { ["Vehicles"] = { getPedOccupiedVehicle(player) }, ["Lights"] = { createMarker(x,y,z,"corona", 1, 255,0,0) }, ["Flares"] = { createObject(2060, x,y,z) } } setElementData(Flares[index]["Vehicles"][1], "Dismissile", true) setElementCollisionsEnabled(Flares[index]["Flares"][1], false) attachElements(Flares[index]["Lights"][1], Flares[index]["Flares"][1]) moveObject(Flares[index]["Flares"][1], distance*100, x, y, gz +1.5) setTimer ( function() if isElement(Flares[index]["Vehicles"][1]) then removeElementData(Flares[index]["Vehicles"][1], "Dismissile") else destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end end, 1000, 1 ) setTimer ( function() outputChatBox(getPlayerName(player)) destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end, 8000, 1 ) end addEvent("UseFlares", true) addEventHandler("UseFlares", getRootElement(), FlarePhys) I need help because i don't know how to make the function work for every player and not for the player that uses the Flare i will appreciate the help, I think i can do this script clientside triggering it for all players but if i do this serverside i will be happy haha. Edited August 30, 2021 by Andres99907 Link to comment
The_GTA Posted August 30, 2021 Share Posted August 30, 2021 (edited) 51 minutes ago, Andres99907 said: I was checking the creator of the flare with an outpuchatbox at the end of the script, and I saw that the creator changed, which means that the variable was declared again. Hello Andres99907! Nice to meet you. I am an experienced developer and want to help you become a better Lua scripter. For this purpose I want to give you advice on how to incrementally improve your work. Did you know about local variables in connection with Lua closures? You can do amazing things with this mechanism like this. local global_index = 0 index = 0 function CreateClosure() local index = global_index + 1 -- uses the "global_index" local variable in the up-most script closure local function callback() return index -- uses the index variable of line 6 end global_index = index return callback end index = 42 -- modifies the global variable "index" which is not a local variable assert( CreateClosure()() == 1 ) assert( CreateClosure()() == 2 ) assert( index == 42 ) -- not changed by CreateClosure function Lua closures are created each time your script puts a function into a variable/table key. When you call a closure then the function is executed which then does access so called "upvalues", the local variables of closures that enclose this closure. Before you can use a local variable you have to declare it using the local keyword! Using this technique we can improve your script by remembering the variables you create during your FlarePhys function call, like this: Flares = {} Chaffs = {} function FlarePhys(x, y, z, distance, gz) local player = client local index = #Flares + 1 Flares[index] = { ["Vehicles"] = { getPedOccupiedVehicle(player) }, ["Lights"] = { createMarker(x,y,z,"corona", 1, 255,0,0) }, ["Flares"] = { createObject(2060, x,y,z) } } setElementData(Flares[index]["Vehicles"][1], "Dismissile", true) setElementCollisionsEnabled(Flares[index]["Flares"][1], false) attachElements(Flares[index]["Lights"][1], Flares[index]["Flares"][1]) moveObject(Flares[index]["Flares"][1], distance*100, x, y, gz +1.5) setTimer ( function() if isElement(Flares[index]["Vehicles"][1]) then removeElementData(Flares[index]["Vehicles"][1], "Dismissile") else destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end end, 1000, 1 ) setTimer ( function() outputChatBox(getPlayerName(player)) destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end, 8000, 1 ) end addEvent("UseFlares", true) addEventHandler("UseFlares", getRootElement(), FlarePhys) This script should work better for you because now the "creator" does not suddenly change anymore. Edited August 30, 2021 by The_GTA 1 Link to comment
Andres99907 Posted August 30, 2021 Author Share Posted August 30, 2021 19 minutes ago, The_GTA said: Hello Andres99907! Nice to meet you. I am an experienced developer and want to help you become a better Lua scripter. For this purpose I want to give you advice on how to incrementally improve your work. Did you know about local variables in connection with Lua closures? You can do amazing things with this mechanism like this. local global_index = 0 index = 0 function CreateClosure() local index = global_index + 1 -- uses the "global_index" local variable in the up-most script closure local function callback() return index -- uses the index variable of line 6 end global_index = index return callback end index = 42 -- modifies the global variable "index" which is not a local variable assert( CreateClosure()() == 1 ) assert( CreateClosure()() == 2 ) assert( index == 42 ) -- not changed by CreateClosure function Lua closures are created each time your script puts a function into a variable/table key. When you call a closure then the function is executed which then does access so called "upvalues", the local variables of closures that enclose this closure. Using this technique we can improve your script by remembering the variables you create during your FlarePhys function call, like this: Flares = {} Chaffs = {} function FlarePhys(x, y, z, distance, gz) local player = client local index = #Flares + 1 Flares[index] = { ["Vehicles"] = { getPedOccupiedVehicle(player) }, ["Lights"] = { createMarker(x,y,z,"corona", 1, 255,0,0) }, ["Flares"] = { createObject(2060, x,y,z) } } setElementData(Flares[index]["Vehicles"][1], "Dismissile", true) setElementCollisionsEnabled(Flares[index]["Flares"][1], false) attachElements(Flares[index]["Lights"][1], Flares[index]["Flares"][1]) moveObject(Flares[index]["Flares"][1], distance*100, x, y, gz +1.5) setTimer ( function() if isElement(Flares[index]["Vehicles"][1]) then removeElementData(Flares[index]["Vehicles"][1], "Dismissile") else destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end end, 1000, 1 ) setTimer ( function() outputChatBox(getPlayerName(player)) destroyElement(Flares[index]["Flares"][1]) destroyElement(Flares[index]["Lights"][1]) end, 8000, 1 ) end addEvent("UseFlares", true) addEventHandler("UseFlares", getRootElement(), FlarePhys) This script should work better for you because now the "creator" does not suddenly change anymore. it worked , i didn't know the use of local for declaring variables because i alwais did my scripts clientsided, i appreciate it bro, thank you :0 1 Link to comment
The_GTA Posted August 30, 2021 Share Posted August 30, 2021 1 minute ago, Andres99907 said: it worked , i didn't know the use of local for declaring variables because i alwais did my scripts clientsided, i appreciate it bro, thank you :0 No problem! I like to help you. If you have any further questions about Lua scripting in general please ask. 1 Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now