Detect players within render.DrawSphere?

How would you detect players within a render.DrawSphere and use the player class to have things done to those players that are within the drawn sphere?

ents.FindInSphere

Entity:IsPlayer

So i would do it like so?
[LUA]
local own = Vector(self.Owner)
if render.DrawSphere (own, 50 , 0, 0) then
return
ents.FindInSphere(own,50):Entity:IsPlayer()
if Entity:IsPlayer() then
Kill()
end
end
[/LUA]

First of all, you would need to call GetPos on self.Owner, you can’t just call Vector and give it an entity.
[lua]own = self.Owner:GetPos()[/lua]
Second, your render.DrawSphere needs a color at the end. And you can’t call ‘if’ on a function like this. You also don’t want to return, because that stops the rest of the code from being executed.
[lua]render.DrawSphere(own, 50, 0, 0, Color(255,255,255))[/lua]
Next up, ents.FindInSphere returns a table of entities, not one single entity. You’ll wanna save that table and then loop through all entries to kill everyone found in the circle.
[lua]local entities = ents.FindInSphere(own, 50)
For index, ent in pairs(entities) do
if ent:IsPlayer() then ent:Kill()
end[/lua]

And also notice how render.DrawSphere is client sided while player:Kill() is server sided. You’ll wanna split this up into two or use ‘if SERVER/CLIENT then’ to make sure each side does only their part.

Ah makes sense! I was trying to figure out how to create the sphere position based on the player position who uses the item. Question, If there anything such as an exception to a if then statement?

E.G
if ent:IsPlayer() then ent:Kill() but if ent:IsPlayer(self.Owner) then false

no, just use the ‘!’ operator

[LUA]
local own = self.Owner:GetPos()

function SWEP:Act()
self.Owner:EmitSound(ShootSound)

if ( CLIENT ) then 

render.DrawSphere( own, 50, 0, 0,color(255,255,255) )

if ( !IsValid(render.DrawSphere)) then return end

if ( SERVER ) then
	local entities = ents.FindInSphere(own,50)
	for index, ent in pairs(entities) do 
		if not !ent:IsPlayer() then ent:Kill()
	end
  end

end
[/LUA]

So it would be like this then right? Because it would pretty much be saying “If the entity creator(render.drawsphere) isn’t the owner then kill but if its not then do nothing?”

[lua]if ent:IsPlayer() and ent != self.Owner then[/lua]
You can use as many and’s as you want :slight_smile:

[LUA]
if ent:IsPlayer() then ent:Kill() and
if ent:IsPlayer() and ent != self.Owner then
false
end
end
[/LUA]

Would this kill players within the sphere but not the owner himself that used the swep to create the sphere? Question, “!” is used as short-hand to say “not” correct? So if ent NOT=self.Owner then it would kill the person who created the sphere as well and the above code wouldn’t work right??

Edit : Also another question, How would you go about creating a function that says “if time elapsed 5 seconds from primaryattack then check to see if self.owner is the only one to occupy the sphere(or check and see if all players but the owner within the sphere are dead) and if so ent:remove(render.drawsphere)”. I’ll likely have to go and look up exactly how to do it, but i know theirs a way to create a timer and am pretty sure theirs a way to check for a ent:playeralive in sphere except owner then sphere disappear but i am not sure how to go about it. (Sorry about all the hand holding with this, literally just started trying to learn LUA and its a little difficult to setup/know all the different “variables”)

[LUA]

local createsphere = render.DrawSphere(own,0,0,Color(0,0,0))
if Player:Alive() false then
cleanup.Add( self.Owner, “render”, ent )
undo.Create(“render.drawsphere”)
undo.AddFunction(function(createsphere))
undo.SetPlayer()
undo.Finish
end

[/LUA]

Edit : Added coding. ^ But even still i am not sure how this would work because i am adding cleanup.Add(ME,“What am i cleaning? Is render even a thing?”, ent??(but i am drawing a sphere in 3d space!!! NOT AN ENTITY??~!?!?)) So it would mean that everything after that which undos wouldn’t be valid either because its not telling the server what to cleanup for the player(me)

Last edit : DAMMIT. I just tried to add the swep i get this!
[LUA]

