SWEP Sound Effect

Hey guys, just a quick question:

I’m brand new to Lua and have been trying to make a sound effect on a swep.

Can anyone draft me a sample of what I’m looking to achieve? I want to take a look at what you can make and learn from there.

What I’m looking to do:

Secondary attack of a swep needs to play server side music in a proximity from the player. But if you press it again it turns off the sound so it’s not annoying.

So basically when you use the secondary attack it’s like turning a sound on and off and if players are in range they can either hear it at max volume, or as they get closer it gets louder.

Is this possible?

TL:DR
Secondary Attack Emits sound at Weapon/Player (the sound follows the player around)
Secondary Attack while sound is playing turns off Sound
Proximity Sound is a bonus

I don’t have a rough draft because I have no idea how to begin this other than the basic Secondary attack sequence.

I commented this bit of code so that you could understand what is going on here:


function SWEP:SecondaryAttack()
	-- Make the timer unique to this weapon -- each entity has its own ent index
	local sName = "MyWeaponSound-" .. self:EntIndex()
	local flCurTime = CurTime()
	
	-- Toggle the sound off
	if (timer.Exists(sName)) then
		timer.Remove(sName)
		
		-- Store the time we stopped the time so that prediction doesn't recreate it
		self.m_flRemoveSoundTime = flCurTime
	-- Sound isn't playing, turn it on
	elseif (self.m_flRemoveSoundTime ~= flCurTime) then
		local pOwner = self:GetOwner()
		
		-- Check that the weapon has an owner
		if (pOwner:IsValid()) then
			-- Play the sound initially
			pOwner:EmitSound("sound.wav")
			
			-- Would be better to use the SWEP's think function instead, but this is a start
			-- Play it again after a specified amount of time
			timer.Create(sName, 5 --[[5 seconds]], 0 --[[Keep running until removed]], function()
				-- The weapon still exists
				if (self:IsValid()) then
					local pNewOwner = self:GetOwner()
					
					-- The weapon still has an owner and it is the same one as before
					if (pNewOwner:IsValid() and pNewOwner == pOwner) then
						pNewOwner:EmitSound("sound.wav")
					else
						-- Stop playing the sound
						timer.Remove(sName)
					end
				else
					timer.Remove(sName)
				end
			end)
		end
	end
	
	-- Don't allow another toggle for five seconds
	self:SetNextSecondaryFire(flCurTime + 5)
end

I will try this out! I’m assuming I’m naming the sound for the Lua file with “MyWeaponSound”.

If I’m understanding this kinda correctly: Does this make the sound toggle-able but from where the soundfile last left off?

If so; I’m looking to make it simply when you secondaryattack it will start a fresh sound, and when you secondaryattack it turns it off, so when you use it again, the sound plays fresh. Or does it reset on it’s own?

Sorry, and also a huge thanks for teaching me a lot in this post. You had a quick reply and I totally didnt expect someone to really give me this much help.

Thank you!

No, that’s just a placeholder timer name – that can be whatever. It’s the sound.wav you need to replace with your sound file/scape.

No, it will just toggle the timer to stop making the sound play more. There is no way to pause and continue a sound in Lua.

It will start fresh, but if you toggle it off, the sound won’t stop playing until it has ended.

Ok! Thanks! I like fail safes incase this SWEP gets out of an admins hands and into the wrong hands.

Also; Do I need to make a cl_init.lua, shared.lua, and init.lua for a swep? Because I don’t know what to put in the cl_init.lua to make it “found”. (Thanks for all the prior help, too).

You do not in this case – just make a single lua file that is named the name of the weapon class (weapon_mysoundweapon or something like that).

code_gs

So what I did in the cl_init.lua was just put the swep name. Everything worked, but I ran into a problem on initial testing.

So here’s how it plays out:

When I right click for secondary attack the sound begins: Ok
About 5 seconds or so in the sound plays again over itself and it like goes on a weird loop. I probably should have described the sound better.

