How to make an entity that plays a sound file on loop and gardually damages players in an radius?

Hello.

im currently making my first entity and swep.
The swep will just shoot the entity so thats no problem.

Im having problems with the entity scripting. I want my entity to play a .wav file on loop ( its about 20 secounds long ) until someone removes it and while it does that it will hurt any player that “hears” it ( i can just fake that by setting an approperate radius ).
But how can i accomplish that?

The main problem is the gradual damage in a radius without knockback

ents.FindInSphere

Entity:TakeDamage

[editline]26th August 2016[/editline]

I think

Entity:SetHealth works without knockback

Does this deal damage to the players in the radius of the object?

You mean SetHealth? Or TakeDamage? Both of them let you damage entities, so if you use them with FindInSphere then you can do radial damage-there’s probably a better way though

Jeah but i dont want the entity to take damage. I want the players that are near the entity to take damage

Sorry, I meant entities (including players) near the main entity. I guess I’ll do an example

Alright. The only thing i now need is a way to detect wich entities are players ( so i dont deal damage to cars or random props )



function ENT:Think()
	for k,v in pairs( ents.FindInSphere( self:GetPos(), 50 ) ) do -- change 50 to be whatever radius you want
		if v ~= self and v:IsPlayer() then
			v:TakeDamage( 69 ) -- change 69 to whatever number you want the damage to be
			-- OR
			v:SetHealth( v:Health() - 69 ) -- change 69 to whatever number you want the damage to be
		end
	end
end


If the entity thinks a bit too slowly you can always speed it up using

Entity:NextThink

But that would be way to expensive.
You are looping through all the entities, comparing positions (with the ents.FindInSphere) and then looping again through those entities to see who are players.
I think if you want to only damage players the best way would be:

[LUA]
function ENT:Think()
local pos = self:GetPos()
for k, v in pairs(player.GetAll()) do
if v:GetPos():Distance(pos) <= 50 then
v:TakeDamage( 69 ) – change 69 to whatever number you want the damage to be
– OR
v:SetHealth( v:Health() - 69 ) – change 69 to whatever number you want the damage to be
end
end
end
[/LUA]

Thanks!

My entity and weapon are now working. Im just having a few minor problems.

First one is pretty simple. I want the entity to remove itself after 10 secounds. How can i do that?

Secoundly im getting this error:


[ERROR] addons/name 10 thing that arent/lua/entities/the_button/init.lua:59: bad argument #2 to 'Simple' (function expected, got no value)
  1. Simple - [C]:-1
   2. unknown - addons/name 10 thing that arent/lua/entities/the_button/init.lua:59

It oviously referring to this function:


function ENT:Think()
	local pos = self:GetPos()
	for k, v in pairs(player.GetAll()) do
		if v:GetPos():Distance(pos) <= 50 then
			timer.Simple(10,function() v:TakeDamage( 1)) -- I added the 
--timer to stop the entity from killing people almost instantly and spamming them 
--with damage. Also this is the line its referring to
		end
	end
end


And lastly i want the entity to spawn a bit further away from the player ( always barely outside its radius so the shooter doesnt get hurt ) and it should also fly further.

Here is the code i have been using to calculate the velocity( its in the swep ):


self:SetNextPrimaryFire(CurTime()+self.Primary.Delay)
	
	if(CLIENT) then return end
	
	local ent = ents.Create("the_button")
	
	if(!IsValid(ent)) then return end
	
	ent:SetPos(self.Owner:EyePos()+(self.Owner:GetAimVector() * 16))
	ent:SetAngles( self.Owner:EyeAngles ())
	ent:Spawn()
	
	local phys = ent:GetPhysicsObject()
	if ( !IsValid (phys)) then ent:Remove() return end
	
	local velocity = self.Owner:GetAimVector()
	velocity = velocity + (VectorRand() * 10)
	phys:ApplyForceCenter(velocity)