[ERROR] addons/test swep/lua/weapons/weapon_test/shared.lua:78: unexpected symbol near ‘and’

  1. unknown - addons/test swep/lua/weapons/weapon_test/shared.lua:0
    [/LUA]

[LUA]
local own = self.Owner:GetPos()

function SWEP:Act()
self.Owner:EmitSound(ShootSound)

if ( CLIENT ) then 

render.DrawSphere( own, 50, 0, 0,color(255,255,255) )

if ( !IsValid(render.DrawSphere)) then return end

if ( SERVER ) then
	local entities = ents.FindInSphere(own,50)
	for index, ent in pairs(entities) do 
		if  ent:IsPlayer() then ent:Kill() and
			if ent:IsPlayer() and ent = self.Owner then
				false

			end
		end
	end
end

end
[/LUA]

even when i change the ent = self.Owner into ent != self.Owner and i remove the and and change into the elseif statement i still get an error. I think it doesn’t like the way i am using false here. [LUA] if ent:IsPlayer() and ent = self.Owner then false[/LUA]

[LUA] ERROR] addons/test swep/lua/weapons/weapon_test/shared.lua:80: unexpected symbol near ‘false’

  1. unknown - addons/test swep/lua/weapons/weapon_test/shared.lua:0
    [/LUA]

I tried defining ent = self.Owner by saying local ent = self.Owner and replacing ent = self.Owner with ent but to no avail it gives me an error. It just doesn’t seem to like something within the If (SERVER) then statement.

as for the timer i would do something similar to this

[LUA]
function something()
timer.Create(“Geass Timer”,5,0,Geassdown) end )
end

function Geassdown()
undo.Create(render.DrawSphere)
undo.Finish
end
[/LUA]

Obviously theirs issues with my undo because i didn’t add a command for the server to tell the client that i am adding an undo list but i think the timer should be like that ^^

Look at your code again.
[lua]if ent:IsPlayer() then ent:Kill() and[/lua]
You don’t use ‘and’ to execute more code, you just add more code on the lines below. And yeah, you’re also using false wrong. This is how it should be, as simple as this:
[lua]if ent:IsPlayer() and ent:Alive() and ent != self.Owner then
ent:Kill()
end[/lua]
If the entity is a player, and he is also alive, and he is not the same player as the owner, then kill him. Fairly straight forward.

Three more things:

  1. You only save your owners position once, if he moves own will still point to where it was first saved. Move that part of the code into the actual function so it saves the position when you use it.

  2. You can’t check IsValid on a function that doesn’t return anything. Even if it did return you’re not calling the function. If you add ‘()’ on the end, you call it. If you don’t, you refer to it. So right now you’re just checking if the function itself is valid.

  3. You have your ‘if SERVER’ inside the ‘if CLIENT’ meaning the server would never get there. Use correct tabulation and keep track of your ends and openings.

Thanks for all the help! You’re the best

2.) So it would be something like this
[LUA]
if ( !IsValid(render.DrawSphere())) then return end
[/LUA]

Actually i think thats wrong ^,

3.) Ahhh i wasn’t aware. i assumed that end had to be at the end so it included all of the code

Another queston for you! If render.DrawSphere is a sphere drawn in 3D space its referred to as an entity correct? That means it would be possible to remove the drawsphere(using undo.Create) after x amount of time correct?(using a timer to calculate the time)

You won’t be able to use IsValid properly on render.DrawSphere at all. You should completely remove that line. Render-functions are all just drawing stuff in the world, it doesn’t create any entites or anything. In fact you’ll need to call them every single frame to make them actually stay there. It will disappear once you stop calling the function.

It seems to me that you’re trying to make a sphere when you do something with a weapon and have it stay there for x amount of time. I think the best way for this is to create an entity (as in making your own .lua file to define your very own entity type) which draws a sphere in its ENT:Draw() function, and then removes itself in that X amount of time.

Make your entity file and put something like this in it:
[lua]ENT.SpawnTime = 0

function ENT:Initialize()
self.SpawnTime = CurTime()
end

function ENT:Think()
if SERVER then
if CurTime() - self.SpawnTime() >= 5 then – Or whatever time you want it to stay alive
self:Remove()
end
end
end

