Freeze a player when seen

Hi, I’ve wanted to freeze players of one team when they are seen by the other team but actually I’ve searched on http://wiki.garrysmod.com/ ; on the Internet… and I couldn’t find anything.

So if someone could help me with this ?

You could use

Player:GetEyeTrace to get what the player is looking at, then

Entity:IsPlayer to check if it’s a player, then

Player:Freeze if it is. You could also use

Player:Team to check the team.
For example:




local trace = player:GetEyeTrace()
local hitent = trace.Entity

if IsValid( hitent ) and hitent:IsPlayer() and hitent:Team() ~= player:Team() then -- Don't freeze the player if it's on the player's team!
	hitent:Freeze( true )
end



Note that if you used GetEyeTrace, I think it only returns the entity the player is looking DIRECTLY at, rather than all the entities on the screen. I remember there was a way to get all the entities on the screen but I forgot what it was. It was on the wiki somewhere though

https://wiki.garrysmod.com/page/ents/FindInCone this maybe?

I think you may be able to use Entity:IsLineOfSightClear() or use some vector dot calculations, I know Stop it Slender does that. You could look at that and see how it works.

Yea I think it’s “Entity:IsLineOfSightClear()” !
I’ll test it !

I’ve tried this but It doesn’t work :confused:


hook.Add("Think", "Freeze173", function() 

local scp173 
for k,v in pairs(player.GetAll()) do
	if v:IsValid() and v:Team() == TEAM_SCP173 then scp173 = v end
end
//if true then  scp173:Freeze(false) return end
	for k,v in pairs(player.GetAll()) do
		if v != scp173 and v:Alive() and v:IsLineOfSightClear(scp173) then scp173:Freeze(true)
		else scp173:Freeze(false) end
	end
 end)

[editline]17th January 2016[/editline]

It appears that “IsLineOfSightClear()” is for every entities in the room :confused:

Have you tried

Entity:Visible( Entity )?

All of the aforementioned functions draw a line from the player’s head to adjacent entities and don’t take into account entities visible to the client’s eye



hook.Add("Think","FreezeSeenObjects",function()
    local freezeStatus = {}
    
    for _,ply in ipairs(player.GetAll()) do
        freezeStatus[ent] = freezeStatus[ent] or false
        local seen = ents.FindInCone(ply:EyePos(),ply:EyeAngles():Forward(),10^4,75) -- 75o FOV

        for _,ent in ipairs(seen) do
            if IsValid(ent) and ent:IsPlayer() and (ent:Team() ~= ply:Team()) then
                freezeStatus[ent] = true
            end
        end
    end

    for ply,status in pairs(freezeStatus) do
        ply:Freeze(status)
    end
end)


ents.FindInCone may be what you want

Or just use the hook

GM/PrePlayerDraw

I’ve done this:


 hook.Add("Think", "Freeze173", function() 
 local scp173
	for k,v in pairs(player.GetAll()) do
		if v:Team() == TEAM_SCP173 then scp173 = v else return end
		if v:Visible(scp173) and v:Alive() and v != scp173 then scp173:Freeze(true)
		else scp173:Freeze(false) end
	end
end)

And it doesn’t work…

Beacouse in there scp173 is the same as v.
You need 2 loops for all players and to make this a bit better instead of putting the players variable as scp173 leave it as v and in the second loop name the k k2 and the v v2.
Also change the


return

to a continue beacouse if any player isnt on that team the loop stops and with


continue

you will make it to go to the next value on the loop.

[editline]17th January 2016[/editline]

Use instead the code you had before but change the return by a continue beacouse of what i said above

So here is the code :


 hook.Add("Think", "Freeze173", function() 
 local scp173
	for k,v in pairs(player.GetAll()) do
		if v:Team() == TEAM_SCP173 then scp173 = v else continue end
		if v:Visible(scp173) and v:Alive() and v != scp173 then scp173:Freeze(true)
		else scp173:Freeze(false) end
	end
end)

But when the player see me, I’m not freezed :confused:

I have also been messing with an SCP gamemode a while back and I made a function that returns whether the SCP is seen or not. It should be noted that the player controlling the SCP isn’t actually it in my gamemode, instead he’s an invisible player placing invisible nodes down to “plan” the SCPs move when everyone blinks (So that the SCP moves instantly), and the SCP is just an entity with the model. Regardless, this is what I use to check whether it is seen:
[lua]function ENT:Seen( specific )

if specific then
	if !specific:IsPlayer() then return Error("SCP:Seen() has been called with a specific player that's not a player entity!") end
	return specific:IsLineOfSightClear(self) and specific:GetPos():Distance(self:GetPos()) <= 700 and specific:EyeAngles():Forward():Dot( (specific:GetPos() - self:GetPos()):GetNormal()) < 0
else
	for k,v in pairs(team.GetPlayers(TEAM_HUMAN)) do
		--print(v:Nick())
		if v:IsLineOfSightClear(self) and v:GetPos():Distance(self:GetPos()) <= 700 and v:EyeAngles():Forward():Dot( (v:GetPos() - self:GetPos()):GetNormal()) < 0 then
			return true
		end
	end
	return false
end

end[/lua]
Specific means I can check it on a specific player, otherwise I loop through all players on TEAM_HUMANS.

Basically, IsLineOfSightClear() doesn’t take into account the direction the player is facing, so you could be looking away from the SCP but if there is a clear line of sight behind you, it would still return true. That’s why I do some dot calculations which take into account the viewing angles. The 700 distance is the fog I set in the gamemode. This :Seen() function is only called in my gamemode when the controlling player tries to manually execute a move (when players are not blinking), not constantly, so I can’t say if it’s optimized.

I recommend you don’t just use this code but instead fiddle with it yourself and learn how it works.

I just want to understand why my code doesn’t work first :confused:

You completely ignored my post.
If you’d read it you would’ve fixed it.

I’ve done this.

I meant the one in wich there were 2 loops for player.GetAll
In there if he wasnt from that team there was a return.
I told you to change that.
Also, the last code you gave us checks for the same player beacouse v and scp173 are the same as youre defining it aa the same player youre checking.
Just follow everything on there and id you dont get what i mean with something tell me.
Ill explain.

Perhaps use team.GetPlayers instead of player.GetAll to only loop through humans and not scps?

Or even player.GetHumans()

The game doesn’t see different teams (like one called TEAM_SCP) and think they’re not humans, it only sees bots as not humans, so that wouldn’t work