sirrjohn Posted September 3, 2023 Share Posted September 3, 2023 I get the following error -- PLAY ZOMBIE SOUNDS local zombiesounds = { "Sonidos/zgroan (1).ogg", "Sonidos/zgroan (2).ogg", "Sonidos/zgroan (3).ogg", "Sonidos/zgroan (4).ogg", "Sonidos/zgroan (5).ogg", "Sonidos/zgroan (6).ogg", "Sonidos/zgroan (7).ogg", "Sonidos/zgroan (8).ogg", "Sonidos/zgroan (9).ogg", "Sonidos/zgroan (10).ogg", "Sonidos/zgroan (11).ogg", "Sonidos/zgroan (12).ogg", "Sonidos/zgroan (13).ogg", "Sonidos/zgroan (14).ogg", "Sonidos/zgroan (15).ogg", "Sonidos/zgroan (16).ogg", "Sonidos/zgroan (17).ogg", "Sonidos/zgroan (18).ogg", "Sonidos/zgroan (19).ogg", "Sonidos/zgroan (20).ogg", "Sonidos/zgroan (21).ogg", "Sonidos/zgroan (22).ogg", "Sonidos/zgroan (23).ogg", "Sonidos/zgroan (24).ogg", "Sonidos/zgroan (25).ogg", "Sonidos/zgroan (26).ogg", "Sonidos/zgroan (27).ogg", "Sonidos/zgroan (28).ogg", "Sonidos/zgroan (29).ogg", "Sonidos/zgroan (30).ogg", "Sonidos/zgroan (31).ogg", "Sonidos/zgroan (32).ogg", "Sonidos/zgroan (33).ogg", "Sonidos/zgroan (34).ogg", "Sonidos/zgroan (35).ogg", "Sonidos/zgroan (36).ogg", } zedSound = false function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) setSoundMaxDistance(zedSound,5) end if getElementData(peds,"deadman") or getElementData(peds,"Muerto") then stopSound(zedSound) end end end setTimer(playZombieSounds,6000,0) Link to comment
Bishop_G Posted September 3, 2023 Share Posted September 3, 2023 function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then if getElementData(peds,"deadman") or getElementData(peds,"Muerto") return end local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) setSoundMaxDistance(zedSound,5) end end end setTimer(playZombieSounds,6000,0) Link to comment
sirrjohn Posted September 3, 2023 Author Share Posted September 3, 2023 (edited) 5 hours ago, Bishop_G said: function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then if getElementData(peds,"deadman") or getElementData(peds,"Muerto") return end local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) setSoundMaxDistance(zedSound,5) end end end setTimer(playZombieSounds,6000,0) Hey Bishop! Sadly it didnt work... I had the same code on a different zombie gamemode and there it worked fine... but on this one it doesnt.. zombies keep making sounds when dead Edited September 3, 2023 by sirrjohn Link to comment
Addlibs Posted September 5, 2023 Share Posted September 5, 2023 (edited) for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) zedSound variable is overwritten for every ped. This means you're creating new sounds but discarding the pointer/reference/element handle for the old one. The old one will thus remain playing and you have no way* to delete it. What you need instead is a table of sounds you've spawned, and when you call stopSound, you should call it once per sound element in that table. This should stop all the sounds you've created. Example: -- when creating spawnedSounds = {} for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) -- do whatever with zedSound spawnedSounds[ped] = zedSound -- store the zedSound into a table for later when calling stopSound -- when stopping for theKey,theSound in pairs(spawnedSounds) do -- go through each sound in the table (note the use of pairs is -- essential if the keys of the table are not numerical and sequential: in this case they are elements so pairs, is needed) -- (also NB: some performance comparisons point out pairs is faster than ipairs even with sequential numeric tables -- so you can just blindly always use pairs instead of ipairs without performance impact) stopSound(theSound) -- stop the sound that is stored as the value of a key=value pair in each row of the table end * You can still recover the pointer/reference/element handle though functions like getElementsByType for sound type but its going to be much harder to identify which one you want. Edited September 5, 2023 by Addlibs 1 Link to comment
sirrjohn Posted September 6, 2023 Author Share Posted September 6, 2023 13 hours ago, Addlibs said: for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) zedSound variable is overwritten for every ped. This means you're creating new sounds but discarding the pointer/reference/element handle for the old one. The old one will thus remain playing and you have no way* to delete it. What you need instead is a table of sounds you've spawned, and when you call stopSound, you should call it once per sound element in that table. This should stop all the sounds you've created. Example: -- when creating spawnedSounds = {} for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) -- do whatever with zedSound spawnedSounds[ped] = zedSound -- store the zedSound into a table for later when calling stopSound -- when stopping for theKey,theSound in pairs(spawnedSounds) do -- go through each sound in the table (note the use of pairs is -- essential if the keys of the table are not numerical and sequential: in this case they are elements so pairs, is needed) -- (also NB: some performance comparisons point out pairs is faster than ipairs even with sequential numeric tables -- so you can just blindly always use pairs instead of ipairs without performance impact) stopSound(theSound) -- stop the sound that is stored as the value of a key=value pair in each row of the table end * You can still recover the pointer/reference/element handle though functions like getElementsByType for sound type but its going to be much harder to identify which one you want. It seems its working, but how to stop sound only when ped is dead? i tried this, didnt work spawnedSounds = {} function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) spawnedSounds[ped] = zedSound for theKey,theSound in pairs(spawnedSounds) do if getElementData(ped,"deadman") or getElementData(ped,"Muerto") then stopSound(theSound) end end end end end setTimer(playZombieSounds,6000,0) Link to comment
DiSaMe Posted September 8, 2023 Share Posted September 8, 2023 There seems to be confusion between variables due to a poor choice of names. ped is a table of all peds while peds is the current ped in the iteration. Because of that, the sound handle inserted into the table in one iteration still gets overridden in the other - because ped is the same value between iterations (always refers to the table of all peds). So it's better to swap them. But with the current names, you're supposed to use spawnedSounds[peds] to refer to the current ped's sound, and pass peds to getElementData. Link to comment
sirrjohn Posted September 9, 2023 Author Share Posted September 9, 2023 13 hours ago, DiSaMe said: There seems to be confusion between variables due to a poor choice of names. ped is a table of all peds while peds is the current ped in the iteration. Because of that, the sound handle inserted into the table in one iteration still gets overridden in the other - because ped is the same value between iterations (always refers to the table of all peds). So it's better to swap them. But with the current names, you're supposed to use spawnedSounds[peds] to refer to the current ped's sound, and pass peds to getElementData. It works now, but with many DUPS... spawnedSounds = {} function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) zedSound = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) spawnedSounds[peds] = zedSound for theKey,theSound in pairs(spawnedSounds) do if getElementData(peds,"deadzombie") then stopSound(theSound) end end end end end setTimer(playZombieSounds,6000,0) Link to comment
DiSaMe Posted September 10, 2023 Share Posted September 10, 2023 This block: for theKey,theSound in pairs(spawnedSounds) do -- end was meant to be used separately from the code that starts the sounds. By putting it into the same block, you're stopping the sounds for all peds if the current ped has deadzombie set to true, as it loops through spawnedSounds table. I'd say your initial code is close enough, you just need to use spawnedSounds[peds] to refer to the current ped's sound. But then the warning will still be there, it happens because calling stopSound destroys the sound element, but the (no-longer-valid) handle is still in spawnedSounds table, so when it gets passed to stopSound the next time, you get a warning. You can remove a value from the table by assigning nil to it, so destroying the current ped's sound would look like this: stopSound(spawnedSounds[peds]) -- stop the sound, destroy the sound element spawnedSounds[peds] = nil -- remove the no-longer-existing element from the table But even then, I can think of scenarios where things go wrong. Like for example the loop is executed every 6 seconds, so you call playSound3D and store the result to spawnedSounds[peds] repeatedly, meaning the sound element from the previous execution is still overwritten by new sound element. So the next stopSound call will only stop the ped's most recent sound. I guess the right way to handle this depends on your needs, but in any case, assuming you clean up the sounds from the table after stopping them, you can check if the sound from earlier executions exists by directly checking the value in the table: if spawnedSounds[peds] then -- called if the sound exists else -- called if the sound doesn't exist end 1 Link to comment
alex17" Posted September 12, 2023 Share Posted September 12, 2023 spawnedSounds = {} function playZombieSounds() local ped = getElementsByType("ped") for theKey,peds in ipairs(ped) do if ped and isElement(peds) and isElementStreamedIn(peds) then local Zx,Zy,Zz = getElementPosition(peds) if not spawnedSounds[peds] or not isElement(spawnedSounds[peds] then spawnedSounds[peds] = playSound3D(zombiesounds[math.random(1,#zombiesounds)], Zx, Zy, Zz, false) end end end end setTimer(playZombieSounds,6000,0) addEventHandler("onClientPedWasted", root, function() if spawnedSounds[source] and isElement(spawnedSounds[source] then destroyElement(spawnedSounds[source]) spawnedSounds[source] = nil end end ) 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