if CLIENT then
function ENT:Draw()
render.DrawSphere(self:GetPos(), 50, 0, 0, Color(0,0,0))
end
end[/lua]
Spawn that entity in when you want and set its position to the player doing whatever with the weapon. It’ll stay there and then remove itself after the time. Remember to add other functions to it if you want, you can make this entity responsible for killing the players if you’d like.

Okay. So i would go ahead and create a folder in my addons folder and call it “Geass Zone”
within i’ll have a shared.lua containing this code.
[LUA]
AddCSLuaFile()
ENT.Type = “entity”
ENT.Base = “base_gmodentity”

ENT.PrintName= “Geass Zone”
ENT.Author= “Keosan+Facepunch”
ENT.Contact= “Facepunch”
ENT.Purpose= “Containing your deadly power”
ENT.Instructions= “Use the power of your geass channeled through this gun which will call all inside it.”
ENT.Spawnable = true
ENT.AdminSpawnable = false

ENT.SpawnTime = 0

function ENT:Initialize()
self.SpawnTime = CurTime()
end

function ENT:Think()
if SERVER then
if CurTime() - self.SpawnTime() >= 5 then – Or whatever time you want it to stay alive
self:Remove()
end

	local entities = ents.FindInSphere(own,50)
	for index, ent in pairs(entities) do
	if ent:IsPlayer() and ent:Alive() and ent != self.Owner then
      ent:Kill()
     end
end

end

if CLIENT then
function ENT:Draw()
render.DrawSphere(self:GetPos(), 50, 0, 0, Color(130,0,0))
end
end
[/LUA]

and then in my actual swep i would have something like this
[LUA]
function SWEP:PrimaryAttack()

if ( not self:CanPrimaryAttack() ) then

return
self.Act()
end

end

function SWEP:SecondaryAttack()
if ( not self:CanSecondaryAttack() ) then

return
end

end

function SWEP:Act()
self.Owner:EmitSound(ShootSound)
return “Geass Zone”
end
[/LUA]

I get an error in console when i do this as well.
[LUA]
[ERROR] addons/test swep/lua/weapons/weapon_test/shared.lua:26: attempt to index global ‘self’ (a nil value)

  1. unknown - addons/test swep/lua/weapons/weapon_test/shared.lua:26
  2. include - [C]:-1
    3. unknown - addons/test swep/lua/weapons/weapon_test/cl_init.lua:1
    [/LUA]

A couple of things, but you’re almost there. You will need to assign the owner to the entity as well, self.Owner is only automatically set on weapons. You are also not even spawning the entity.

[lua]function SWEP:Act()
self.Owner:EmitSound(ShootSound)
local sphere = ents.Create(whateveryourentityiscalled)
sphere:SetPos(self.Owner:GetPos())
sphere.Owner = self.Owner
sphere:Spawn()
end[/lua]

The reason for your error is because you’re calling self.Act() not self:Act() (Colon, not dot). Using a colon passes whatever’s before the colon as ‘self’, while dot does not.

And also you might wanna look up ‘return’. You’re using it a lot in places that don’t make sense.

So dot is just for the line itself while the colon is for everything before it?

I’ll look up dot and again thanks for all the help! I figured it was so… i made the wrong assumption and assumed that the entity itself was spawning itself so i would only have to call the entity not create one. But i was wrong :frowning:

I’ll look up return, i am not entirely sure what it does…

Edit :
Also one secondaryattack my swep will shoot out like a shotgun and when i primary shoot it doesnt use the sound i made.

[LUA]
local ShootSound = (Weapon_Pistolshoot.Single)
[/LUA]
and then i have a TEST WEP.txt with
this




"wave" "weapons/testwep/pistolshoot.wav"
}

