Hello! I am making a border game and we are making a bot that asks you questions and if you respond correctly, you can pass and not die. But we have a problem where it stays open whenever you’re in. Here is the script. I hope you can help!
local gate = script.Parent
local door1 = workspace.Map.Border.Wall.Gate.DoorSystem.Door1
local door2 = workspace.Map.Border.Wall.Gate.DoorSystem.Door2
local roomSpace = workspace.GuardBotPart
local gatekeeper = gate:WaitForChild("Gatekeeper")
local chatService = game:GetService("Chat")
local players = game:GetService("Players")
local RunService = game:GetService("RunService")
local killZone = workspace.KillZone
local npcTemplate = script.Parent.Parent:WaitForChild("GuardMassacre")
local npc = workspace:FindFirstChild("GuardMassacre") or npcTemplate:Clone()
npc.Parent = workspace
local playersInRoom = {}
local dialogueStates = {}
local activeTargets = {}
local chasing = false
-- Kill a player
local function killPlayer(player)
local character = player.Character
if character and character:FindFirstChild("Humanoid") then
character.Humanoid.Health = 0
end
end
-- Players in kill zone
local function getTouchingPlayers()
local touchingPlayers = {}
for _, player in ipairs(players:GetPlayers()) do
local char = player.Character
if char and char:FindFirstChild("HumanoidRootPart") and killZone:IsA("BasePart") then
if (killZone.Position - char.HumanoidRootPart.Position).Magnitude < (killZone.Size.Magnitude / 2) then
table.insert(touchingPlayers, player)
end
end
end
return touchingPlayers
end
-- Chase targets
local function chaseAllTargets()
if chasing then return end
chasing = true
for player, _ in pairs(activeTargets) do
coroutine.wrap(function()
local humanoid = npc:FindFirstChild("Humanoid")
local rootPart = npc:FindFirstChild("HumanoidRootPart")
if not humanoid or not rootPart then return end
local character = player.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then return end
while activeTargets[player] and character:FindFirstChild("HumanoidRootPart") do
local targetPos = character.HumanoidRootPart.Position
local npcPos = rootPart.Position
local direction = (targetPos - npcPos).Unit
local moveToPosition = npcPos + direction * 10
humanoid:MoveTo(moveToPosition)
if (targetPos - npcPos).Magnitude < 5 then
killPlayer(player)
activeTargets[player] = nil
task.wait(6)
local newClone = npcTemplate:Clone()
newClone.Parent = workspace
newClone.PrimaryPart.CFrame = CFrame.new(-16.5, 13.501, -78)
npc:Destroy()
npc = newClone
break
end
task.wait(0.2)
end
end)()
end
task.delay(10, function()
chasing = false
end)
end
-- Gatekeeper dialogue
local function gatekeeperSay(text)
local head = gatekeeper:FindFirstChild("Head")
if head then
chatService:Chat(head, text, Enum.ChatColor.White)
end
end
-- Door functions
local function openDoor1()
if next(playersInRoom) == nil then
door1.CanCollide = false
door1.Transparency = 0.5
print("Door1 opened")
end
end
local function closeDoor1()
door1.CanCollide = true
door1.Transparency = 0
print("Door1 closed")
end
local function openDoor2()
door2.CanCollide = false
door2.Transparency = 0.5
print("Door2 opened")
end
local function closeDoor2()
task.wait(2)
door2.CanCollide = true
door2.Transparency = 0
print("Door2 closed")
end
-- Dialogue handling
local function beginDialogue(player)
if dialogueStates[player] then return end
dialogueStates[player] = {
step = 1,
name = nil,
reason = nil,
toolCheckStarted = false,
}
gatekeeperSay("What is your name?")
end
local function startToolCheckLoop(player)
local state = dialogueStates[player]
if not state or state.toolCheckStarted then return end
state.toolCheckStarted = true
coroutine.wrap(function()
while playersInRoom[player] do
local character = player.Character
local tool = character and character:FindFirstChildOfClass("Tool")
if tool then
if tool.Name == "Passport" then
gatekeeperSay("Thank you, " .. (state.name or "guest") .. ". You may proceed.")
openDoor2()
break
elseif tool.Name == "Fake Passport" then
local chance = math.random(1, 4)
if chance == 1 then
gatekeeperSay("I said, no fake passports!")
local touching = getTouchingPlayers()
for _, plr in ipairs(touching) do
activeTargets[plr] = true
end
chatService:Chat(npc.Head, "YOU'RE UNDER ARREST!", Enum.ChatColor.White)
chaseAllTargets()
else
gatekeeperSay("Thank you, " .. (state.name or "guest") .. ". You may proceed.")
openDoor2()
end
break
end
end
task.wait(1)
end
end)()
end
-- Handle player chats for dialogue
players.PlayerAdded:Connect(function(player)
player.Chatted:Connect(function(message)
local state = dialogueStates[player]
if not state then return end
if state.step == 1 then
state.name = message
state.step = 2
gatekeeperSay("Why are you here?")
elseif state.step == 2 then
state.reason = message
state.step = 3
gatekeeperSay("Please hold up your Passport. No Fakes!")
startToolCheckLoop(player)
end
end)
end)
-- Player enters room
roomSpace.Touched:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
local player = players:GetPlayerFromCharacter(character)
if player and not playersInRoom[player] then
print("Player touched RoomSpace:", player.Name)
playersInRoom[player] = true
local count = 0
for _ in pairs(playersInRoom) do count += 1 end
if count >= 2 then
local touching = getTouchingPlayers()
for _, plr in ipairs(touching) do
activeTargets[plr] = true
end
chatService:Chat(npc.Head, "YOU'RE UNDER ARREST!", Enum.ChatColor.White)
chaseAllTargets()
playersInRoom = {}
return
end
task.delay(2, function()
closeDoor2()
end)
task.wait(1)
beginDialogue(player)
end
end)
-- Player leaves room
roomSpace.TouchEnded:Connect(function(hit)
local character = hit:FindFirstAncestorOfClass("Model")
local player = players:GetPlayerFromCharacter(character)
workspace.NextPersonEnterTxt.Sound:Play()
chatService:Chat(workspace.NextPersonEnterTxt, "NEXT PERSON ENTER", Enum.ChatColor.White)
if player then
print("Player left RoomSpace:", player.Name)
playersInRoom[player] = nil
dialogueStates[player] = nil
openDoor1()
close
end
end)
-- Initialize on start
openDoor1()