Some gate that can be useful in Border Games

I made a gate that lights up red when someone is carrying a blacklisted item, but green if not. The script is super simple and my model is open-sourced!

Gate it self

(1) Gate - Roblox
Gate.rbxm (4.7 KB)
Uncopylocked Testing place

Editing the code
local BadColor = Color3.new(1, 0, 0) --the color of the lights when carrying a blaclisted item
local GoodColor = Color3.new(0.333333, 1, 0) --the color of lights when carrying an non-blacklisted item
local NeutralColor = Color3.new(1, 1, 1) --the color of the lights when on standby
local BlacklistedNames = { --Edit the contents to the names of items you want to blacklist
	"Tool",
	"Tool2"
}
local Blacklisted = {}

for _, name in pairs(BlacklistedNames) do
	Blacklisted[name] = true
end




function NameCheckFromTable (Table, Name)
	return Table[Name]
end
function InstanceTableCheckWithStringTable (InstanceTable, StringTable)
	for _, Item in pairs(InstanceTable) do
		if StringTable[Item.Name] then
			return true
		end
	end
	return false
end

function LightUp (Color)
	local Lights = script.Parent.Lights:GetChildren()
	for i,item in pairs(Lights) do
		item.Color = Color
	end
end

function StartCheck (Touched)
	local Char = Touched.Parent
	local Player = game.Players:GetPlayerFromCharacter(Char)
	if not Player then return end

	local Backpack = Player.Backpack:GetChildren()
	local HeldItem = Char:FindFirstChildOfClass("Tool")

	local InsCheck = InstanceTableCheckWithStringTable(Backpack, Blacklisted)
	local NameCheck = false
	if HeldItem then
		NameCheck = Blacklisted[HeldItem.Name]
	end

	local NewColor
	if InsCheck or NameCheck then
		NewColor = BadColor
	else
		NewColor = GoodColor
	end
	LightUp(NewColor)
	wait(1)
	LightUp(NeutralColor)
end

script.Parent.Sensor.Touched:Connect(StartCheck)
Editing the lights
  • There will be a folder in the model called Lights, Inside there will be parts, any part that is inside will change colour to the different situation.
    image
Updates
  • Update 17/12/2020
    Thanks to @goldenstein64, my code has been optimized!
    Also, I made the testing place available to all.
  • Update 18/12/2020
    Minor Update allowing more customization! (See “Editing the code”)

Feel free to give feedback!

9 Likes

I really needed it! And I found this post now! Thank you very much! :happy4:

1 Like

Only 3 suggestions I could give:

  • Using a dictionary-based blacklist instead of an array-based one:
local Blacklisted = {
    ["Tool"] = true,
    ["Tool2"] = true
}
-- alternatively
local BlacklistedArray = {
    "Tool",
    "Tool2"
}

local Blacklisted = {}
for _, name in ipairs(BlacklistedArray) do
    Blacklisted[name] = true
end

This would make your string table checkers simpler and more performant:

function NameCheckFromTable (Table, Name)
    local NameFound = Table[Name]
    if NameFound then
        return true
    else
        return false
    end
end
-- a shorter version,
-- you can basically replace the entire thing
function NameCheckFromTable (Table, Name)
    return Table[Name]
end
function InstanceTableCheckWithStringTable (InstanceTable, StringTable)
    for _, Item in ipairs(InstanceTable) do
        if StringTable[Item.Name] then
            return true
        end
    end
    return false
end
If we disregard the above suggestion,
  • Using the NameCheckFromTable function in your InstanceTableCheckWithStringTable function:
function InstanceTableCheckWithStringTable (InstanceTable, StringTable)
    for _, Item in ipairs(InstanceTable) do
        local Name = Item.Name
        local NameFound = NameCheckFromTable(StringTable, Name)
        if NameFound then
            return true
        end
    end
    return false
end

Even then, you could just use table.find:

-- NameCheckFromTable = table.find

function InstanceTableCheckWithStringTable (InstanceTable, StringTable)
    for _, Item in ipairs(InstanceTable) do
        local Name = Item.Name
        local NameFound = table.find(StringTable, Name)
        if NameFound ~= nil then
            return true
        end
    end
    return false
end

  • Combining the NameCheck and InsCheck logical gates:
function StartCheck (Touched)
	local Char = Touched.Parent
	local Player = game.Players:GetPlayerFromCharacter(Char)
	if not Player then return end

	local Backpack = Player.Backpack:GetChildren()
	local HeldItem = Char:FindFirstChildOfClass("Tool")
	
	local InsCheck = InstanceTableCheckWithStringTable(Backpack, Blacklisted)
	local NameCheck = false
	if HeldItem then
		NameCheck = Blacklisted[HeldItem.Name]
	end
	
	local NewColor
	if InsCheck or NameCheck then
		NewColor = Color3.new(1, 0, 0)
	else
		NewColor = Color3.new(0.333333, 1, 0)
	end
	LightUp(NewColor)
	wait(1)
	LightUp(Color3.new(1, 1, 1))
end
  • simplifying the final script.Parent.Sensor.Touched function by the tiniest bit:
--[[ instead of
script.Parent.Sensor.Touched:Connect(function(Touched)
    StartCheck(Touched)
end)
--]]

-- you can do
script.Parent.Sensor.Touched:Connect(StartCheck)

And a few nitpicks barely worth mentioning:

  • I would put a space after each comma to better separate arguments visually.
  • I would have put a local keyword behind each of those function definitions.
  • I would have used game:GetService("Players") and referenced it as a variable at the top of the script.
  • I might have made the red and green colors constants up top next to Blacklisted? I might have also used Color3.fromRGB, but that’s just what I’m used to.

Overall, I think your script is clean, readable, and easy to change. Good job!

1 Like

Ok, thanks a lot for your feedback, I will take note and update the code as soon as possible! :happy1:

1 Like