"Weapon_Pistolshoot.Single"
{
"channel" "CHAN_ITEM"
"volume" "1.0"
"CompatibilityAttenuation" "1.0"
"pitch" "


I have this in my sound folder but when i primary shoot it doesn’t use my custom sound.

Double edit:

For secondaryattack i did
[LUA]

function SWEP:SecondaryAttack()
return
false
end
[/LUA]
so hopefully that fixes being able to use the secondary attack button on my swep

[editline]4th August 2015[/editline]

I ended up updating the code to above and i get
[LUA]

[ERROR] addons/test swep/lua/weapons/weapon_test/shared.lua:26: attempt to index global ‘self’ (a nil value)

  1. unknown - addons/test swep/lua/weapons/weapon_test/shared.lua:26
  2. include - [C]:-1
    3. unknown - addons/test swep/lua/weapons/weapon_test/cl_init.lua:1
    [/LUA]

I looked up online and found that self can be called implicitly and that the errors people were having were like so
[LUA]
function mygun.method()
end
[/LUA]
and the fix was
[LUA]
function mygun:method()
end
[/LUA]
but i don’t think i have an error like that. I even tried doing self:Act() and SWEP:Act() and it still gives me the self is not global error.

I don’t get errors on join!
But now i have this…
[LUA]

[ERROR] addons/test swep/lua/weapons/weapon_test/shared.lua:60: attempt to call field ‘Create’ (a nil value)

  1. Act - addons/test swep/lua/weapons/weapon_test/shared.lua:60
  2. unknown - addons/test swep/lua/weapons/weapon_test/shared.lua:49
    [/LUA]

I changed it to If server then and now it works. No more errors! However my gun simply does nothing now when i shoot it.(Doesn’t play sound and doesn’t render sphere)

SO i am assuming i sent up an entity file incorrectly?

I have seem to run into the error of having the gun not give any errors on joining but now nothing is created when i PrimaryAttack nor is sound being played. If i use SWEP.Primary.Sound = Sound(“weapons/testwep/pistolshoot.wav”) it says the sound can’t be found on the disk(even when i do resource.AddFile(“pistolshoot.wav”). I think the other issue is with my entity. I couldn’t find very much on how to correctly create an entity but my doesn’t show up in the entity tab and nor does my gun create my entity when i shoot. If you care to i need some help on how to do this!

resource.AddFile is relative to the garrysmod/ folder. Meaning it would be sound/whatever.wav

Ill try that out and see if it works! Do you know anything on creating entities though?

I have three files, Init.lua,cl_init.lua, and shared.lua.

Heres my code for all three

init.lua
[LUA]
AddCSLuaFile(“cl_init.lua”)
AddCSLuaFIle(“shared.lua”)
include(“shared.lua”)

ENT.SpawnTime = 0
function ENT:Initialize()
self.SpawnTime = CurTime()
end

function ENT:Think()
if CurTime() - self.SpawnTime() >= 5 then – Or whatever time you want it to stay alive
self:Remove()
end

	local entities = ents.FindInSphere(own,50)
	for index, ent in pairs(entities) do
	if ent:IsPlayer() and ent:Alive() and ent != self.Owner then
      ent:Kill()
     end

end
[/LUA]

cl_init.lua
[LUA]
include(“shared.lua”)
function ENT:Draw()
render.DrawSphere(self:GetPos(), 50, 0, 0, Color(130,0,0))
end
[/LUA]

shared.lua
[LUA]
AddCSLuaFile()
ENT.Type = “anim”
ENT.Base = “base_gmodentity”
ENT.Name = “Geass Zone”
ENT.PrintName= “Geass Zone”
ENT.Author= “Keosan+Facepunch”
ENT.Contact= “Facepunch”
ENT.Category = “Geass”
ENT.Purpose= “Containing your deadly power”
ENT.Instructions= “Use the power of your geass channeled through this gun which will call all inside it.”
ENT.Spawnable = false
ENT.AdminSpawnable = true

ENT.SpawnTime = 0
[/LUA]

But i can’t get my entity to be created when i shoot my gun.(I have an entities folder in the testwep/lua/entities and another addon folder called Geass Zone with my entities inside that and nothing!) The entity does not show in my entities tab on gmod(Q)

I’m not sure if this is the issue, but try to avoid using space in the names of your stuff. It should be “geass_zone”. Also you have ents.FindInSphere() in a think function (!). Put that up in the Initialize one instead, it only needs to do this once when it spawns. The Create error you get is because ents.Create is only server sided but your client code still gets to that point.

I’ll try it! Thanks for all the help. I’ll be reading up on LUA and GLua after Thursday so i won’t feel so much like i am sucking on the teet of others. If you are willing , i’ll leave my profile so that you can add me if you feel like helping a newbie with a lot of questions or feel like talking/shooting the shit.