Bean666 Posted January 31, 2021 Share Posted January 31, 2021 Hello, i just want to know if my code is correct, this is serverside, I created a timer table so if a player leaves the zone the others timer and explosions wont stop, only his, is my code correct or im doing things really wrong? local areaex = createColRectangle ( 2076.61499, 971.57928, 50, 50) local arearadar = createRadarArea ( 2076.61499, 971.57928, 50, 50, 0, 255, 0, 100) local timers = { }; function enterZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then outputChatBox("Entering zone",hitPlayer, 255, 0, 0) local pX, pY, pZ = getElementPosition ( hitPlayer ) timers[ hitPlayer ] = setTimer ( function() createExplosion ( pX+math.random(-30,30), pY, pZ, 6, source ) end, 3000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) function leaveZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then outputChatBox("leaving",hitPlayer) killTimer( timers[ hitPlayer ] ); end end addEventHandler( "onColShapeLeave", areaex, leaveZone ) Link to comment
SpecT Posted January 31, 2021 Share Posted January 31, 2021 It seems fine to me. As long as it works fine you should not worry about it. You could only add a check if the timer exists and then kill it. if isTimer(timers[hitPlayer]) then killTimer(timers[hitPlayer]); end IF IT AIN'T BROKE, DON'T FIX IT Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) it works but i haven't tested it with players yet, im just not sure if it would kill other player's timers anyway can u help me with this code, i put locations in the table that there would be a random nearby explosion around the player so i made these the problem is I dont know how to make it work as i want to since i made a loop that a certain explosion would happen but it only happens on 1 place, and i'm aware of that, the real problem is idk how to make all locations in the table be in the createExplosion randomly, it just picks one location in the table and it repeats, how to solve that? function enterZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then local pX, pY, pZ = getElementPosition ( hitPlayer ) local locations = { { pX, pY, pZ }, { pX+30, pY+60, pZ}, { pX+60, pY, pZ } } loc = math.random(#locations) timers[ hitPlayer ] = setTimer ( function() createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) end, 5000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) Edited January 31, 2021 by Shaman123 Link to comment
SpecT Posted January 31, 2021 Share Posted January 31, 2021 (edited) You have to put the math.random line inside the timer function. This way everytime the timer executes the function it will generate random number and then the explosions will be at random locations. timers[ hitPlayer ] = setTimer ( function() loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) end, 5000, 0 ) About the kill timers it will kill only the specified player's timer. The other timers (for the other players) will stay untouched. Edited January 31, 2021 by SpecT Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 51 minutes ago, SpecT said: You have to put the math.random line inside the timer function. This way everytime the timer executes the function it will generate random number and then the explosions will be at random locations. timers[ hitPlayer ] = setTimer ( function() loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) end, 5000, 0 ) About the kill timers it will kill only the specified player's timer. The other timers (for the other players) will stay untouched. and last, how do i create a timer within a timer? I tried but its hard i created another table for the timer 2, and it kinda works, but idk if thats well optimized, the problem is i want to kill the timer2 after 5 seconds its been going on, how do I do that? timers[ hitPlayer ] = setTimer ( function() timer2[ hitPlayer ] = setTimer(function() loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) end, 1500, 0) end, 10000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) EDIT: i did this, is this fine? it works kinda fine but i want u to take a look if its really okay, edit again: nvm this is buggy, im having a hard time killing timer2, i executed it , but timer 3 is looping as well. local timers = { }; local timer2 = { }; local timer3= { }; function enterZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then outputChatBox("enter",hitPlayer, 255, 0, 0) timers[ hitPlayer ] = setTimer ( function() outputChatBox("started", hitPlayer, 255, 0, 0) timer2[ hitPlayer ] = setTimer ( function() local pX, pY, pZ = getElementPosition ( hitPlayer ) local locations = { { pX+20, pY, pZ }, { pX+30, pY, pZ}, { pX+30, pY+20, pZ}, { pX, pY+35, pZ}, { pX, pY+40, pZ}, { pX+60, pY, pZ } } loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) timer3[hitPlayer] = setTimer(function() if isTimer(timer2[hitPlayer]) then killTimer(timer2[hitPlayer]) outputChatBox("ended", hitElement, 0, 255, 0) end end, 5000, 1) end, 2000, 0 ) end, 12000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) Edited January 31, 2021 by Shaman123 Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 37 minutes ago, Shaman123 said: and last, how do i create a timer within a timer? I tried but its hard i created another table for the timer 2, and it kinda works, but idk if thats well optimized, the problem is i want to kill the timer2 after 5 seconds its been going on, how do I do that? timers[ hitPlayer ] = setTimer ( function() timer2[ hitPlayer ] = setTimer(function() loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) end, 1500, 0) end, 10000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) EDIT: i did this, is this fine? it works kinda fine but i want u to take a look if its really okay, edit again: nvm this is buggy, im having a hard time killing timer2, i executed it , but timer 3 is looping as well. local timers = { }; local timer2 = { }; local timer3= { }; function enterZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then outputChatBox("enter",hitPlayer, 255, 0, 0) timers[ hitPlayer ] = setTimer ( function() outputChatBox("started", hitPlayer, 255, 0, 0) timer2[ hitPlayer ] = setTimer ( function() local pX, pY, pZ = getElementPosition ( hitPlayer ) local locations = { { pX+20, pY, pZ }, { pX+30, pY, pZ}, { pX+30, pY+20, pZ}, { pX, pY+35, pZ}, { pX, pY+40, pZ}, { pX+60, pY, pZ } } loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) timer3[hitPlayer] = setTimer(function() if isTimer(timer2[hitPlayer]) then killTimer(timer2[hitPlayer]) outputChatBox("ended", hitElement, 0, 255, 0) end end, 5000, 1) end, 2000, 0 ) end, 12000, 0 ) end end addEventHandler( "onColShapeHit", areaex, enterZone ) update: here first loop is fine, works fine, but when the second loop comes, timer1 starts, timer2 starts, then is ended instantly by timer 3. no delays how is that?, nvm i get it now, because i had put the timer3 on loop as well, on the timer2, so it gives multiple timer3s, how can i fix this? or how can i put the timer3 out of timer2 then if timer2 starts, it starts too. Edited January 31, 2021 by Shaman123 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 2 hours ago, Shaman123 said: how can i fix this? or how can i put the timer3 out of timer2 then if timer2 starts, it starts too. Recommendation: It is best do not nest timer functions. Just create new named functions outside: local timers = {} --[[ if not timers[hitPlayer] then timers[hitPlayer] = setTimer(stage1, 3000, 1, hitPlayer) end ]] function stage1 (hitPlayer) timers[hitPlayer] = setTimer(stage2, 3000, 1, hitPlayer) end function stage2 (hitPlayer) timers[hitPlayer] = setTimer(stage3, 3000, 1, hitPlayer) end function stage3 (hitPlayer) timers[hitPlayer] = nil end function stopStageTimer (player) if timers[ player ] then if isTimer(timers[ player ] ) then killTimer(timers[ player ] ) end timers[ player ] = nil end end addCommandHandler("stopTimer", stopStageTimer) If your code works in stages, adding more timer tables will create more complexity. It is best to use 1 single timer table for all stages. Especially when you do this: end, 2000, 0 ) end, 12000, 0 ) This combo can kill your server at a given moment. Never create an infinity timer inside of another infinity timer. It will just multiply. Even if you create something that will prevent this inside of the function. > If there is an error inside the most inner function, the function will stop and it is not prevented any more. The following code can be used for: Stopping a timer Prevent double timers if timer2[ hitPlayer ] then if isTimer(timer2[ hitPlayer ] ) then killTimer(timer2[ hitPlayer ] ) end timer2[ hitPlayer ] = nil end Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 2 hours ago, IIYAMA said: Recommendation: It is best do not nest timer functions. Just create new named functions outside: local timers = {} --[[ if not timers[hitPlayer] then timers[hitPlayer] = setTimer(stage1, 3000, 1, hitPlayer) end ]] function stage1 (hitPlayer) timers[hitPlayer] = setTimer(stage2, 3000, 1, hitPlayer) end function stage2 (hitPlayer) timers[hitPlayer] = setTimer(stage3, 3000, 1, hitPlayer) end function stage3 (hitPlayer) timers[hitPlayer] = nil end function stopStageTimer (player) if timers[ player ] then if isTimer(timers[ player ] ) then killTimer(timers[ player ] ) end timers[ player ] = nil end end addCommandHandler("stopTimer", stopStageTimer) If your code works in stages, adding more timer tables will create more complexity. It is best to use 1 single timer table for all stages. Especially when you do this: end, 2000, 0 ) end, 12000, 0 ) This combo can kill your server at a given moment. Never create an infinity timer inside of another infinity timer. It will just multiply. Even if you create something that will prevent this inside of the function. > If there is an error inside the most inner function, the function will stop and it is not prevented any more. The following code can be used for: Stopping a timer Prevent double timers if timer2[ hitPlayer ] then if isTimer(timer2[ hitPlayer ] ) then killTimer(timer2[ hitPlayer ] ) end timer2[ hitPlayer ] = nil end function stage3 (hitPlayer) timers[hitPlayer] = nil end Thanks for these, i got an idea now, and btw the stage3 is where it stops the timer right? and as i'm aware it'll only stop for the player right? not all of them. Edited January 31, 2021 by Shaman123 1 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 (edited) 5 minutes ago, Shaman123 said: the stage3 is where it stops the timer right? and as i'm aware it'll only stop for the player right? not all of them. That is correct. But it stops by itself, since it only runs 1x. (0= infinity) setTimer(stage3, 3000, 1, hitPlayer) In stage3 there is only a clean up for the value in the table. Edited January 31, 2021 by IIYAMA Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 18 minutes ago, IIYAMA said: That is correct. But it stops by itself, since it only runs 1x. (0= infinity) setTimer(stage3, 3000, 1, hitPlayer) In stage3 there is only a clean up for the value in the table. function leaveZone(hitPlayer) if isElement(hitPlayer) and getElementType(hitPlayer) == "player" then if timers[ hitPlayer ] then if isTimer(timers[ hitPlayer ] ) then killTimer(timers[ hitPlayer ] ) outputChatBox("leaving",hitPlayer) end end end end addEventHandler( "onColShapeLeave", areaex, leaveZone ) Player leaves Colshape, all timers in the timertable will be killed. is this correct? (only his timers, not others) Edited January 31, 2021 by Shaman123 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 10 minutes ago, Shaman123 said: Player leaves Colshape, all timers in the timertable will be killed. is this correct? (only his timers, not others) That is correct. But don't forget to clean up: if timers[ hitPlayer ] then if isTimer(timers[ hitPlayer ] ) then killTimer(timers[ hitPlayer ] ) outputChatBox("leaving",hitPlayer) end timers[ hitPlayer ] = nil -- clean up end Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 3 minutes ago, IIYAMA said: That is correct. But don't forget to clean up: if timers[ hitPlayer ] then if isTimer(timers[ hitPlayer ] ) then killTimer(timers[ hitPlayer ] ) outputChatBox("leaving",hitPlayer) end timers[ hitPlayer ] = nil -- clean up end may I ask why u put the timer [ hitPlayer ] = nil after the end? what is the explanation. Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 9 minutes ago, Shaman123 said: may I ask why u put the timer [ hitPlayer ] = nil after the end? what is the explanation. Even if you destroy the timer, both the value of the player(as table key) and timer (as table value) are still inside of the table. Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 15 minutes ago, IIYAMA said: Even if you destroy the timer, both the value of the player(as table key) and timer (as table value) are still inside of the table. function leaveZone(hitPlayer) if timers[ hitPlayer ] then if isTimer(timers[ hitPlayer ] ) then killTimer(timers[ hitPlayer ] ) outputChatBox("leaving",hitPlayer) end end end timers[ hitPlayer ] = nil addEventHandler( "onColShapeLeave", areaex, leaveZone ) table index is nil line 51, 51 is timers [hitPlayer] = nil whats the problem? EDIT: nvm i just put the line 51 above the ends, idk if thats fine but it fixed the error. anyways i want a time loop, but as u said its safer to just make the timer to "1", not "0", how is it possible to make an endless loop without the "0"?, like example i want the same cycle to repeat every 5 minutes. i tried making a loop by making the start stage a "0" but ended up getting messy. its sad Edited January 31, 2021 by Shaman123 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 28 minutes ago, Shaman123 said: how is it possible to make an endless loop without the "0"? When you are on stage3, you could start stage1 again. That is one way of doing. Also, have 1 infinity timer is not the end of the world. As long as it does not start another infinity timer within. Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 13 minutes ago, IIYAMA said: When you are on stage3, you could start stage1 again. That is one way of doing. Also, have 1 infinity timer is not the end of the world. As long as it does not start another infinity timer within. function stage1 (hitPlayer) outputChatBox("bomb", hitPlayer, 255, 0, 0) local pX, pY, pZ = getElementPosition ( hitPlayer ) local locations = { { pX+20, pY, pZ }, { pX+30, pY, pZ}, { pX+30, pY+20, pZ}, { pX, pY+35, pZ}, { pX, pY+40, pZ}, { pX+60, pY, pZ } } loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, hitPlayer ) timers[hitPlayer] = setTimer(stage2, 5*1000, 1, hitPlayer) end function stage2 (hitPlayer) outputChatBox("repeat", hitPlayer, 0, 255, 0) timers[hitPlayer] = nil timers[hitPlayer] = setTimer(stage1, 3000, 1, hitPlayer) end ohhh i got it, so basically like this right? anyways thanks man, u helped me so much today. Edited January 31, 2021 by Shaman123 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 37 minutes ago, Shaman123 said: ohhh i got it, so basically like this right? yes Small note: when you set another value, then you do not have to set it first to nil. Your code will overwrite the previous value with a new value: timers[hitPlayer] = nil timers[hitPlayer] = setTimer(stage1, 3000, 1, hitPlayer) -- < overwrite But feel free to leave it as it is, in case you are going expand the code. Link to comment
Bean666 Posted January 31, 2021 Author Share Posted January 31, 2021 (edited) 15 minutes ago, IIYAMA said: yes Small note: when you set another value, then you do not have to set it first to nil. Your code will overwrite the previous value with a new value: timers[hitPlayer] = nil timers[hitPlayer] = setTimer(stage1, 3000, 1, hitPlayer) -- < overwrite But feel free to leave it as it is, in case you are going expand the code. btw i tried the opposite version of them sharing timers, no individual timers anymore, that's easy, but im having a problem, how do you define a player in serverside? no matter how i put thePlayer, or try to define it it always says nil such as this, i want to happen that this function only happens if the player is in the areaex colshape function stage2 (thePlayer, matchingDimension) local detection = isElementWithinColShape ( thePlayer, areaex ) detection = detection and getElementDimension( thePlayer ) == getElementDimension( areaex ) if detection then local pX, pY, pZ = getElementPosition ( thePlayer ) local locations = { { pX+20, pY, pZ }, { pX+30, pY, pZ}, { pX+30, pY+20, pZ}, { pX, pY+35, pZ}, { pX, pY+40, pZ}, { pX+60, pY, pZ } } loc = math.random(#locations) createExplosion ( locations[loc][1], locations[loc][2], locations[loc][3], 6, source ) timers = setTimer(stage3, 1500, 1, source) end end isElementWithinColShape, expected element at argument 1, got nil. how do you define a player in serverside? Edited January 31, 2021 by Shaman123 Link to comment
Moderators IIYAMA Posted January 31, 2021 Moderators Share Posted January 31, 2021 (edited) 27 minutes ago, Shaman123 said: how do you define a player in serverside? The player is a value that is in most cases defined based on the action that made the code run in the first place. If it is an event, it differs from the pre-defined variable or parameter: Predefined variable: 'source'(responsible element for an event: onPlayerWasted), Predefined variable: 'client'(triggerServerEvent) Parameter: onVehicleEnter > first argument is the ped that enters, check wiki. For this event `source` is the vehicle because: onVehicleEnter > the event is about the vehicle and not a player. All this information is available on wiki. When dealing with functions that take input through different ways. It is best to normalize the information first, which you want to pass through your function. An example for addCommandHandler and an event: -- Information normalized from 2 - input(s) function showText (player, text) outputChatBox(text, player) end -- input 1 addCommandHandler("hi", function (player) showText(player, "Hi!") end) -- input 2 addEventHandler("onPlayerWasted", root, function () showText(source, "I died, sorry my bad.") end) Edited January 31, 2021 by IIYAMA 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