Smoke grenade blocking player line of sight


I’d like to make it so that the smoke from a smoke grenade will block a player’s line of sight to another player and prevent their name tag from drawing. Could anyone offer some information on how I could achieve this? I’ve been looking at util/TraceEntity, Structures/Trace, Enums/MASKStructures/TraceResult but the descriptions given are quite vague.

In relation to this, I’d also like to know how I could create an “invisible shape”, such as a sphere that can vary in size. If I could create this, could I check if a trace were to go through it and determine line of sight that way?

Any help is appreciated,

Edit: Solved thanks to OzymandiasJ.

Apply a variable to the player like Player.IsBlinded, then modify the tag drawing function to run a check
[lua]if LocalPlayer().IsBlinded then return end[/lua]
It’ll require more than that, because you have to send the variable to player and do some ‘thinking’ about where to hook the function that blinds the player and takes blind off.

This is definitely bad coding 101, since the grenade explosion is already known clientside (smoke) you can do all calculations on the client side, that and you didn’t actually help.

If you want to create a physics shape from a sphere, look at PhysicsInitSphere, you’ll need to enable custom collision checks, and you can do ENTITY:SetCollisionGroup(COLLISION_GROUP_DEBRIS_TRIGGER) to make it only solid to traces.

Thanks for the help. I’ve tried spawning an entity at the position of the grenade when it detonates but it doesn’t block traces.

[lua]function ENT:Initialize()
self.Entity:PhysicsInitSphere( 450 )
self.Entity:SetCollisionGroup( COLLISION_GROUP_DEBRIS_TRIGGER )
self.Entity:EnableCustomCollisions( true )
local phys = self:GetPhysicsObject()
if ( IsValid( phys ) ) then phys:EnableCollisions(true); phys:Wake(); end

Could you offer any information on which kind of trace I should use and its masks? I’m really confused.

I may or may not have forgotten SetCollisionBounds, which actually determines the “trace” size of the object. The Collision and Physics bounds are different. Try self:SetCollisionBounds(Vector(-450, -450, -450),Vector(450, 450, 450))

Also, on the trace part, a normal trace without any specified Masks would work. I’m assuming you’re calling this from a player, then PLAYER:GetEyeTrace should do the trick. It’s basically a util.QuickTrace, which is a convience function (using GetEyePos and GetEyeAngles:Normalize()), because you don’t have to specify anything but startpoint and a direction for a trace to work. Normally you don’t have to specify a mask unless you specifically only want to prevent picking up certain things, like brushes.

Thanks very much, it’s actually working. I’m really glad. The only problem remaining is that it now also blocks bullets. Do you know of any way to make it block only the eye traces, and not say a trace for a weapon attack?

Since you have enabled custom collisions, I think if you make the Entity report false in a collision hook with any player, any bullets will be blocked. I know that if you make players report false in a collision hook with an entity they cannot shoot it, so the reverse should apply.
If you do self:SetCustomCollisionCheck(true) in the entity’s initialization, then set some variable on it like self.NoPlayerCollision = true, then add this hook at the bottom:

hook.Add(“ShouldCollide”, “ShouldCollide_SmokeGrenade”, function(e1, e2)
return !((e1.NoPlayerCollision or e2.NoPlayerCollision) and (e1:IsPlayer() or e2:IsPlayer()))

Thank you very much, it works like a treat. The only problem was that a melee weapon was still hitting it, but I just added the smoke entity to the filter bit of its trace structure. Works great, thanks again.