What I have going on in my head is I want a weapon where the first attack damages. Then the secondary attack plays music (the sound effect). I ideally wanted it to be proximity (think slenderman beats how when he gets closer you KNOW he is stalking you as it gets louder). But more like a simple, right click to turn on, right click to turn off.

Here are the issues, I wonder if you can help me tailor it (and you definitely do not need to go above and beyond what you have already done :)!)

When I right click for secondary attack a second time, the sound plays again, even if the prior sound was playing (is there a way to fix this?) Strangely if I spam right click it will play the full track, but very choppy as if skipping 5 sec intervals.

I probably should have said that to start.

[editline]14th February 2017[/editline]

Also, final question from me!

What’s the distance at which other players can hear this?

Two things: change the file structure to what I said above. You are only running it clientside and it is causing the cooldown to never be properly set. Secondly, change the “5” in the timer and cool down to better reflect the sound length – it was just a guess.

[editline]13th February 2017[/editline]

I believe 2500 units, but I could be remembering incorrectly

Ok I will give it a shot! Will post in a bit!

[editline]14th February 2017[/editline]

Ok! Worked out great! No spam! Only final question is how do I stop it from looping? After 67 seconds (since I tested spamming, which it did not spam during the track) it plays immediately after.
Just need to solve that.

Then actually, I think you said the track cannot be stopped once playing, I’m assuming there’s no way to stop the sound mid track by right clicking if it’s playing correct?

There is no explicit way to stop it with EmitSound. You could try something hacky like declaring the sound with sound.Add then running an empty sound on the same channel, but I would have to do more testing to know if it worked properly.

Hmm, for now, how do you suppose stopping the loop after 67 seconds?

Also; I’ll try making a script tomorrow and post it here. This is wonderful in case someone is attempting the same thing I am.

If this is music we’re talking about, sound.PlayURL is what you’re looking for.

Naw, I added the sound file as a resource. Didn’t want to directly stream it. I just want to be able to turn it on and off from right click on a weapon.

[editline]14th February 2017[/editline]

function SWEP:SecondaryAttack()
– Make the timer unique to this weapon – each entity has its own ent index
local sName = “MyersChase” … self:EntIndex()
local flCurTime = CurTime()

-- Toggle the sound off
if (timer.Exists(sName)) then
	timer.Remove(sName)
	
	-- Store the time we stopped the time so that prediction doesn't recreate it
	self.m_flRemoveSoundTime = flCurTime
-- Sound isn't playing, turn it on
elseif (self.m_flRemoveSoundTime ~= flCurTime) then
	local pOwner = self:GetOwner()
	
	-- Check that the weapon has an owner
	if (pOwner:IsValid()) then
		-- Play the sound initially
		pOwner:EmitSound("dwmyers/dwmyersknife/Myerschase.wav")
		
		-- Would be better to use the SWEP's think function instead, but this is a start
		-- Play it again after a specified amount of time
		---timer.Create(sName, 67 --[[5 seconds]], 1 --[[Keep running until removed]], function()
			-- The weapon still exists
			---if (self:IsValid()) then
				---local pNewOwner = self:GetOwner()
				
				-- The weapon still has an owner and it is the same one as before
				---if (pNewOwner:IsValid() and pNewOwner == pOwner) then
					---pNewOwner:EmitSound("dwmyers/dwmyersknife/Myerschase.wav")
				---else
					-- Stop playing the sound
					---timer.Remove(sName)
				---end
			---else
				---timer.Remove(sName)
			---end
		---end)
	end
end

-- Don't allow another toggle for five seconds
self:SetNextSecondaryFire(flCurTime + 67)

end

I dont know how to post it in Lua format like the above posts.

This is 90% formatted to how I like it!

The sound doesnt spam, it plays at the player (I need to test it with a friend), and it doesnt loop.

The only ideal thing that I will experiment with later is if I can get it to stop playing (maybe by recalculation the sound source location with sound.play or whatnot every .5sec) when right clicking a second time during the track.

This works! I like it for a “for fun” weapon… Will post any updates later. All I did was omit some of the code to tailor it.