Automatically close/open door if player is in vector (or not)

Hello,
the map my server is running on has special doors which should only be accessed by certain teams, e.g: Police or Firefighters. The Police and Fire Department also have gates.
I wish to open these gates if the player is in the area(vector) altough i don’t know how to detect this.

my code so far:



local policedoors = {
{Vector(-8656, 9392, 314), '*59'}, 
{Vector(-8656, 9680, 314), '*60'},
						}
						
local function gateDoorspolice
	for k, v in pairs(policedoors ) do
		for _, ent in pairs(something with sphere? i don't know.) do
			if (ent:IsDoor() && ent:GetModel() == v[2]) then
				ent:Fire("lock", "", 0);
			end
		end
	end
end

Should i use some kind of hook here? would think be okay?


misread

Use Fire( “Lock” ) and Fire( “Unlock” ) and you can use ents.FindInSphere on gmod wiki.

The question isn’t about that tough, i already know how to use ents.FindInSphere for opening doors on startup but i don’t know how to open if a player is in an area & is in the correct team

Well its only running once, use a think function or a timer… it needs to always check or its just sitting there like wtf is going on?

I know i need to use a hook or timer for it, that’s, for the second time, not my question.

It seems like you want to check if a player is close to vector. Which if that’s the case

ents.FindInSphere is the way to go. And you should call that in a think hook. To check the team you should be able to do this ( If you are using DarkRP for the jobs ):



local policedoors = {
{Vector(-8656, 9392, 314), '*59', "Firefighter"}, 
{Vector(-8656, 9680, 314), '*60', "Police Officer"},
						}
						ent:IsPlayer()
local function gateDoorspolice()
	for k, v in pairs(policedoors ) do
		for _, ent in pairs(ents.FindInSphere(v[1], 300) do // Look for player within 300 units from the door
			if (!ent:IsPlayer()) then continue end
			if (team.GetName(ent:Team()):lower() == v[3]:lower() ) then // Check players team
				// Assuming the position is exact or pretty much exact vector for door
				for _, door in pairs(ents.FindInSphere(v[1], 10) do // Check for a door
					if(door:IsDoor() && door:GetModel() == v[2]) then // Check if it's actually a door
						door:Fire("unlock") // Unlock it because someone with the required team is close by
						return
					end
				end
			else
				for _, door in pairs(ents.FindInSphere(v[1], 10) do // Check for a door
					if(door:IsDoor() && door:GetModel() == v[2]) then // Check if it's actually a door
						door:Fire("lock") // lock it because no player that can open is close by
						return
					end
				end
			end
		end
	end
end

hook.Add("Think", "policeDoorChecker", function()
   gateDoorspolice()
end)


This probably isn’t the most effective way to do it Also if you just want to make sure only one or multiple team(s) can open the door ( Without key ) there’s better ways to do it.

I’m using something entirely else than darkRP but i suppose it will work fine with normal gmod teams (TEAM_FIREFIGHTER for example) would work. thanks for this!

I got the opening working, but it doesn’t work when checking the players teams, altough i plan on figuring that out later.

I got them to open but they wont close if i’m out of range, already tried doing if the entities found aren’t players and are in team POLICE_OFFICER but to no avail, here’s a clip for clarification and my current code.



local policedoors = {
{Vector(-8656, 9392, 314), '*59', "TEAM_POLICE"}, 
{Vector(-8656, 9680, 314), '*60', "TEAM_POLICE"},
						}
local function gateDoorspolice()

	for k, v in pairs( policedoors ) do
		for _, ent in pairs(ents.FindInSphere(v[1], 300)) do
			if (!ent:IsPlayer()) then
				door:Fire("Unlock")
				door:Fire("Close")
				Msg("Close")		
			end
			if (!ent:IsPlayer || team.GetName( ent:Team() != v[3] ) then
				door:Fire("Unlock")
				door:Fire("Close")
				Msg("Close")
			end
			if (ent:IsPlayer()) then
				Msg("entisplayer")
				if (ent:InVehicle() ) then
					for _, door in pairs(ents.FindInSphere(v[1], 10)) do
						if (door:IsDoor() && door:GetModel() == v[2]) then
							door:Fire("Unlock")
							door:Fire("Open")
							Msg("open")
						
						end
					end
				end
			end
		end
	end
end

[video]https://youtu.be/rrcrjPrPpC8[/video]

First of all, you should probably stay away from stolen gamemodes…

I assume it’s not working because when there are no players in range it’s not going to have any values to loop through, so that “Unlock” “Close” won’t do anything.

Try something like this:



function OpenGates( _Vehicle )
	if _Vehicle.OpenGates && _Vehicle.OpenGates > CurTime() then return end

	local gates = {}
	gates[1] = Vector(-8656, 9392, 314)
	gates[2] = Vector(-8656, 9672, 315)

	for k, v in pairs( gates ) do
		for _, ent in pairs( ents.FindInSphere( v, 20 ) ) do
			ent:Fire('open', '', .5)
			_Vehicle.OpenGates = CurTime() + 7
			timer.Simple(6, function() ent:Fire('close', '', .5) end)
		end
	end
end

hook.Add( 'Think', 'Think.OpenGates', function( )
	for k, v in pairs(ents.FindInSphere(Vector(-8654, 9532, 309), 300)) do
		if v:IsVehicle() --[[ && some stupid check to make sure that the vehicle belongs to that of an officer ]] then
			OpenGates( v )
		end
	end
end)


I would do something like this. (Untested though :D)


local policedoors = {
	{Vector(-8656, 9392, 314), {[TEAM_POLICE] = true, [TEAM_ANOTHER] = true}}, 
	{Vector(-8656, 9680, 314), {[TEAM_POLICE] = true, [TEAM_ANOTHER] = true}},
}

local doorEntities = {
	["prop_door_rotating"] = true,
	["func_door"] = true,
}

local PlayerDetectionRange = 300
local DoorDetectionRange = 10

local ThinkDelay = 0.5


local function openDoor(doorTable, door)
	
	for k,v in pairs(ents.FindInSphere(doorTable[1], PlayerDetectionRange)) do
		if ent:IsPlayer() and doorTable[2][ent:GetTeam()] then
			if IsValid(door) then 
				door:Fire("open", "", 0.1)
				timer.Simple(4, function() if IsValid(door) then door:Fire("close", "", 0.1) end end)
			end
		end
	end
	
end

local function CheckOpenDoors()
	for _,doorTable in pairs(policedoors) do
		for k,v in pairs(ents.FindInSphere(doorTable[1], DoorDetectionRange) do
			if doorEntities[v:GetClass()] then openDoor(doorTable, v) end
		end
	end
end


local NextDoorThink = 0
hook.Add("Think", "OpenDoors", function() 
	if NextDoorThink <= CurTime() then
		NextDoorThink = NextDoorThink + ThinkDelay
		CheckOpenDoors()
	end
end)

In the examples above, everyone is using team.GetName, following the fact you proboly used one, you dont use TEAM_ because when assigning a team you give it a valid printname, use that instead.

I didnt?

:snip:

You would probably also want to trace between player and door to make sure that both entities are in line of sight so you don’t accidentally bump doors that don’t need opening through the wall with ents.FindInSphere.

There’s really no need for that in his example specifically…